#!/bin/sh
#
# Generated by qconf 2.0 ( http://delta.affinix.com/qconf/ )
#

show_usage() {
cat <<EOT
Usage: $0 [OPTION]...

This script creates necessary configuration files to build/install.

Main options:
  --prefix=[path]       Base path for build/install.  Default: /usr/local
  --bindir=[path]       Directory for binaries.  Default: PREFIX/bin
  --libdir=[path]       Directory for libraries.  Default: PREFIX/lib
  --datadir=[path]      Directory for data.  Default: PREFIX/share
  --qtdir=[path]        Directory where Qt is installed.
  --extraconf=[conf]    Extra configuration for nonstandard cases.
  --verbose             Show extra configure output.
  --qtselect=[N]        Select major Qt version (4 or 5).
  --help                This help text.

Project options:
  --release                   Build with debugging turned off (default).
  --debug                     Build with debugging turned on.
  --no-separate-debug-info    Do not store debug information in a separate
                              file (default for mac).
  --separate-debug-info       Strip debug information into a separate .debug
                              file (default for non-mac).

Dependency options:
  --with-idn-inc=[path]            Path to libidn include files
  --with-idn-lib=[path]            Path to libidn library or framework files
  --with-qca-inc=[path]            Path to QCA include files
  --with-qca-lib=[path]            Path to QCA library or framework files
  --with-zlib-inc=[path]           Path to zlib include files
  --with-zlib-lib=[path]           Path to zlib library files
  --with-qjdns-inc=[path]          Path to QJDns include files
  --with-qjdns-lib=[path]          Path to QJDns library files
  --enable-universal               Enable use of Mac OS X universal binary
                                   support
  --disable-qdbus                  Disable use of QDBUS
  --disable-keychain               Disable use of Qt Keychain
  --enable-webkit                  Enable use of webkit
  --with-webkit=[type]             type of webkit QtWebKit/QtWebEngine
  --with-http-parser-inc=[path]    Path to HTTP Parser include files
  --with-http-parser-lib=[path]    Path to HTTP Parser library files
  --bundled-http-parser            Build with bundled HTTP Parser
  --disable-growl                  Disable use of Growl
  --with-growl=[path]              Path to the Growl framework
  --enable-whiteboarding           Enable use of White Board support
  --disable-xss                    Disable use of the XScreenSaver extension
  --disable-aspell                 Disable use of aspell
  --with-aspell-inc=[path]         Path to Aspell include files
  --with-aspell-lib=[path]         Path to Aspell library files
  --disable-enchant                Disable use of enchant
  --disable-hunspell               Disable use of hunspell
  --with-hunspell-inc=[path]       Path to Hunspell include files
  --with-hunspell-lib=[path]       Path to Hunspell library files
  --disable-plugins                Disable use of Psi Plugin support

EOT
}

# which/make detection adapted from Qt
which_command() {
	ALL_MATCHES=
	if [ "$1" = "-a" ]; then
		ALL_MATCHES="-a"
		shift
	fi

	OLD_HOME=$HOME
	HOME=/dev/null
	export HOME

	WHICH=`which which 2>/dev/null`
	if echo $WHICH | grep 'shell built-in command' >/dev/null 2>&1; then
		WHICH=which
	elif [ -z "$WHICH" ]; then
		if which which >/dev/null 2>&1; then
			WHICH=which
		else
			for a in /usr/ucb /usr/bin /bin /usr/local/bin; do
				if [ -x $a/which ]; then
					WHICH=$a/which
					break
				fi
			done
		fi
	fi

	RET_CODE=1
	if [ -z "$WHICH" ]; then
		OLD_IFS=$IFS
		IFS=:
		for a in $PATH; do
			if [ -x $a/$1 ]; then
				echo "$a/$1"
				RET_CODE=0
				[ -z "$ALL_MATCHES" ] && break
			fi
		done
		IFS=$OLD_IFS
		export IFS
	else
		a=`"$WHICH" "$ALL_MATCHES" "$1" 2>/dev/null`
		if [ ! -z "$a" -a -x "$a" ]; then
			echo "$a"
			RET_CODE=0
		fi
	fi
	HOME=$OLD_HOME
	export HOME
	return $RET_CODE
}
WHICH=which_command

# find a make command
if [ -z "$MAKE" ]; then
	MAKE=
	for mk in gmake make; do
		if $WHICH $mk >/dev/null 2>&1; then
			MAKE=`$WHICH $mk`
			break
		fi
	done
	if [ -z "$MAKE" ]; then
		echo "You don't seem to have 'make' or 'gmake' in your PATH."
		echo "Cannot proceed."
		exit 1
	fi
fi

show_qt_info() {
	printf "Be sure you have a proper Qt 4.0+ build environment set up.  This means not\n"
	printf "just Qt, but also a C++ compiler, a make tool, and any other packages\n"
	printf "necessary for compiling C++ programs.\n"
	printf "\n"
	printf "If you are certain everything is installed, then it could be that Qt is not\n"
	printf "being recognized or that a different version of Qt is being detected by\n"
	printf "mistake (for example, this could happen if \$QTDIR is pointing to a Qt 3\n"
	printf "installation).  At least one of the following conditions must be satisfied:\n"
	printf "\n"
	printf " 1) --qtdir is set to the location of Qt\n"
	printf " 2) \$QTDIR is set to the location of Qt\n"
	printf " 3) QtCore is in the pkg-config database\n"
	printf " 4) qmake is in the \$PATH\n"
	printf "\n"
	printf "This script will use the first one it finds to be true, checked in the above\n"
	printf "order.  #3 and #4 are the recommended options.  #1 and #2 are mainly for\n"
	printf "overriding the system configuration.\n"
	printf "\n"
}

while [ $# -gt 0 ]; do
	optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
	case "$1" in
		--prefix=*)
			PREFIX=$optarg
			shift
			;;

		--bindir=*)
			BINDIR=$optarg
			shift
			;;

		--libdir=*)
			LIBDIR=$optarg
			shift
			;;

		--datadir=*)
			DATADIR=$optarg
			shift
			;;

		--qtdir=*)
			EX_QTDIR=$optarg
			shift
			;;

		--extraconf=*)
			QC_EXTRACONF=$optarg
			shift
			;;

		--release)
			QC_RELEASE="Y"
			shift
			;;

		--debug)
			QC_DEBUG="Y"
			shift
			;;

		--no-separate-debug-info)
			QC_NO_SEPARATE_DEBUG_INFO="Y"
			shift
			;;

		--separate-debug-info)
			QC_SEPARATE_DEBUG_INFO="Y"
			shift
			;;

		--with-idn-inc=*)
			QC_WITH_IDN_INC=$optarg
			shift
			;;

		--with-idn-lib=*)
			QC_WITH_IDN_LIB=$optarg
			shift
			;;

		--with-qca-inc=*)
			QC_WITH_QCA_INC=$optarg
			shift
			;;

		--with-qca-lib=*)
			QC_WITH_QCA_LIB=$optarg
			shift
			;;

		--with-zlib-inc=*)
			QC_WITH_ZLIB_INC=$optarg
			shift
			;;

		--with-zlib-lib=*)
			QC_WITH_ZLIB_LIB=$optarg
			shift
			;;

		--with-qjdns-inc=*)
			QC_WITH_QJDNS_INC=$optarg
			shift
			;;

		--with-qjdns-lib=*)
			QC_WITH_QJDNS_LIB=$optarg
			shift
			;;

		--enable-universal)
			QC_ENABLE_universal="Y"
			shift
			;;

		--disable-qdbus)
			QC_DISABLE_qdbus="Y"
			shift
			;;

		--disable-keychain)
			QC_DISABLE_keychain="Y"
			shift
			;;

		--enable-webkit)
			QC_ENABLE_webkit="Y"
			shift
			;;

		--with-webkit=*)
			QC_WITH_WEBKIT=$optarg
			shift
			;;

		--with-http-parser-inc=*)
			QC_WITH_HTTP_PARSER_INC=$optarg
			shift
			;;

		--with-http-parser-lib=*)
			QC_WITH_HTTP_PARSER_LIB=$optarg
			shift
			;;

		--bundled-http-parser)
			QC_BUNDLED_HTTP_PARSER="Y"
			shift
			;;

		--disable-growl)
			QC_DISABLE_growl="Y"
			shift
			;;

		--with-growl=*)
			QC_WITH_GROWL=$optarg
			shift
			;;

		--enable-whiteboarding)
			QC_ENABLE_whiteboarding="Y"
			shift
			;;

		--disable-xss)
			QC_DISABLE_xss="Y"
			shift
			;;

		--disable-aspell)
			QC_DISABLE_aspell="Y"
			shift
			;;

		--with-aspell-inc=*)
			QC_WITH_ASPELL_INC=$optarg
			shift
			;;

		--with-aspell-lib=*)
			QC_WITH_ASPELL_LIB=$optarg
			shift
			;;

		--disable-enchant)
			QC_DISABLE_enchant="Y"
			shift
			;;

		--disable-hunspell)
			QC_DISABLE_hunspell="Y"
			shift
			;;

		--with-hunspell-inc=*)
			QC_WITH_HUNSPELL_INC=$optarg
			shift
			;;

		--with-hunspell-lib=*)
			QC_WITH_HUNSPELL_LIB=$optarg
			shift
			;;

		--disable-plugins)
			QC_DISABLE_plugins="Y"
			shift
			;;

		--verbose)
			QC_VERBOSE="Y"
			shift
			;;
		--qtselect=*)
			QC_QTSELECT="${optarg}"
			shift
			;;
		--help) show_usage; exit ;;
		*) echo "configure: WARNING: unrecognized options: $1" >&2; shift; ;;
	esac
done

PREFIX=${PREFIX:-/usr/local}
BINDIR=${BINDIR:-$PREFIX/bin}
LIBDIR=${LIBDIR:-$PREFIX/lib}
DATADIR=${DATADIR:-$PREFIX/share}

echo "Configuring Psi ..."

if [ "$QC_VERBOSE" = "Y" ]; then
echo
echo PREFIX=$PREFIX
echo BINDIR=$BINDIR
echo LIBDIR=$LIBDIR
echo DATADIR=$DATADIR
echo EX_QTDIR=$EX_QTDIR
echo QC_EXTRACONF=$QC_EXTRACONF
echo QC_RELEASE=$QC_RELEASE
echo QC_DEBUG=$QC_DEBUG
echo QC_NO_SEPARATE_DEBUG_INFO=$QC_NO_SEPARATE_DEBUG_INFO
echo QC_SEPARATE_DEBUG_INFO=$QC_SEPARATE_DEBUG_INFO
echo QC_WITH_IDN_INC=$QC_WITH_IDN_INC
echo QC_WITH_IDN_LIB=$QC_WITH_IDN_LIB
echo QC_WITH_QCA_INC=$QC_WITH_QCA_INC
echo QC_WITH_QCA_LIB=$QC_WITH_QCA_LIB
echo QC_WITH_ZLIB_INC=$QC_WITH_ZLIB_INC
echo QC_WITH_ZLIB_LIB=$QC_WITH_ZLIB_LIB
echo QC_WITH_QJDNS_INC=$QC_WITH_QJDNS_INC
echo QC_WITH_QJDNS_LIB=$QC_WITH_QJDNS_LIB
echo QC_ENABLE_universal=$QC_ENABLE_universal
echo QC_DISABLE_qdbus=$QC_DISABLE_qdbus
echo QC_DISABLE_keychain=$QC_DISABLE_keychain
echo QC_ENABLE_webkit=$QC_ENABLE_webkit
echo QC_WITH_WEBKIT=$QC_WITH_WEBKIT
echo QC_WITH_HTTP_PARSER_INC=$QC_WITH_HTTP_PARSER_INC
echo QC_WITH_HTTP_PARSER_LIB=$QC_WITH_HTTP_PARSER_LIB
echo QC_BUNDLED_HTTP_PARSER=$QC_BUNDLED_HTTP_PARSER
echo QC_DISABLE_growl=$QC_DISABLE_growl
echo QC_WITH_GROWL=$QC_WITH_GROWL
echo QC_ENABLE_whiteboarding=$QC_ENABLE_whiteboarding
echo QC_DISABLE_xss=$QC_DISABLE_xss
echo QC_DISABLE_aspell=$QC_DISABLE_aspell
echo QC_WITH_ASPELL_INC=$QC_WITH_ASPELL_INC
echo QC_WITH_ASPELL_LIB=$QC_WITH_ASPELL_LIB
echo QC_DISABLE_enchant=$QC_DISABLE_enchant
echo QC_DISABLE_hunspell=$QC_DISABLE_hunspell
echo QC_WITH_HUNSPELL_INC=$QC_WITH_HUNSPELL_INC
echo QC_WITH_HUNSPELL_LIB=$QC_WITH_HUNSPELL_LIB
echo QC_DISABLE_plugins=$QC_DISABLE_plugins
echo
fi

printf "Verifying Qt build environment ... "

if [ -z "$QC_QTSELECT" ]; then
	QC_QTSELECT="$(echo $QT_SELECT | tr -d "qt")"
fi

if [ ! -z "$QC_QTSELECT" ]; then
	QTSEARCHTEXT="$QC_QTSELECT"
else
	QTSEARCHTEXT="4 or 5"
fi

# run qmake and check version
qmake_check() {
	if [ -x "$1" ]; then
		cmd="\"$1\" -query QT_VERSION"
		if [ "$QC_VERBOSE" = "Y" ]; then
			echo "running: $cmd"
		fi
		vout=`/bin/sh -c "$cmd" 2>&1`
		case "${vout}" in
			*.*.*)
				vmaj="${vout%%.*}"
				if [ ! -z "$QC_QTSELECT" ]; then
					if [ "$vmaj" = "$QC_QTSELECT" ]; then
						return 0
					fi
				else
					if [ "$vmaj" = "4" ] || [ "$vmaj" = "5" ]; then
						return 0
					fi
				fi
				;;
		esac
		if [ "$QC_VERBOSE" = "Y" ]; then
			echo "Warning: $1 not for Qt ${QTSEARCHTEXT}"
		fi
	fi
	return 1
}

if [ "$QC_VERBOSE" = "Y" ]; then
	echo
fi

qm=""
qt4_names="qmake-qt4 qmake4"
qt5_names="qmake-qt5 qmake5"
names="qmake"
if [ -z "$QC_QTSELECT" ]; then
	names="${qt5_names} ${qt4_names} $names"
else
	if [ "$QC_QTSELECT" = "4" ]; then
		names="${qt4_names} $names"
	elif [ "$QC_QTSELECT" -ge "5" ]; then
		names="${qt5_names} $names"
	fi
fi

if [ -z "$qm" ] && [ ! -z "$EX_QTDIR" ]; then
	# qt4 check: --qtdir
	for n in $names; do
		qstr=$EX_QTDIR/bin/$n
		if qmake_check "$qstr"; then
			qm=$qstr
			break
		fi
	done
	if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then
		echo "Warning: qmake not found via --qtdir"
	fi

elif [ -z "$qm" ] && [ ! -z "$QTDIR" ]; then
	# qt4 check: QTDIR
	for n in $names; do
		qstr=$QTDIR/bin/$n
		if qmake_check "$qstr"; then
			qm=$qstr
			break
		fi
	done
	if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then
		echo "Warning: qmake not found via \$QTDIR"
	fi

else
	# Try all other implicit checks

	# qtchooser
	if [ -z "$qm" ]; then
		qtchooser=$($WHICH qtchooser 2>/dev/null)
		if [ ! -z "$qtchooser" ]; then
			if [ ! -z "$QC_QTSELECT" ]; then
				versions="$QC_QTSELECT"
			else
				cmd="$qtchooser --list-versions"
				if [ "$QC_VERBOSE" = "Y" ]; then
					echo "running: $cmd"
				fi
				versions=`$cmd`
			fi
			for version in $versions; do
				cmd="$qtchooser -run-tool=qmake -qt=${version} -query QT_INSTALL_BINS"
				if [ "$QC_VERBOSE" = "Y" ]; then
					echo "running: $cmd"
				fi
				qtbins=`$cmd 2>/dev/null`
				if [ ! -z "$qtbins" ] && qmake_check "$qtbins/qmake"; then
					qm="$qtbins/qmake"
					break
				fi
			done
		fi
	fi
	if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then
		echo "Warning: qmake not found via qtchooser"
	fi

	# qt4: pkg-config
	if [ -z "$qm" ]; then
		cmd="pkg-config QtCore --variable=exec_prefix"
		if [ "$QC_VERBOSE" = "Y" ]; then
			echo "running: $cmd"
		fi
		str=`$cmd 2>/dev/null`
		if [ ! -z "$str" ]; then
			for n in $names; do
				qstr=$str/bin/$n
				if qmake_check "$qstr"; then
					qm=$qstr
					break
				fi
			done
		fi
	fi
	if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then
		echo "Warning: qmake not found via pkg-config"
	fi

	# qmake in PATH
	if [ -z "$qm" ]; then
		for n in $names; do
			qstr=`$WHICH -a $n 2>/dev/null`
			for q in $qstr; do
				if qmake_check "$q"; then
					qm="$q"
					break
				fi
			done
			if [ ! -z "$qm" ]; then
				break
			fi
		done
	fi
	if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then
		echo "Warning: qmake not found via \$PATH"
	fi

	# end of implicit checks
fi

if [ -z "$qm" ]; then
	if [ "$QC_VERBOSE" = "Y" ]; then
		echo " -> fail"
	else
		echo "fail"
	fi
	printf "\n"
	printf "Reason: Unable to find the 'qmake' tool for Qt ${QTSEARCHTEXT}.\n"
	printf "\n"
	show_qt_info
	exit 1;
fi
if [ "$QC_VERBOSE" = "Y" ]; then
	echo qmake found in "$qm"
fi

# try to determine the active makespec
defmakespec=$QMAKESPEC
if [ -z "$defmakespec" ]; then
	if $WHICH readlink >/dev/null 2>&1; then
		READLINK=`$WHICH readlink`
	fi
	if [ ! -z "$READLINK" ]; then
		qt_mkspecsdir=`"$qm" -query QT_INSTALL_DATA`/mkspecs
		if [ -d "$qt_mkspecsdir" ] && [ -h "$qt_mkspecsdir/default" ]; then
			defmakespec=`$READLINK $qt_mkspecsdir/default`
		fi
	fi
fi

if [ "$QC_VERBOSE" = "Y" ]; then
	echo makespec is $defmakespec
fi

qm_spec=""
# if the makespec is macx-xcode, force macx-g++
if [ "$defmakespec" = "macx-xcode" ]; then
	qm_spec=macx-g++
	QMAKESPEC=$qm_spec
	export QMAKESPEC
	if [ "$QC_VERBOSE" = "Y" ]; then
		echo overriding makespec to $qm_spec
	fi
fi

gen_files() {
cat >"$1/modules.cpp" <<EOT
#line 1 "qt5.qcm"
/*
-----BEGIN QCMOD-----
name: Qt >= 5.0.0
-----END QCMOD-----
*/
class qc_qt5 : public ConfObj
{
public:
    qc_qt5(Conf *c) : ConfObj(c) {}
    QString name() const { return "Qt >= 5.0.0"; }
    QString shortname() const { return "qt5"; }
    bool exec()
    {
    	return(QT_VERSION >= 0x050000);
    }

    QString resultString() const
    {
    	return QT_VERSION_STR;
    }
};

class QtCompFinder : public ConfObj
{
protected:
    QString compId;
    QString compShortName;
    QString compName;
    QString extraConfIfFound;
    QString finderResult;

public:
    /**
     * id - (QT += <id>)
     * shortName - used with QC_ENABLE_<shortName> | QC_DISABLE_<shortName> env vars
     *             MUST MATCH with qcm module name without extension
     * name - something visible in the log
     * extraConfIfFound - extra string added to conf.pri if found
     */
    QtCompFinder(const QString &id,const QString &shortName, const QString &name,
    	     const QString &extraConfIfFound, Conf *c) :
    	ConfObj(c), compId(id), compShortName(shortName), compName(name),
    	extraConfIfFound(extraConfIfFound)
    {}

    QString name() const { return compName; }
    QString shortname() const { return compShortName; }
    QString resultString() const
    {
        if (!finderResult.isEmpty())
            return finderResult;

        return ConfObj::resultString();
    }

    bool exec()
    {
        if (!conf->getenv("QC_DISABLE_" + compShortName).isEmpty()) {
            finderResult = "disabled";
            return false;
        }

    	QString proextra =
    	"CONFIG += qt\\n"
    	"QT -= gui\\n"
    	"QT += ";
    	
    	proextra += compId;

    	QString str =
    	"\\n"
    	"int main()\\n"
    	"{\\n"
    	"	return 0;\\n"
    	"}\\n";

    	int ret;
    	if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra, &ret))
    		return false;
    	if(ret != 0)
    		return false;

    	if (!extraConfIfFound.isEmpty()) {
    		conf->addExtra(extraConfIfFound);
    	}

    	return true;
    }
};

#define QC_AS_STR(s) #s

#define QC_SILENT_NOT_FOUND(modname) \\
class qc_##modname : public ConfObj \\
{ \\
public: \\
    qc_##modname(Conf *c) : ConfObj(c) {} \\
    QString name() const { return QC_AS_STR(modname); } \\
    QString shortname() const { return QC_AS_STR(modname); } \\
    QString checkString() const { return QString(); } \\
    bool exec() { return false; } \\
};

#define QC_FIND_QT_COMP_BASE(id, shortname, name, extraConfIfFound, suffix) \\
class qc_##shortname##suffix : public QtCompFinder \\
{ \\
public: \\
    qc_##shortname##suffix(Conf *c) : QtCompFinder(QC_AS_STR(id), QC_AS_STR(shortname), QC_AS_STR(name), extraConfIfFound, c) {} \\
};

#define QC_FIND_QT_COMP_E(id, shortname, name, extraConfIfFound) QC_FIND_QT_COMP_BASE(id, shortname, name, extraConfIfFound,)
#define QC_FIND_QT_COMP(id, shortname, name) QC_FIND_QT_COMP_E(id, shortname, name, "")
#line 1 "buildmodeapp.qcm"
/*
-----BEGIN QCMOD-----
name: buildmodeapp
section: project
arg: release,Build with debugging turned off (default).
arg: debug,Build with debugging turned on.
arg: no-separate-debug-info,Do not store debug information in a separate file (default for mac).
arg: separate-debug-info,Strip debug information into a separate .debug file (default for non-mac).
-----END QCMOD-----
arg: debug-and-release,Build two versions, with and without debugging turned on (mac only).
*/

#define QC_BUILDMODE
bool qc_buildmode_release = false;
bool qc_buildmode_debug = false;
bool qc_buildmode_separate_debug_info = false;

#define PSI_DIR_NAME "psi-plus"

static QString sourceDir;

// this is a utility function required by few other modules
static bool psiGenerateFile(const QString &inFile, const QString &outFile, const QHash<QString,QString> &vars)
{
    QFile fin(inFile);
    QFile fout(outFile);
    if(!fin.open(QIODevice::ReadOnly | QIODevice::Text) || !fout.open(QIODevice::WriteOnly | QIODevice::Truncate))
    	return false;

    QTextStream tin(&fin);
    QTextStream tout(&fout);
    while(!tin.atEnd())
    {
    	QString line = tin.readLine();

    	QHashIterator<QString,QString> it(vars);
    	while(it.hasNext())
    	{
    		it.next();
    		line.replace("@@" + it.key() + "@@", it.value());
    	}

    	tout << line << endl;
    }

    return true;
}

class qc_buildmodeapp : public ConfObj
{
public:
    qc_buildmodeapp(Conf *c) : ConfObj(c) {}
    QString name() const { return "buildmodeapp"; }
    QString shortname() const { return "buildmodeapp"; }

    // no output
    QString checkString() const { return QString(); }

    bool exec()
    {
    	QFileInfo fi(qc_getenv("QC_COMMAND"));
    	sourceDir = fi.absolutePath();

    	// first, parse out the options
    	bool opt_release = false;
    	bool opt_debug = false;
    	bool opt_debug_and_release = false;
    	bool opt_no_separate_debug_info = false;
    	bool opt_separate_debug_info = false;

    	if(conf->getenv("QC_RELEASE") == "Y")
    		opt_release = true;
    	if(conf->getenv("QC_DEBUG") == "Y")
    		opt_debug = true;
    	if(conf->getenv("QC_DEBUG_AND_RELEASE") == "Y")
    		opt_debug_and_release = true;
    	if(conf->getenv("QC_NO_SEPARATE_DEBUG_INFO") == "Y")
    		opt_no_separate_debug_info = true;
    	if(conf->getenv("QC_SEPARATE_DEBUG_INFO") == "Y")
    		opt_separate_debug_info = true;

    	bool staticmode = false;
    	if(conf->getenv("QC_STATIC") == "Y")
    		staticmode = true;

#ifndef Q_OS_MAC
    	if(opt_debug_and_release)
    	{
    		printf("\\nError: The --debug-and-release option is for mac only.\\n");
    		exit(1);
    	}
#endif

    	// sanity check exclusive options
    	int x;

    	// build mode
    	x = 0;
    	if(opt_release)
    		++x;
    	if(opt_debug)
    		++x;
    	if(opt_debug_and_release)
    		++x;
    	if(x > 1)
    	{
    		printf("\\nError: Use only one of --release, --debug, or --debug-and-release.\\n");
    		exit(1);
    	}

    	// debug info
    	x = 0;
    	if(opt_no_separate_debug_info)
    		++x;
    	if(opt_separate_debug_info)
    		++x;
    	if(x > 1)
    	{
    		printf("\\nError: Use only one of --separate-debug-info or --no-separate-debug-info\\n");
    		exit(1);
    	}

    	// now process the options

    	if(opt_release)
    		qc_buildmode_release = true;
    	else if(opt_debug)
    		qc_buildmode_debug = true;
    	else if(opt_debug_and_release)
    	{
    		qc_buildmode_release = true;
    		qc_buildmode_debug = true;
    	}
    	else // default
    		qc_buildmode_release = true;

    	if(opt_separate_debug_info)
    		qc_buildmode_separate_debug_info = true;
    	else if(opt_no_separate_debug_info)
    	{
    		// nothing to do
    	}
    	else // default
    	{
#ifndef Q_OS_MAC
    		qc_buildmode_separate_debug_info = true;
#endif
    	}

    	// make the string
    	QStringList opts;
    	QString other;

    	if(qc_buildmode_release && qc_buildmode_debug)
    	{
    		opts += "debug_and_release";
    		opts += "build_all";
    	}
    	else if(qc_buildmode_release)
    		opts += "release";
    	else // qc_buildmode_debug
    		opts += "debug";

    	if(qc_buildmode_separate_debug_info)
    	{
    		opts += "separate_debug_info";
    		other += "*-g++*:QMAKE_CFLAGS += -g\\n";
    		other += "*-g++*:QMAKE_CXXFLAGS += -g\\n";
    	}

    	QString str = "CONFIG -= debug_and_release debug release\\n";
    	str += QString("CONFIG += ") + opts.join(" ") + '\\n';
    	conf->addExtra(str);

    	if(!other.isEmpty())
    		conf->addExtra(other);

    	return true;
    }
};
#line 1 "idn.qcm"
/*
-----BEGIN QCMOD-----
name: libidn
arg: with-idn-inc=[path],Path to libidn include files
arg: with-idn-lib=[path],Path to libidn library or framework files
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_idn
//----------------------------------------------------------------------------
class qc_idn : public ConfObj
{
public:
    qc_idn(Conf *c) : ConfObj(c) {}
    QString name() const { return "LibIDN"; }
    QString shortname() const { return "libidn"; }
    bool exec()
    {
        QString idn_incdir, idn_libdir, idn_prefixdir;
    	idn_incdir = conf->getenv("QC_WITH_IDN_INC");
    	idn_libdir = conf->getenv("QC_WITH_IDN_LIB");
        idn_prefixdir = conf->getenv("PREFIX");

        if (!idn_incdir.isEmpty() || !idn_libdir.isEmpty() || !idn_prefixdir.isEmpty()) { // prefer this if given
    		if ((!idn_incdir.isEmpty() && conf->checkHeader(idn_incdir, "stringprep.h")) ||
    		    (idn_incdir.isEmpty() && conf->findHeader("stringprep.h", QStringList(), &idn_incdir))) {
    			conf->addIncludePath(idn_incdir);
    		} else {
    			printf("Headers not found!\\n");
    			return false;
    		}

#ifdef Q_OS_WIN
            conf->addDefine("LIBIDN_STATIC"); // it's need only for iris anyway
            QString staticLibName = qc_buildmode_debug? "libidnd" : "libidn";
            QString dynamicLibName = qc_buildmode_debug? "idnd" : "idn";
            QStringList libNames = QStringList() << staticLibName << dynamicLibName;
#else
            QStringList libNames = QStringList() << "idn";
#endif
            bool libFound = false;
            foreach (const QString &libName, libNames) {
                if((!idn_libdir.isEmpty() && conf->checkLibrary(idn_libdir, libName)) ||
                   (idn_libdir.isEmpty() && conf->findLibrary(libName, &idn_libdir))) {
                    conf->addLib(idn_libdir.isEmpty()? QString("-l") + libName : QString("-L%1 -l%2").arg(idn_libdir, libName));
                    libFound = true;
                    break;
                }
            }
            if (!libFound) {
                printf("Libraries not found!\\n");
            }
            return libFound;
    	}

    	QStringList incs;
    	QString version, libs, other;
    	if(conf->findPkgConfig("libidn", VersionAny, QString::null, &version, &incs, &libs, &other))
    	{
    		for(int n = 0; n < incs.count(); ++n)
    			conf->addIncludePath(incs[n]);
    		if(!libs.isEmpty())
    			conf->addLib(libs);
    		return true;
    	}

    	return false;
    }
};
#line 1 "qca.qcm"
/*
-----BEGIN QCMOD-----
name: QCA >= 2.0
arg: with-qca-inc=[path],Path to QCA include files
arg: with-qca-lib=[path],Path to QCA library or framework files
-----END QCMOD-----
*/

// adapted from crypto.prf
static QString internal_crypto_prf(const QString &incdir, const QString &libdir, const QString &frameworkdir)
{
    QString out = QString(
"QCA_INCDIR = %1\\n"
"QCA_LIBDIR = %2\\n"
"QMAKE_RPATHDIR = %2\\n"
"QCA_FRAMEWORKDIR = %3\\n"
"\\n"
"CONFIG *= qt\\n"
"\\n"
"LINKAGE =\\n"
"QCA_NAME = qca-qt5\\n"
"\\n"
"!isEmpty(QCA_FRAMEWORKDIR): {\\n"
"    framework_dir = \$\$QCA_FRAMEWORKDIR\\n"
"    exists(\$\$framework_dir/\$\${QCA_NAME}.framework) {\\n"
"    	#QMAKE_FRAMEWORKPATH *= \$\$framework_dir\\n"
"    	LIBS *= -F\$\$framework_dir\\n"
"    	INCLUDEPATH += \$\$framework_dir/\$\${QCA_NAME}.framework/Headers\\n"
"    	LINKAGE = -framework \$\${QCA_NAME}\\n"
"    }\\n"
"}\\n"
"\\n"
"# else, link normally\\n"
"isEmpty(LINKAGE) {\\n"
"    !isEmpty(QCA_INCDIR):INCLUDEPATH += \$\$QCA_INCDIR/QtCrypto\\n"
"    !isEmpty(QCA_LIBDIR):LIBS += -L\$\$QCA_LIBDIR\\n"
"    LINKAGE = -l\$\${QCA_NAME}\\n"
"    CONFIG(debug, debug|release) {\\n"
"    	windows:LINKAGE = -l\$\${QCA_NAME}d\\n"
"    	mac:LINKAGE = -l\$\${QCA_NAME}_debug\\n"
"    }\\n"
"}\\n"
"\\n"
"LIBS += \$\$LINKAGE\\n"
    ).arg(incdir, libdir, frameworkdir);
    return out;
}

// set either libdir or frameworkdir, but not both
static bool qca_try(Conf *conf, const QString &incdir, const QString &libdir, const QString &frameworkdir, bool release, bool debug, QString *_prf)
{
    QString proextra;
    QString prf;
    if (!incdir.isEmpty() || !libdir.isEmpty() || !frameworkdir.isEmpty()) {
    	prf = internal_crypto_prf(conf->escapePath(incdir), conf->escapePath(libdir), frameworkdir);
    } else {
    	prf = "CONFIG += crypto\\n";
    }
    proextra =
    "CONFIG += qt\\n"
    "CONFIG -= debug_and_release debug release\\n"
    "QT -= gui\\n";
    proextra += prf;

    QString str =
    "#include <QtCrypto>\\n"
    "\\n"
    "int main()\\n"
    "{\\n"
    "	unsigned long x = QCA_VERSION;\\n"
    "	if(x >= 0x020000 && x < 0x030000) return 0; else return 1;\\n"
    "}\\n";

    // test desired versions, potentially both release and debug

    if(release)
    {
    	int ret;
    	if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra + "CONFIG += release\\n", &ret) || ret != 0)
    		return false;
    }

    if(debug)
    {
    	int ret;
    	if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra + "CONFIG += debug\\n", &ret) || ret != 0)
    		return false;
    }

    *_prf = prf;
    return true;
}

static bool qca_try_lib(Conf *conf, const QString &incdir, const QString &libdir, bool release, bool debug, QString *prf)
{
    return qca_try(conf, incdir, libdir, QString(), release, debug, prf) ||
            qca_try(conf, incdir + "/Qca-qt5", libdir, QString(), release, debug, prf);
}

static bool qca_try_framework(Conf *conf, const QString &frameworkdir, bool release, bool debug, QString *prf)
{
    return qca_try(conf, QString(), QString(), frameworkdir, release, debug, prf);
}

static bool qca_try_ext_prf(Conf *conf, bool release, bool debug, QString *prf)
{
    return qca_try(conf, QString(), QString(), QString(), release, debug, prf);
}

//----------------------------------------------------------------------------
// qc_qca
//----------------------------------------------------------------------------
class qc_qca : public ConfObj
{
public:
    qc_qca(Conf *c) : ConfObj(c) {}
    QString name() const { return "QCA >= 2.0"; }
    QString shortname() const { return "qca"; }
    bool exec()
    {
    	// get the build mode
#ifdef QC_BUILDMODE
    	bool release = qc_buildmode_release;
    	bool debug = qc_buildmode_debug;
#else
    	// else, default to just release mode
    	bool release = true;
    	bool debug = false;
#endif

    	QString qca_incdir, qca_libdir, qca_crypto_prf;
    	qca_incdir = conf->getenv("QC_WITH_QCA_INC");
    	qca_libdir = conf->getenv("QC_WITH_QCA_LIB");

#if defined(Q_OS_MAC)
    	if(!qca_libdir.isEmpty() && qca_try_framework(conf, qca_libdir, release, debug, &qca_crypto_prf))
    	{
    		conf->addExtra(qca_crypto_prf);
    		return true;
    	}
#endif

    	if(!qca_incdir.isEmpty() && !qca_libdir.isEmpty() && qca_try_lib(conf, qca_incdir, qca_libdir, release, debug, &qca_crypto_prf))
    	{
    		conf->addExtra(qca_crypto_prf);
    		return true;
    	}
    	
    	if (qca_try_ext_prf(conf, release, debug, &qca_crypto_prf))
    	{
    		conf->addExtra(qca_crypto_prf);
    		return true;
    	}

    	QStringList incs;
    	QString version, libs, other;

        if(conf->findPkgConfig("qca2-qt5", VersionMin, "2.0.0", &version, &incs, &libs, &other))
        {
            for(int n = 0; n < incs.count(); ++n)
                conf->addIncludePath(incs[n]);
            if(!libs.isEmpty())
                conf->addLib(libs);
            return true;
        }

    	QStringList prefixes;
#ifndef Q_OS_WIN
        prefixes += "/usr";
    	prefixes += "/usr/local";
#endif
        QString prefix = conf->getenv("PREFIX");
        if (!prefix.isEmpty()) {
            prefixes += prefix;
        }

    	for(int n = 0; n < prefixes.count(); ++n)
    	{
    		const QString &prefix = prefixes[n];
    		if(qca_try_lib(conf, prefix + "/include", prefix + "/lib", release, debug, &qca_crypto_prf))
    		{
    			conf->addExtra(qca_crypto_prf);
    			return true;
    		}
    	}

    	return false;
    }
};
#line 1 "zlib.qcm"
/*
-----BEGIN QCMOD-----
name: zlib
arg: with-zlib-inc=[path],Path to zlib include files
arg: with-zlib-lib=[path],Path to zlib library files
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_zlib
//----------------------------------------------------------------------------
class qc_zlib : public ConfObj
{
public:
    qc_zlib(Conf *c) : ConfObj(c) {}
    QString name() const { return "zlib"; }
    QString shortname() const { return "zlib"; }

    bool exec()
    {
    	QStringList incs;
    	QString version, libs, other;
    	QString s;
    	
    	

    	if(!conf->findPkgConfig("zlib", VersionAny, "", &version, &incs, &libs, &other)) {

    		s = conf->getenv("QC_WITH_ZLIB_INC");
    		if(!s.isEmpty()) {
    			if(!conf->checkHeader(s, "zlib.h"))
    				return false;
    		}
    		else {
    			if(!conf->findHeader("zlib.h", QStringList(), &s))
    				return false;
    		}

    		QStringList libNames = QStringList() << "z";
    		QString libName;
#ifdef Q_OS_WIN
    		libNames << (qc_buildmode_debug? "zlibd" : "zlib");
#endif
    		for (;;) {
    			s = conf->getenv("QC_WITH_ZLIB_LIB");
    			if(!s.isEmpty()) {
    				foreach (const QString l, libNames) 
    					if(conf->checkLibrary(s, l)) {
    						libName = l;
    						break;
    					}
    			} else {
    				foreach (const QString l, libNames) 
    					if(conf->findLibrary(l, &s)) {
    						libName = l;
    						break;
    					}
    			}
    			
    			if(!libName.isEmpty())
    				break;
    					
    			return false;
    		}
    		if (!s.isEmpty()) {
    			libs = QString("-L%1 -l%2").arg(s, libName);
    		} else {
    			libs = s.isEmpty()? QString("-l")+libName : QString("-L%1 -l%2").arg(s, libName);
    		}
    	}

    	foreach(const QString &inc, incs) {
    		conf->addIncludePath(inc);
    	}
    	conf->addLib(libs);

#ifdef Q_OS_WIN
    	// HACK: on windows, always use psi's bundled minizip
    	conf->addExtra("CONFIG += psi-minizip");
    	return true;
#else
    	incs.clear();
    	libs.clear();
    	if(!conf->findPkgConfig("minizip", VersionAny, "", &version, &incs, &libs, &other)) {

    		s = conf->getenv("QC_WITH_MINIZIP_INC");
    		if ((!s.isEmpty() && conf->checkHeader(s, "unzip.h")) ||
    		    (s.isEmpty() && conf->findHeader("unzip.h", QStringList(), &s))) {
    			incs.append(s);
    		}

    		s = conf->getenv("QC_WITH_MINIZIP_LIB");
    		if((!s.isEmpty() && conf->checkLibrary(s, "minizip")) ||
    		   (s.isEmpty() && conf->findLibrary("minizip", &s))) {
    			libs = s.isEmpty()? "-lminizip" : QString("-L%1 -lminizip").arg(s);
    		}
    	}

    	if (!incs.isEmpty() && !libs.isEmpty()) {
    		foreach(const QString &inc, incs) {
    			conf->addIncludePath(inc);
    		}
    		conf->addLib(libs);
    	} else {
    		conf->addExtra("CONFIG += psi-minizip");
    	}

    	return true;
#endif
    }
};
#line 1 "qjdns.qcm"
/*
-----BEGIN QCMOD-----
name: jdns
arg: with-qjdns-inc=[path],Path to QJDns include files
arg: with-qjdns-lib=[path],Path to QJDns library files
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qjdns
//----------------------------------------------------------------------------
class qc_qjdns : public ConfObj
{
public:
    qc_qjdns(Conf *c) : ConfObj(c) {}
    QString name() const { return "QJDns"; }
    QString shortname() const { return "qjdns"; }
    QString resultString() const
    {
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    	return "Disabled for Qt5 and above";
#else
    	return ConfObj::resultString();
#endif
    }
    bool exec()
    {
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    	return true; // hack. TODO: figure out how to force jdns
#endif
    	conf->addExtra("CONFIG += need_jdns");
#if defined Q_OS_WIN || defined Q_OS_MAC
    	// HACK: on Windows and Mac OS X, always use psi's bundled qjdns
    	conf->addExtra("CONFIG += iris-qjdns");
    	return true;
#else
    	QStringList incs;
    	QString version, libs, other;
    	QString s;

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    	bool found = conf->findPkgConfig("qjdns-qt5", VersionMin, "2.0.3", &version, &incs, &libs, &other);
#else
    	bool found = conf->findPkgConfig("qjdns-qt4", VersionMin, "2.0.3", &version, &incs, &libs, &other);
#endif
    	if(!found && !conf->findPkgConfig("qjdns", VersionMin, "2.0.0", &version, &incs, &libs, &other)) {
    		s = conf->getenv("QC_WITH_QJDNS_INC");
    		if ((!s.isEmpty() && conf->checkHeader(s, "qjdns.h")) ||
    			(s.isEmpty() && conf->findHeader("qjdns.h", QStringList(), &s))) {
    			incs.append(s);
    		}

    		s = conf->getenv("QC_WITH_QJDNS_LIB");
    		if((!s.isEmpty() && conf->checkLibrary(s, "qjdns")) ||
    		   (s.isEmpty() && conf->findLibrary("qjdns", &s))) {
    			libs = s.isEmpty()? "-lqjdns -ljdns" : QString("-L%1 -lqjdns -ljdns").arg(s);
    		}
    	}

    	if (!incs.isEmpty() && !libs.isEmpty()) {
    		foreach(const QString &inc, incs) {
    			conf->addIncludePath(inc);
    		}
    		conf->addLib(libs);
    		conf->addExtra("CONFIG += ext-qjdns");
    	}

    	return true;
#endif
    }
};
#line 1 "x11.qcm"
/*
-----BEGIN QCMOD-----
name: Xorg X11
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_x11
//----------------------------------------------------------------------------
class qc_x11 : public ConfObj
{
public:
    qc_x11(Conf *c) : ConfObj(c) {}

    QString name() const { return "Xorg X11"; }
    QString shortname() const { return "x11"; }
    QString checkString() const { return QString(); }

    bool exec()
    {
    	QString str =
    		"int main()\\n"
    		"{\\n"
    		"    return 0;\\n"
    		"}\\n";
    	QString proextra = "CONFIG += x11\\n";
#if QT_VERSION >= 0x050000 && defined Q_OS_LINUX
    	proextra += "LIBS += -lxcb\\n";
    	proextra += "QT += x11extras\\n";
#endif
    	return conf->doCompileAndLink(str, QStringList(), QString(), proextra, NULL);
    }
};
#line 1 "universal.qcm"
/*
-----BEGIN QCMOD-----
name: Mac OS X universal binary support
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_universal
//----------------------------------------------------------------------------
class qc_universal : public ConfObj
{
public:
    qc_universal(Conf *c) : ConfObj(c) {}
    QString name() const { return "universal binary support"; }
    QString shortname() const { return "universal"; }
    QString checkString() const { return QString(); }

    bool exec()
    {
#ifdef Q_OS_MAC
    	conf->addExtra("CONFIG += qc_universal");
#endif
    	return true;
    }
};
#line 1 "qdbus.qcm"
/*
-----BEGIN QCMOD-----
name: QDBUS
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qdbus
//----------------------------------------------------------------------------

#ifdef Q_OS_WIN
QC_SILENT_NOT_FOUND(qdbus)
#else
// id, shortname, name, extraConfIfFound
QC_FIND_QT_COMP_E(dbus, qdbus, QtDbus, "CONFIG += dbus")
#endif
#line 1 "keychain.qcm"
/*
-----BEGIN QCMOD-----
name: Qt Keychain
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_keychain
//----------------------------------------------------------------------------
// id, shortname, name, extraConfIfFound
QC_FIND_QT_COMP_BASE(Qt5Keychain, keychain, Qt Keychain, "CONFIG += keychain", _base)

class qc_keychain : public qc_keychain_base
{
public:
    qc_keychain(Conf *c) :
        qc_keychain_base(c)
    {}

    bool exec()
    {
        if (qc_keychain_base::exec()) {
            conf->addExtra("CONFIG += keychain_with_qtmodule");
            return true;
        }

        // try to find by path
        QString s;
        if (!conf->findHeader("qt5keychain/keychain.h", QStringList(), &s)) {
            qWarning("keychain header qt5keychain/keychain.h is not found");
            return false;
        }

        QStringList libnames;
#ifdef _MSC_VER
# ifdef QC_BUILDMODE
    	libnames += (qc_buildmode_debug? "libqt5keychaind" : "libqt5keychain"); // possibly static
        libnames += (qc_buildmode_debug? "qt5keychaind" : "qt5keychain"); // possibly dynamic
# else
    	libnames << "libqt5keychain" << "qt5keychain";
# endif
#else
        libnames << "qt5keychain";
#endif
        QString libName;
        foreach (const QString l, libnames) 
            if(conf->findLibrary(l, &s)) {
                libName = l;
                break;
            }

        if(libName.isEmpty()) {
            qWarning("keychain library qt5keychain is not found");
            return false;
        }
        conf->addLib(QString("-L%1 -l%2").arg(s, libName));

        // header and library were found by default paths. lets just add extra
        conf->addExtra(extraConfIfFound);
        return true;
    }
};
#line 1 "qtmultimedia.qcm"
/*
-----BEGIN QCMOD-----
name: QtMultimedia
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qtmultimedia
//----------------------------------------------------------------------------
// id, shortname, name
QC_FIND_QT_COMP(multimedia, qtmultimedia, QtMultimedia)
#line 1 "qtconcurrent.qcm"
/*
-----BEGIN QCMOD-----
name: QtConcurrent
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qtconcurrent
//----------------------------------------------------------------------------
// id, shortname, name
QC_FIND_QT_COMP(concurrent, qtconcurrent, QtConcurrent)
#line 1 "qtsql.qcm"
/*
-----BEGIN QCMOD-----
name: QtSql
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qtsql
//----------------------------------------------------------------------------
// id, shortname, name
QC_FIND_QT_COMP(sql, qtsql, QtSql)
#line 1 "qtwidgets.qcm"
/*
-----BEGIN QCMOD-----
name: QtWidgets
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qtwidgets
//----------------------------------------------------------------------------
// id, shortname, name
QC_FIND_QT_COMP(widgets, qtwidgets, QtWidgets)
#line 1 "qtnetwork.qcm"
/*
-----BEGIN QCMOD-----
name: QtNetwork
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qtnetwork
//----------------------------------------------------------------------------
// id, shortname, name
QC_FIND_QT_COMP(network, qtnetwork, QtNetwork)
#line 1 "qtxml.qcm"
/*
-----BEGIN QCMOD-----
name: QtXml
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_qtxml
//----------------------------------------------------------------------------
// id, shortname, name
QC_FIND_QT_COMP(xml, qtxml, QtXml)
#line 1 "webkit.qcm"
/*
-----BEGIN QCMOD-----
name: webkit
arg: with-webkit=[type],type of webkit QtWebKit/QtWebEngine
-----END QCMOD-----
*/

QString qc_webkit_type;

//----------------------------------------------------------------------------
// qc_webkit
//----------------------------------------------------------------------------
class qc_webkit : public ConfObj
{
    QString webkitType;
public:
    qc_webkit(Conf *c) : ConfObj(c) {}
    QString name() const { return "QtWebKit"; }
    QString shortname() const { return "webkit"; }
    bool exec()
    {
    	if (!conf->getenv("QC_DISABLE_webkit").isEmpty()) {
    		webkitType = "disabled";
    		return false;
    	}

    	QStringList tryList;
    	QString wt = conf->getenv("QC_WITH_WEBKIT").toLower();
    	if (wt.isEmpty() || !(wt == "qtwebkit" || wt == "qtwebengine")) {
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
    		tryList << "qtwebengine" << "qtwebkit";
#else
    		tryList << "qtwebkit";
#endif
    	} else {
#if QT_VERSION < QT_VERSION_CHECK(5,6,0)
    		if (wt == "qtwebengine") {
    			webkitType = "unsupported";
    			return false;
    		}
#endif
    		tryList << wt;
    	}

    	QString qt;
    	foreach (const QString &wt, tryList) {
    		if (wt == "qtwebengine") {
    			webkitType = "QtWebEngine";
    			qt = "webenginewidgets webchannel";
    		} else {
    			webkitType = "QtWebKit";
    			qt = "webkit";
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
    			qt += " webkitwidgets";
#endif
    		}

    		QString proextra = "CONFIG += qt webkit\\n";
    		proextra += "QT += " + qt + "\\n";

    		QString str =
    		"\\n"
    		"int main()\\n"
    		"{\\n"
    		"	return 0;\\n"
    		"}\\n";

    		int ret;
    		if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra, &ret))
    			continue;
    		if(ret != 0)
    			continue;

    		conf->addExtra("CONFIG += " + wt);
    		qc_webkit_type = wt;
    		return true;
    	}

    	webkitType = "not found";

    	return false;
    }

    QString resultString() const
    {
    	return webkitType;
    }
};
#line 1 "http-parser.qcm"
/*
-----BEGIN QCMOD-----
name: hunspell
arg: with-http-parser-inc=[path],Path to HTTP Parser include files
arg: with-http-parser-lib=[path],Path to HTTP Parser library files
arg: bundled-http-parser,Build with bundled HTTP Parser
-----END QCMOD-----
*/

#define QC_HTTP_PARSER
bool qc_use_http_parser = false;

//----------------------------------------------------------------------------
// qc_http_parser
//----------------------------------------------------------------------------
class qc_http_parser : public ConfObj
{
    bool use_bundled;
public:
    qc_http_parser(Conf *c) : ConfObj(c), use_bundled(false) {}
    QString name() const { return "HTTP Parser"; }
    QString shortname() const { return "httpparser"; }

    QString resultString() const
    {
    	if (qc_use_http_parser) {
    		if (use_bundled)
    			return "bundled";
    		return ConfObj::resultString();
    	}
    	return "Not needed w/o webengine";
    }

    bool exec()
    {
    	qc_use_http_parser = (qc_webkit_type == "qtwebengine");
    	if (!qc_use_http_parser)
    		return true; // http parser is not needed. success.

    	QString s;
    	if(conf->getenv("QC_BUNDLED_HTTP_PARSER") == "Y") {
    		goto use_bundled_lbl;
    	}

#if !(defined(Q_OS_WIN) || defined(Q_OS_MAC))
    	s = conf->getenv("QC_WITH_HTTP_PARSER_INC");
    	if(!s.isEmpty()) {
    		if(!conf->checkHeader(s, "http_parser.h")) {
    			qWarning("HTTP Parser includes not found!");
    			return false;
    		}
    		conf->addIncludePath(s);
    	}
    	else {
    		QStringList sl;
    		sl += "/usr/include";
    		sl += "/usr/local/include";
    		sl += "/sw/include";
    		if(!conf->findHeader("http_parser.h", sl, &s)) {
    			qWarning("HTTP Parser includes not found. Use bundled");
    			goto use_bundled_lbl;
    		}
    		conf->addIncludePath(s);
    	}

    	s = conf->getenv("QC_WITH_HTTP_PARSER_LIB");
    	if(!s.isEmpty()) {
    		if(!conf->checkLibrary(s, "http_parser")) {
    			qWarning("HTTP Parser libraries not found!");
    			return false;
    		}
    		conf->addLib(QString("-L") + s);
    	}
    	else {
    		if(!conf->findLibrary("http_parser", &s)) {
    			qWarning("HTTP Parser libraries not found. Use bundled");
    			goto use_bundled_lbl;
    		}
    		if (!s.isEmpty())
    			conf->addLib(QString("-L") + s);
    	}

    	conf->addLib("-lhttp_parser");

    	return true;
#endif
use_bundled_lbl:
    	use_bundled = true;
    	conf->addExtra("CONFIG += bundled_http_parser");
    	return true;

    }
};
#line 1 "growl.qcm"
/*
-----BEGIN QCMOD-----
name: Growl
arg: with-growl=[path],Path to the Growl framework
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_growl
//----------------------------------------------------------------------------
class qc_growl : public ConfObj
{
public:
    qc_growl(Conf *c) : ConfObj(c) {}
    QString name() const { return "Growl"; }
    QString shortname() const { return "growl"; }
#ifndef Q_OS_MAC
    QString checkString() const { return QString(); }
#endif

    // TODO: This should go into ConfObj
    bool checkFramework(const QString &path, const QString &name)
    {
    	QString str =
    	"int main()\\n"
    	"{\\n"
    	"    return 0;\\n"
    	"}\\n";

    	QString extra;
    	if(!path.isEmpty())
    		extra += QString("-F") + path + ' ';
    	extra += QString("-framework ") + name;
    	if(!conf->doCompileAndLink(str, QStringList(), extra, "", NULL))
    		return false;
    	return true;
    }

    // TODO: This should go into ConfObj
    void addFrameworkPath(const QString& str)
    {
    	conf->addExtra("QMAKE_CXXFLAGS += -F" + str);
    	conf->addExtra("QMAKE_OBJECTIVE_CFLAGS += -F" + str);
    	conf->addLib("-F" + str);
    }

    bool exec()
    {
#ifdef Q_OS_MAC
    	QString growl_path = conf->getenv("QC_WITH_GROWL");
    	if(!checkFramework(growl_path, "Growl"))
    		return false;

    	if(!growl_path.isEmpty())
    		addFrameworkPath(growl_path);
    	conf->addLib("-framework Growl");
    	conf->addDefine("HAVE_GROWL");

    	return true;
#else
    	return false;
#endif
    }
};
#line 1 "whiteboarding.qcm"
/*
-----BEGIN QCMOD-----
name: White Board support
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_whiteboarding
//----------------------------------------------------------------------------
static bool qc_qtsvg_found = false;
class qc_whiteboarding : public QtCompFinder
{
public:
    qc_whiteboarding(Conf *c) : QtCompFinder("svg", "whiteboarding", "White Board support", "", c) {}
    QString resultString() const
    {
    	if (!qc_qtsvg_found) {
    		return "QtSVG is not found";
    	}
    	return ConfObj::resultString();
    }

    bool exec()
    {
    	if (!QtCompFinder::exec()) {
    		return false;
    	}
    	qc_qtsvg_found = true;

    	conf->addDefine("WHITEBOARDING");

    	// Finish
    	conf->addExtra("CONFIG += whiteboarding");

    	qWarning("");
    	qWarning("");
    	qWarning("        !!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!");
    	qWarning("        WHITEBOARDING SUPPORT IS STILL UNFINISHED !!!");
    	qWarning("        USE AT YOUR OWN RISK !!!");

    	return true;
    }
};
#line 1 "xss.qcm"
/*
-----BEGIN QCMOD-----
name: the XScreenSaver extension
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_xss
//----------------------------------------------------------------------------
class qc_xss : public ConfObj
{
public:
    qc_xss(Conf *c) : ConfObj(c) {}

    QString name() const { return "the XScreenSaver extension"; }
    QString shortname() const { return "xss"; }
#ifdef Q_OS_WIN
    QString checkString() const { return QString(); }
#endif

    bool exec()
    {
#ifdef Q_OS_WIN
    	// skip XSS support on windows
    	return false;
#else
    	QString str =
    		"#include<X11/Xlib.h>\\n"
    		"#include<X11/Xutil.h>\\n"
    		"#include<X11/extensions/scrnsaver.h>\\n"
    		"\\n"
    		"int main()\\n"
    		"{\\n"
    		"    XScreenSaverQueryExtension(NULL, NULL, NULL);\\n"
    		"    return 0;\\n"
    		"}\\n";
    	QString proextra = "CONFIG += x11\\n";

    	if (!conf->doCompileAndLink(str, QStringList(), "-lXss", proextra, NULL)) {
    		if (!conf->doCompileAndLink(str, QStringList(), QString(), proextra, NULL)) {
    			return false;
    		}
    	}
    	else {
    		conf->addLib("-lXss");
    	}

    	conf->addDefine("HAVE_XSS");
    	return true;
#endif
    }
};
#line 1 "aspell.qcm"
/*
-----BEGIN QCMOD-----
name: aspell
arg: with-aspell-inc=[path],Path to Aspell include files
arg: with-aspell-lib=[path],Path to Aspell library files
-----END QCMOD-----
*/

#define QC_ASPELL
bool qc_aspell_have = false;
QStringList qc_aspell_defs;
QStringList qc_aspell_incs;
QStringList qc_aspell_libs;

//----------------------------------------------------------------------------
// qc_aspell
//----------------------------------------------------------------------------
class qc_aspell : public ConfObj
{
public:
    qc_aspell(Conf *c) : ConfObj(c) {}
    QString name() const { return "aspell"; }
    QString shortname() const { return "aspell"; }

    // no output
    QString checkString() const { return QString(); }

    bool exec()
    {
    	// on mac, always use built-in spell check
#ifdef Q_OS_MAC
    	return false;
#else
    	qc_aspell_have = false;
    	qc_aspell_defs.clear();
    	qc_aspell_incs.clear();
    	qc_aspell_libs.clear();

    	QString s;

#ifdef Q_OS_WIN
    	s = conf->getenv("QC_WITH_ASPELL_INC");
    	if(!s.isEmpty()) {
    		if(!conf->checkHeader(s, "aspell.h")) {
    			conf->debug("Aspell includes not found!");
    			return false;
    		}
    		qc_aspell_incs += s;
    	}
    	else
    		return false;

    	QString a_lib = conf->getenv("QC_WITH_ASPELL_LIB");
    	if(a_lib.isEmpty())
    		return false;

    	QStringList libnames;
    	libnames += "aspell-15";
    	libnames += "aspell";

    	bool success;
    	QString libname_success;
    	foreach(const QString &libname, libnames) {
    		conf->debug(QString("Trying %1").arg(libname));
    		if(conf->checkLibrary(a_lib, libname)) {
    			success = true;
    			libname_success = libname;
    			break;
    		}
    	}

    	if(!success)
    		return false;

    	qc_aspell_defs += "HAVE_ASPELL";
    	qc_aspell_libs += QString("-L") + a_lib;
    	qc_aspell_libs += QString("-l") + libname_success;
    	qc_aspell_have = true;
#else
    	s = conf->getenv("QC_WITH_ASPELL_INC");
    	if(!s.isEmpty()) {
    		if(!conf->checkHeader(s, "aspell.h")) {
    			conf->debug("Aspell includes not found!");
    			return false;
    		}
    		qc_aspell_incs += s;
    	}
    	else {
    		QStringList sl;
    		sl += "/usr/include";
    		sl += "/usr/local/include";
    		sl += "/sw/include";
    		if(!conf->findHeader("aspell.h", sl, &s)) {
    			conf->debug("Aspell includes not found!");
    			return false;
    		}
    		qc_aspell_incs += s;
    	}

    	s = conf->getenv("QC_WITH_ASPELL_LIB");
    	if(!s.isEmpty()) {
    		if(!conf->checkLibrary(s, "aspell")) {
    			conf->debug("Aspell libraries not found!");
    			return false;
    		}
    		qc_aspell_libs += QString("-L") + s;
    	}
    	else {
    		if(!conf->findLibrary("aspell", &s)) {
    			conf->debug("Aspell libraries not found!");
    			return false;
    		}
    		if (!s.isEmpty())
    			qc_aspell_libs += QString("-L") + s;
    	}

    	qc_aspell_defs += "HAVE_ASPELL";
    	qc_aspell_libs += "-laspell";
    	qc_aspell_have = true;
#endif

    	return true;
#endif
    }
};
#line 1 "enchant.qcm"
/*
-----BEGIN QCMOD-----
name: enchant
-----END QCMOD-----
*/

#define QC_ENCHANT
bool qc_enchant_have = false;
QStringList qc_enchant_defs;
QStringList qc_enchant_incs;
QStringList qc_enchant_libs;

//----------------------------------------------------------------------------
// qc_enchant
//----------------------------------------------------------------------------
class qc_enchant : public ConfObj
{
public:
    qc_enchant(Conf *c) : ConfObj(c) {}
    QString name() const { return "enchant"; }
    QString shortname() const { return "enchant"; }

    // no output
    QString checkString() const { return QString(); }

    bool exec()
    {
                // on mac, always use built-in spell check
#ifdef Q_OS_MAC
    	return false;
#endif

    	qc_enchant_have = false;
    	qc_enchant_defs.clear();
    	qc_enchant_incs.clear();
    	qc_enchant_libs.clear();

    	QStringList incs;
    	QString version, libs, other;
    	if(!conf->findPkgConfig("enchant", VersionMin, "1.3.0", &version, &incs, &libs, &other))
                        return false;
    	if(conf->findPkgConfig("enchant", VersionMin, "2.0.0", &version, &incs, &libs, &other))
                        qc_enchant_defs += "HAVE_ENCHANT2";

    	qc_enchant_defs += "HAVE_ENCHANT";
    	qc_enchant_incs += incs;
    	qc_enchant_libs += libs;
    	qc_enchant_have = true;

    	return true;
    }
};
#line 1 "hunspell.qcm"
/*
-----BEGIN QCMOD-----
name: hunspell
arg: with-hunspell-inc=[path],Path to Hunspell include files
arg: with-hunspell-lib=[path],Path to Hunspell library files
-----END QCMOD-----
*/

#define QC_HUNSPELL
bool qc_hunspell_have = false;
QStringList qc_hunspell_defs;
QStringList qc_hunspell_incs;
QStringList qc_hunspell_libs;

//----------------------------------------------------------------------------
// qc_hunspell
//----------------------------------------------------------------------------
class qc_hunspell : public ConfObj
{
public:
    qc_hunspell(Conf *c) : ConfObj(c) {}
    QString name() const { return "hunspell"; }
    QString shortname() const { return "hunspell"; }

    // no output
    QString checkString() const { return QString(); }

    bool exec()
    {
    	// on mac, always use built-in spell check
#ifdef Q_OS_MAC
    	return false;
#else
    	qc_hunspell_have = false;
    	qc_hunspell_defs.clear();
    	qc_hunspell_incs.clear();
    	qc_hunspell_libs.clear();

#ifdef Q_OS_WIN
    	QStringList libnames;
# ifdef _MSC_VER
        qc_hunspell_defs += "HUNSPELL_STATIC"; // at least it's static by default when their msvc sln is in use.
#  ifdef QC_BUILDMODE
    	libnames += (qc_buildmode_debug? "libhunspelld" : "libhunspell"); // possibly static
        libnames += (qc_buildmode_debug? "hunspelld" : "hunspell"); // possibly dynamic
#  else
    	libnames << "libhunspell" << "hunspell";
#  endif
# else // mingw?
        libnames << "hunspell-1.3" << "hunspell";
# endif
        QString libs, incs;
        foreach (const QString libname, libnames)
            if(conf->findSimpleLibrary("QC_WITH_HUNSPELL_INC", "QC_WITH_HUNSPELL_LIB", "hunspell/hunspell.hxx", libname, &incs, &libs)) {
                break;
            }

        if(libs.isEmpty()) {
            printf("hunspell library is not found");
            return false;
        }
        conf->addLib(libs);

    	qc_hunspell_defs += "HAVE_HUNSPELL";
        qc_hunspell_libs += libs;
        qc_hunspell_incs += incs + "/hunspell";
    	qc_hunspell_have = true;
#else // Q_OS_WIN. unix below
    	qc_hunspell_have = false;
    	qc_hunspell_defs.clear();
    	qc_hunspell_incs.clear();
    	qc_hunspell_libs.clear();

    	QStringList incs;
    	QString version, libs, other;
    	if(!conf->findPkgConfig("hunspell", VersionMin, "1.3.0", &version, &incs, &libs, &other))
                        return false;

    	qc_hunspell_defs += "HAVE_HUNSPELL";
    	qc_hunspell_incs += incs;
    	qc_hunspell_libs += libs;
    	qc_hunspell_have = true;
#endif // Q_OS_WIN

    	return true;
#endif // Q_OS_MAC
    }
};
#line 1 "spell.qcm"
/*
-----BEGIN QCMOD-----
name: spellcheck engine
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_spell
//----------------------------------------------------------------------------
class qc_spell : public ConfObj
{
public:
    QString engine;

    qc_spell(Conf *c) : ConfObj(c) {}
    QString name() const { return "spellcheck engine"; }
    QString shortname() const { return "spell"; }

    bool exec()
    {
    	// on mac, always use built-in spell check
#ifdef Q_OS_MAC
    	engine = "using Mac built-in";
    	return true;
#endif

    	bool have = false;
    	QStringList defs, incs, libs;

#ifdef QC_ENCHANT
    	if(!have && qc_enchant_have)
    	{
    		defs = qc_enchant_defs;
    		incs = qc_enchant_incs;
    		libs = qc_enchant_libs;
    		engine = "enchant";
    		have = true;
    	}
#endif
#ifdef QC_ASPELL
    	if(!have && qc_aspell_have)
    	{
    		defs = qc_aspell_defs;
    		incs = qc_aspell_incs;
    		libs = qc_aspell_libs;
    		engine = "aspell";
    		have = true;
    	}
#endif
#ifdef QC_HUNSPELL
    	if(!have && qc_hunspell_have)
    	{
    		defs = qc_hunspell_defs;
    		incs = qc_hunspell_incs;
    		libs = qc_hunspell_libs;
    		engine = "hunspell";
    		have = true;
    	}
#endif

    	if(!have)
    		return true;

    	for(int n = 0; n < defs.count(); ++n)
    		conf->addDefine(defs[n]);
    	for(int n = 0; n < incs.count(); ++n)
    		conf->addIncludePath(incs[n]);
    	for(int n = 0; n < libs.count(); ++n)
    		conf->addLib(libs[n]);

    	return true;
    }

    QString resultString() const
    {
    	if(!engine.isEmpty())
    		return engine;
    	else
    		return "no";
    }
};
#line 1 "plugins.qcm"
/*
-----BEGIN QCMOD-----
name: Psi Plugin support
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_plugins
//----------------------------------------------------------------------------
class qc_plugins : public ConfObj
{
public:
    qc_plugins(Conf *c) : ConfObj(c) {}
    QString name() const { return "Psi Plugin support"; }
    QString shortname() const { return "plugins"; }
    bool exec()
    {
    	QFileInfo fi(qc_getenv("QC_COMMAND"));
    	QString sourceDir = fi.absolutePath();

    	conf->addDefine("PSI_PLUGINS");

    	// Finish
    	conf->addExtra("CONFIG += psi_plugins");

    	QHash<QString,QString> vars;
#ifdef Q_OS_WIN
    	vars["plugins_dir"] = "";
    	vars["data_dir"] = "";
#else
    	vars["plugins_dir"] = conf->getenv("LIBDIR") + "/" PSI_DIR_NAME "/plugins";
    	vars["data_dir"] = conf->getenv("DATADIR") + "/" PSI_DIR_NAME;
#endif
    	QStringList psiFeatures;
    	if (!qc_webkit_type.isEmpty()) {
    		psiFeatures << qc_webkit_type;
    	}
    	vars["features"] = psiFeatures.join(" ");
    	psiGenerateFile(sourceDir + "/pluginsconf.pri.in", "pluginsconf.pri", vars);

    	return true;
    }
};
#line 1 "conf.qcm"
/*
-----BEGIN QCMOD-----
name: Psi Configuration
-----END QCMOD-----
*/

#include <QDateTime>

static QString psiGetVersion()
{
    QString str;

    {
    	QFile file(sourceDir + "/version");
    	if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    	{
    		QTextStream ts(&file);
    		if(!ts.atEnd())
    			str = ts.readLine();
    	}

    	if(str.isEmpty())
    		str = "UnknownVersion";
    }

    QString nowstr = QDateTime::currentDateTime().toString("yyyyMMdd");
    str.replace("@@DATE@@", nowstr);
    return str;
}

class qc_conf : public ConfObj
{
public:
    qc_conf(Conf *c) : ConfObj(c) {}
    QString name() const { return "Psi Configuration"; }
    QString shortname() const { return "conf"; }
    QString checkString() const { return QString(); }
    bool exec()
    {
    	QString version = psiGetVersion();
    	QRegExp verre("^\\\\d+(?:\\\\.\\\\d+)+");
    	if (verre.indexIn(version) == -1) {
    		conf->debug("Failed to parse version file");
    		return false;
    	}
    	conf->addExtra(QString("PSI_VERSION = %1").arg(verre.cap(0)));
    	
    	QHash<QString,QString> vars;
    	vars["VERSION"] = version;
    	QDir::current().mkpath("mac");
    	psiGenerateFile(sourceDir + "/mac/Info.plist.in", "mac/Info.plist", vars);
    	
    	vars.clear();
    	vars["source_dir"] = sourceDir;
    	vars["build_dir"] = QDir::currentPath();
    	psiGenerateFile(sourceDir + "/.qmake.cache.in", ".qmake.cache", vars);

#ifndef Q_OS_WIN
    	conf->addExtra(QString("PSI_LIBDIR=%1/" PSI_DIR_NAME).arg(conf->getenv("LIBDIR")));
    	conf->addExtra(QString("PSI_DATADIR=%1/" PSI_DIR_NAME).arg(conf->getenv("DATADIR")));
#endif

    	QDir(".").mkdir("src");
    	QFile file("src/config.h");
    	if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) {
    		QTextStream stream( &file );
#ifndef Q_OS_WIN
    		stream << "#define PSI_LIBDIR \\"" << conf->getenv("LIBDIR") << "/" PSI_DIR_NAME "\\"" << endl;
    		stream << "#define PSI_DATADIR \\"" << conf->getenv("DATADIR") << "/" PSI_DIR_NAME "\\"" << endl;
#endif
    		stream << "#define PSI_VERSION \\"" << version << "\\"" << endl;
    	}

    	conf->addDefine("HAVE_CONFIG");

    	return true;
    }
};
#line 1 "recursiveprl.qcm"
/*
-----BEGIN QCMOD-----
name: Generate .prl files
-----END QCMOD-----
*/

//----------------------------------------------------------------------------
// qc_recursiveprl
//----------------------------------------------------------------------------
class qc_recursiveprl : public ConfObj
{
public:
    bool success;

    qc_recursiveprl(Conf *c) : ConfObj(c) {}
    QString name() const { return "Generate .prl files"; }
    QString shortname() const { return "recursiveprl"; }

    QString checkString() const
    {
    	return "Generating .prl files ...";
    }

    QString resultString() const
    {
    	if(success)
    		return "ok";
    	else
    		return "fail";
    }

    bool exec()
    {
    	success = true;

    	if(!writeConf())
    	{
    		success = false;
    		return false;
    	}

    	QFileInfo fi(qc_getenv("QC_COMMAND"));
    	QStringList args;
    	args += "-prl";
    	args += "-r";
    	args += fi.dir().filePath(qc_getenv("QC_PROFILE"));
    	if(conf->doCommand(conf->qmake_path, args) != 0)
    	{
    		success = false;
    		return false;
    	}

    	return true;
    }

    bool writeConf()
    {
    	// adapted from conf4.cpp.  probably a future version of qconf
    	//   should just have a function to do this so we don't have
    	//   to copy code
    	QFile f("conf.pri");
    	if(!f.open(QFile::WriteOnly | QFile::Truncate))
    	{
    		conf->debug(QString("Error writing %1").arg(f.fileName()));
    		return false;
                }

    	QString str;
    	str += "# qconf\\n\\n";

    	QString var;
    	var = qc_getenv("PREFIX");
    	if(!var.isEmpty())
    		str += QString("PREFIX = %1\\n").arg(var);
    	var = qc_getenv("BINDIR");
    	if(!var.isEmpty())
    		str += QString("BINDIR = %1\\n").arg(var);
    	var = qc_getenv("INCDIR");
    	if(!var.isEmpty())
    		str += QString("INCDIR = %1\\n").arg(var);
    	var = qc_getenv("LIBDIR");
    	if(!var.isEmpty())
    		str += QString("LIBDIR = %1\\n").arg(var);
    	var = qc_getenv("DATADIR");
    	if(!var.isEmpty())
    		str += QString("DATADIR = %1\\n").arg(var);
    	str += '\\n';

    	if(qc_getenv("QC_STATIC") == "Y")
    		str += "CONFIG += staticlib\\n";

    	if(!conf->DEFINES.isEmpty())
    		str += "DEFINES += " + conf->DEFINES + '\\n';
    	if(!conf->INCLUDEPATH.isEmpty())
    		str += "INCLUDEPATH += " + conf->escapedIncludes() + '\\n';
    	if(!conf->LIBS.isEmpty())
    		str += "LIBS += " + conf->escapedLibs() + '\\n';
    	if(!conf->extra.isEmpty())
    		str += conf->extra;
    	str += '\\n';

                QByteArray cs = str.toLatin1();
                f.write(cs);
                f.close();

    	return true;
    }
};

EOT
cat >"$1/modules_new.cpp" <<EOT
    o = new qc_qt5(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_buildmodeapp(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_idn(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_qca(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_zlib(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_qjdns(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_x11(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_universal(conf);
    o->required = false;
    o->disabled = true;
    o = new qc_qdbus(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_keychain(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_qtmultimedia(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_qtconcurrent(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_qtsql(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_qtwidgets(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_qtnetwork(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_qtxml(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_webkit(conf);
    o->required = false;
    o->disabled = true;
    o = new qc_http_parser(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_growl(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_whiteboarding(conf);
    o->required = false;
    o->disabled = true;
    o = new qc_xss(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_aspell(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_enchant(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_hunspell(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_spell(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_plugins(conf);
    o->required = false;
    o->disabled = false;
    o = new qc_conf(conf);
    o->required = true;
    o->disabled = false;
    o = new qc_recursiveprl(conf);
    o->required = true;
    o->disabled = false;

EOT
cat >"$1/conf4.h" <<EOT
/*
Copyright (C) 2004-2008  Justin Karneges

This file is free software; unlimited permission is given to copy and/or
distribute it, with or without modifications, as long as this notice is
preserved.
*/

#ifndef QC_CONF4_H
#define QC_CONF4_H

#include <QtCore>

class Conf;

enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny };

// ConfObj
//
// Subclass ConfObj to create a new configuration module.
class ConfObj
{
public:
	Conf *conf;
	bool required;
	bool disabled;
	bool success;

	ConfObj(Conf *c);
	virtual ~ConfObj();

	// long or descriptive name of what is being checked/performed
	// example: "KDE >= 3.3"
	virtual QString name() const = 0;

	// short name
	// example: "kde"
	virtual QString shortname() const = 0;

	// string to display during check
	// default: "Checking for [name] ..."
	virtual QString checkString() const;

	// string to display after check
	// default: "yes" or "no", based on result of exec()
	virtual QString resultString() const;

	// this is where the checking code goes
	virtual bool exec() = 0;
};

// Conf
//
// Interact with this class from your ConfObj to perform detection
// operations and to output configuration parameters.
class Conf
{
public:
	bool debug_enabled;
	QString qmake_path;
	QString qmakespec;
	QString maketool;

	QString DEFINES;
	QStringList INCLUDEPATH;
	QStringList LIBS;
	QString extra;

	QList<ConfObj*> list;
	QMap<QString,QString> vars;

	Conf();
	~Conf();

	QString getenv(const QString &var);
	QString qvar(const QString &s);
	QString normalizePath(const QString &s) const;
	QString escapeQmakeVar(const QString &s) const;
	inline QString escapePath(const QString &s) /* prepare fs path for qmake file */
	{ return escapeQmakeVar(normalizePath(s)); }
	QString escapedIncludes() const;
	QString escapedLibs() const;

	bool exec();

	void debug(const QString &s);

	QString expandIncludes(const QString &inc);
	QString expandLibs(const QString &lib);

	int doCommand(const QString &s, QByteArray *out = 0);
	int doCommand(const QString &prog, const QStringList &args, QByteArray *out = 0);

	bool doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode = 0);
	bool checkHeader(const QString &path, const QString &h);
	bool findHeader(const QString &h, const QStringList &ext, QString *inc);
	bool checkLibrary(const QString &path, const QString &name);
	bool findLibrary(const QString &name, QString *lib);
	QString findProgram(const QString &prog);
	bool findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs);
	bool findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags);
	bool findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags);

	void addDefine(const QString &str);
	void addLib(const QString &str);
	void addIncludePath(const QString &str);
	void addExtra(const QString &str);

private:
	bool first_debug;

	friend class ConfObj;
	void added(ConfObj *o);
};

#endif

EOT
cat >"$1/conf4.cpp" <<EOT
/*
Copyright (C) 2004-2008  Justin Karneges

This file is free software; unlimited permission is given to copy and/or
distribute it, with or without modifications, as long as this notice is
preserved.
*/

#include "conf4.h"

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#ifndef PATH_MAX
# ifdef Q_OS_WIN
#  define PATH_MAX 260
# endif
#endif

class MocTestObject : public QObject
{
	Q_OBJECT
public:
	MocTestObject() {}
};

QString qc_getenv(const QString &var)
{
	char *p = ::getenv(var.toLatin1().data());
	if(!p)
		return QString();
	return QString(p);
}

QStringList qc_pathlist()
{
	QStringList list;
	QString path = qc_getenv("PATH");
	if(!path.isEmpty())
	{
#ifdef Q_OS_WIN
		list = path.split(';', QString::SkipEmptyParts);
#else
		list = path.split(':', QString::SkipEmptyParts);
#endif
	}
#ifdef Q_OS_WIN
	list.prepend(".");
#endif
	return list;
}

QString qc_findprogram(const QString &prog)
{
	QString out;
	QStringList list = qc_pathlist();
	for(int n = 0; n < list.count(); ++n)
	{
		QFileInfo fi(list[n] + '/' + prog);
		if(fi.exists() && fi.isExecutable())
		{
			out = fi.filePath();
			break;
		}

#ifdef Q_OS_WIN
		// on windows, be sure to look for .exe
		if(prog.right(4).toLower() != ".exe")
		{
			fi = QFileInfo(list[n] + '/' + prog + ".exe");
			if(fi.exists() && fi.isExecutable())
			{
				out = fi.filePath();
				break;
			}
		}
#endif
	}
	return out;
}

QString qc_findself(const QString &argv0)
{
#ifdef Q_OS_WIN
	if(argv0.contains('\\\\'))
#else
	if(argv0.contains('/'))
#endif
		return argv0;
	else
		return qc_findprogram(argv0);
}

int qc_run_program_or_command(const QString &prog, const QStringList &args, const QString &command, QByteArray *out, bool showOutput)
{
	if(out)
		out->clear();

	QProcess process;
	process.setReadChannel(QProcess::StandardOutput);

	if(!prog.isEmpty())
		process.start(prog, args);
	else if(!command.isEmpty())
		process.start(command);
	else
		return -1;

	if(!process.waitForStarted(-1))
		return -1;

	QByteArray buf;

	while(process.waitForReadyRead(-1))
	{
		buf = process.readAllStandardOutput();
		if(out)
			out->append(buf);
		if(showOutput)
			fprintf(stdout, "%s", buf.data());

		buf = process.readAllStandardError();
		if(showOutput)
			fprintf(stderr, "%s", buf.data());
	}

	buf = process.readAllStandardError();
	if(showOutput)
		fprintf(stderr, "%s", buf.data());

	// calling waitForReadyRead will cause the process to eventually be
	//   marked as finished, so we should not need to separately call
	//   waitForFinished. however, we will do it anyway just to be safe.
	//   we won't check the return value since false could still mean
	//   success (if the process had already been marked as finished).
	process.waitForFinished(-1);

	if(process.exitStatus() != QProcess::NormalExit)
		return -1;

	return process.exitCode();
}

int qc_runcommand(const QString &command, QByteArray *out, bool showOutput)
{
	return qc_run_program_or_command(QString(), QStringList(), command, out, showOutput);
}

int qc_runprogram(const QString &prog, const QStringList &args, QByteArray *out, bool showOutput)
{
	return qc_run_program_or_command(prog, args, QString(), out, showOutput);
}

bool qc_removedir(const QString &dirPath)
{
	QDir dir(dirPath);
	if(!dir.exists())
		return false;
	QStringList list = dir.entryList();
	foreach(QString s, list)
	{
		if(s == "." || s == "..")
			continue;
		QFileInfo fi(dir.filePath(s));
		if(fi.isDir())
		{
			if(!qc_removedir(fi.filePath()))
				return false;
		}
		else
		{
			if(!dir.remove(s))
				return false;
		}
	}
	QString dirName = dir.dirName();
	if(!dir.cdUp())
		return false;
	if(!dir.rmdir(dirName))
		return false;
	return true;
}

// simple command line arguemnts splitter able to understand quoted args.
// the splitter removes quotes and unescapes symbols as well.
QStringList qc_splitflags(const QString &flags)
{
	QStringList ret;
	bool searchStart = true;
	bool inQuotes = false;
	bool escaped = false;
	QChar quote, backslash = QLatin1Char('\\\\');
	QString buf;
#ifdef PATH_MAX
	buf.reserve(PATH_MAX);
#endif
	for (int i=0; i < flags.length(); i++) {
		if (searchStart && flags[i].isSpace()) {
			continue;
		}
		if (searchStart) {
			searchStart = false;
			buf.clear();
		}
		if (escaped) {
			buf += flags[i];
			escaped = false;
			continue;
		}
		//buf += flags[i];
		if (inQuotes) {
			if (quote == QLatin1Char('\\'')) {
				if (flags[i] == quote) {
					inQuotes = false;
					continue;
				}
			} else { // we are in double quoetes
				if (flags[i] == backslash && i < flags.length() - 1 &&
						(flags[i+1] == QLatin1Char('"') || flags[i+1] == backslash))
				{
					// if next symbol is one of in parentheses ("\\)
					escaped = true;
					continue;
				}
			}
		} else {
			if (flags[i].isSpace()) {
				ret.append(buf);
				searchStart = true;
				buf.clear();
				continue;
#ifndef Q_OS_WIN /* on windows backslash is just a path separator */
			} else if (flags[i] == backslash) {
				escaped = true;
				continue; // just add next symbol
#endif
			} else if (flags[i] == QLatin1Char('\\'') || flags[i] == QLatin1Char('"')) {
				inQuotes = true;
				quote = flags[i];
				continue;
			}
		}
		buf += flags[i];
	}
	if (buf.size()) {
		ret.append(buf);
	}
	return ret;
}

void qc_splitcflags(const QString &cflags, QStringList *incs, QStringList *otherflags)
{
	incs->clear();
	otherflags->clear();

	QStringList cflagsList = qc_splitflags(cflags);
	for(int n = 0; n < cflagsList.count(); ++n)
	{
		QString str = cflagsList[n];
		if(str.startsWith("-I"))
		{
			// we want everything except the leading "-I"
			incs->append(str.remove(0, 2));
		}
		else
		{
			// we want whatever is left
			otherflags->append(str);
		}
	}
}

QString qc_escapeArg(const QString &str)
{
	QString out;
	for(int n = 0; n < (int)str.length(); ++n) {
		if(str[n] == '-')
			out += '_';
		else
			out += str[n];
	}
	return out;
}


QString qc_trim_char(const QString &s, const QChar &ch)
{
	if (s.startsWith(ch) && s.endsWith(ch)) {
		return s.mid(1, s.size() - 2);
	}
	return s;
}

// removes surrounding quotes, removes trailing slashes, converts to native separators.
// accepts unescaped but possible quoted path
QString qc_normalize_path(const QString &str)
{
	QString path = str.trimmed();
	path = qc_trim_char(path, QLatin1Char('"'));
	path = qc_trim_char(path, QLatin1Char('\\''));

	// It's OK to use unix style'/' pathes on windows Qt handles this without any problems.
	// Using Windows-style '\\\\' can leads strange compilation error with MSYS which uses
	// unix style.
	QLatin1Char nativeSep('/');
#ifdef Q_OS_WIN
	path.replace(QLatin1Char('\\\\'), QLatin1Char('/'));
#endif
	// trim trailing slashes
	while (path.length() && path[path.length() - 1] == nativeSep) {
		path.resize(path.length() - 1);
	}
	return path;
}

// escape filesystem path to be added to qmake pro/pri file.
QString qc_escape_string_var(const QString &str)
{
	QString path = str;
	path.replace(QLatin1Char('\\\\'), QLatin1String("\\\\\\\\"))
			.replace(QLatin1Char('"'), QLatin1String("\\\\\\""));
	if (path.indexOf(QLatin1Char(' ')) != -1) { // has spaces
		return QLatin1Char('"') + path + QLatin1Char('"');
	}
	return path;
}

// escapes each path in incs and join into single string suiable for INCLUDEPATH var
QString qc_prepare_includepath(const QStringList &incs)
{
	if (incs.empty()) {
		return QString();
	}
	QStringList ret;
	foreach (const QString &path, incs) {
		ret.append(qc_escape_string_var(path));
	}
	return ret.join(QLatin1String(" "));
}

// escapes each path in libs and to make it suiable for LIBS var
// notice, entries of libs are every single arg for linker.
QString qc_prepare_libs(const QStringList &libs)
{
	if (libs.isEmpty()) {
		return QString();
	}
	QSet<QString> pathSet;
	QStringList paths;
	QStringList ordered;
	foreach (const QString &arg, libs) {
		if (arg.startsWith(QLatin1String("-L"))) {
			QString path = qc_escape_string_var(arg.mid(2));
			if (!pathSet.contains(path)) {
				pathSet.insert(path);
				paths.append(path);
			}
		} else if (arg.startsWith(QLatin1String("-l"))) {
			ordered.append(arg);
		} else {
			ordered.append(qc_escape_string_var(arg));
		}
	}
	QString ret;
	if (paths.size()) {
		ret += (QLatin1String(" -L") + paths.join(QLatin1String(" -L")) + QLatin1Char(' '));
	}
	return ret + ordered.join(QLatin1String(" "));
}

//----------------------------------------------------------------------------
// ConfObj
//----------------------------------------------------------------------------
ConfObj::ConfObj(Conf *c)
{
	conf = c;
	conf->added(this);
	required = false;
	disabled = false;
	success = false;
}

ConfObj::~ConfObj()
{
}

QString ConfObj::checkString() const
{
	return QString("Checking for %1 ...").arg(name());
}

QString ConfObj::resultString() const
{
	if(success)
		return "yes";
	else
		return "no";
}

//----------------------------------------------------------------------------
// qc_internal_pkgconfig
//----------------------------------------------------------------------------
class qc_internal_pkgconfig : public ConfObj
{
public:
	QString pkgname, desc;
	VersionMode mode;
	QString req_ver;

        qc_internal_pkgconfig(Conf *c, const QString &_name, const QString &_desc, VersionMode _mode, const QString &_req_ver) : ConfObj(c)
	{
		pkgname = _name;
		desc = _desc;
		mode = _mode;
		req_ver = _req_ver;
	}

	QString name() const { return desc; }
	QString shortname() const { return pkgname; }

	bool exec()
	{
		QStringList incs;
		QString version, libs, other;
		if(!conf->findPkgConfig(pkgname, mode, req_ver, &version, &incs, &libs, &other))
			return false;

		for(int n = 0; n < incs.count(); ++n)
			conf->addIncludePath(incs[n]);
		if(!libs.isEmpty())
			conf->addLib(libs);
		//if(!other.isEmpty())
		//	conf->addExtra(QString("QMAKE_CFLAGS += %1\\n").arg(other));

		if(!required)
			conf->addDefine("HAVE_PKG_" + qc_escapeArg(pkgname).toUpper());

		return true;
	}
};

//----------------------------------------------------------------------------
// Conf
//----------------------------------------------------------------------------
Conf::Conf()
{
	// TODO: no more vars?
	//vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC));
	//vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR));
	//vars.insert("QMAKE_LIBS_X11",   new QString(X11_LIB));
	//vars.insert("QMAKE_CC", CC);

	debug_enabled = false;
}

Conf::~Conf()
{
	qDeleteAll(list);
}

void Conf::added(ConfObj *o)
{
	list.append(o);
}

QString Conf::getenv(const QString &var)
{
	return qc_getenv(var);
}

void Conf::debug(const QString &s)
{
	if(debug_enabled)
	{
		if(first_debug)
			printf("\\n");
		first_debug = false;
		printf(" * %s\\n", qPrintable(s));
	}
}

bool Conf::exec()
{
	for(int n = 0; n < list.count(); ++n)
	{
		ConfObj *o = list[n];

		// if this was a disabled-by-default option, check if it was enabled
		if(o->disabled)
		{
			QString v = QString("QC_ENABLE_") + qc_escapeArg(o->shortname());
			if(getenv(v) != "Y")
				continue;
		}
		// and the opposite?
		else
		{
			QString v = QString("QC_DISABLE_") + qc_escapeArg(o->shortname());
			if(getenv(v) == "Y")
				continue;
		}

		bool output = true;
		QString check = o->checkString();
		if(check.isEmpty())
			output = false;

		if(output)
		{
			printf("%s", check.toLatin1().data());
			fflush(stdout);
		}

		first_debug = true;
		bool ok = o->exec();
		o->success = ok;

		if(output)
		{
			QString result = o->resultString();
			if(!first_debug)
				printf(" -> %s\\n", result.toLatin1().data());
			else
				printf(" %s\\n", result.toLatin1().data());
		}

		if(!ok && o->required)
		{
			printf("\\nError: need %s!\\n", o->name().toLatin1().data());
			return false;
		}
	}
	return true;
}

QString Conf::qvar(const QString &s)
{
	return vars.value(s);
}

QString Conf::normalizePath(const QString &s) const
{
	return qc_normalize_path(s);
}

QString Conf::escapeQmakeVar(const QString &s) const
{
	return qc_escape_string_var(s);
}

QString Conf::escapedIncludes() const
{
	return qc_prepare_includepath(INCLUDEPATH);
}

QString Conf::escapedLibs() const
{
	return qc_prepare_libs(LIBS);
}

QString Conf::expandIncludes(const QString &inc)
{
	return QLatin1String("-I") + inc;
}

QString Conf::expandLibs(const QString &lib)
{
	return QLatin1String("-L") + lib;
}

int Conf::doCommand(const QString &s, QByteArray *out)
{
	debug(QString("[%1]").arg(s));
	int r = qc_runcommand(s, out, debug_enabled);
	debug(QString("returned: %1").arg(r));
	return r;
}

int Conf::doCommand(const QString &prog, const QStringList &args, QByteArray *out)
{
	QString fullcmd = prog;
	QString argstr = args.join(QLatin1String(" "));
	if(!argstr.isEmpty())
		fullcmd += QString(" ") + argstr;
	debug(QString("[%1]").arg(fullcmd));
	int r = qc_runprogram(prog, args, out, debug_enabled);
	debug(QString("returned: %1").arg(r));
	return r;
}

bool Conf::doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode)
{
#ifdef Q_OS_WIN
	QDir tmp("qconftemp");
#else
	QDir tmp(".qconftemp");
#endif
	QStringList normalizedLibs;
	foreach (const QString &l, qc_splitflags(libs)) {
		normalizedLibs.append(qc_normalize_path(l));
	}

	if(!tmp.mkdir("atest"))
	{
		debug(QString("unable to create atest dir: %1").arg(tmp.absoluteFilePath("atest")));
		return false;
	}
	QDir dir(tmp.filePath("atest"));
	if(!dir.exists())
	{
		debug("atest dir does not exist");
		return false;
	}

	QString fname = dir.filePath("atest.cpp");
	QString out = "atest";
	QFile f(fname);
	if(!f.open(QFile::WriteOnly | QFile::Truncate))
	{
		debug("unable to open atest.cpp for writing");
		return false;
	}
	if(f.write(filedata.toLatin1()) == -1)
	{
		debug("error writing to atest.cpp");
		return false;
	}
	f.close();

	debug(QString("Wrote atest.cpp:\\n%1").arg(filedata));

	QString pro = QString(
		"CONFIG  += console\\n"
		"CONFIG  -= qt app_bundle\\n"
		"DESTDIR  = \$\$PWD\\n"
		"SOURCES += atest.cpp\\n");
	QString inc = qc_prepare_includepath(incs);
	if(!inc.isEmpty())
		pro += "INCLUDEPATH += " + inc + '\\n';
	QString escaped_libs = qc_prepare_libs(normalizedLibs);
	if(!escaped_libs.isEmpty())
		pro += "LIBS += " + escaped_libs + '\\n';
	pro += proextra;

	fname = dir.filePath("atest.pro");
	f.setFileName(fname);
	if(!f.open(QFile::WriteOnly | QFile::Truncate))
	{
		debug("unable to open atest.pro for writing");
		return false;
	}
	if(f.write(pro.toLatin1()) == -1)
	{
		debug("error writing to atest.pro");
		return false;
	}
	f.close();

	debug(QString("Wrote atest.pro:\\n%1").arg(pro));

	QString oldpath = QDir::currentPath();
	QDir::setCurrent(dir.path());

	bool ok = false;
	int r = doCommand(qmake_path, QStringList() << "atest.pro");
	if(r == 0)
	{
		r = doCommand(maketool, QStringList());
		if(r == 0)
		{
			ok = true;
			if(retcode)
			{
				QString runatest = out;
#ifdef Q_OS_UNIX
				runatest.prepend("./");
#endif
				*retcode = doCommand(runatest, QStringList());
			}
		}
		r = doCommand(maketool, QStringList() << "distclean");
		if(r != 0)
			debug("error during atest distclean");
	}

	QDir::setCurrent(oldpath);

	// cleanup
	//dir.remove("atest.pro");
	//dir.remove("atest.cpp");
	//tmp.rmdir("atest");

	// remove whole dir since distclean doesn't always work
	qc_removedir(tmp.filePath("atest"));

	if(!ok)
		return false;
	return true;
}

bool Conf::checkHeader(const QString &path, const QString &h)
{
	return QDir(path).exists(h);
}

bool Conf::findHeader(const QString &h, const QStringList &ext, QString *inc)
{
	if(checkHeader("/usr/include", h))
	{
		*inc = "";
		return true;
	}
	QStringList dirs;
	dirs += "/usr/local/include";
	dirs += ext;
	for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
	{
		if(checkHeader(*it, h))
		{
			*inc = *it;
			return true;
		}
	}
	return false;
}

bool Conf::checkLibrary(const QString &path, const QString &name)
{
	QString str =
		//"#include <stdio.h>\\n"
		"int main()\\n"
		"{\\n"
		//"    printf(\\"library checker running\\\\\\\\n\\");\\n"
		"    return 0;\\n"
		"}\\n";

	QString libs;
	if(!path.isEmpty())
		libs += QString("-L") + path + ' ';
	libs += QString("-l") + name;
	if(!doCompileAndLink(str, QStringList(), libs, QString()))
		return false;
	return true;
}

bool Conf::findLibrary(const QString &name, QString *lib)
{
	if(checkLibrary("", name))
	{
		*lib = "";
		return true;
	}
	if(checkLibrary("/usr/local/lib", name))
	{
		*lib = "/usr/local/lib";
		return true;
	}
	return false;
}

QString Conf::findProgram(const QString &prog)
{
	return qc_findprogram(prog);
}

bool Conf::findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs)
{
	QString inc, lib;
	QString s;

	s = getenv(incvar);
	if(!s.isEmpty()) {
		if(!checkHeader(s, incname))
			return false;
		inc = s;
	}
	else {
		if(!findHeader(incname, QStringList(), &s))
			return false;
		inc = s;
	}

	s = getenv(libvar);
	if(!s.isEmpty()) {
		if(!checkLibrary(s, libname))
			return false;
		lib = s;
	}
	else {
		if(!findLibrary(libname, &s))
			return false;
		lib = s;
	}

	QString lib_out;
	if(!lib.isEmpty())
		lib_out += QString("-L") + s;
	lib_out += QString("-l") + libname;

	*incpath = inc;
	*libs = lib_out;
	return true;
}

bool Conf::findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags)
{
	QStringList args;
	QByteArray out;
	int ret;

	args += "--version";
	ret = doCommand(path, args, &out);
	if(ret != 0)
		return false;

	QString version_out = QString::fromLatin1(out).trimmed();

	args.clear();
	args += "--libs";
	ret = doCommand(path, args, &out);
	if(ret != 0)
		return false;

	QString libs_out = QString::fromLatin1(out).trimmed();

	args.clear();
	args += "--cflags";
	ret = doCommand(path, args, &out);
	if(ret != 0)
		return false;

	QString cflags = QString::fromLatin1(out).trimmed();

	QStringList incs_out, otherflags_out;
	qc_splitcflags(cflags, &incs_out, &otherflags_out);

	*version = version_out;
	*incs = incs_out;
	*libs = libs_out;
	*otherflags = otherflags_out.join(QLatin1String(" "));
	return true;
}

bool Conf::findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags)
{
	QStringList args;
	QByteArray out;
	int ret;

	args += name;
	args += "--exists";
	ret = doCommand("pkg-config", args, &out);
	if(ret != 0)
		return false;

	if(mode != VersionAny)
	{
		args.clear();
		args += name;
		if(mode == VersionMin)
			args += QString("--atleast-version=%1").arg(req_version);
		else if(mode == VersionMax)
			args += QString("--max-version=%1").arg(req_version);
		else
			args += QString("--exact-version=%1").arg(req_version);
		ret = doCommand("pkg-config", args, &out);
		if(ret != 0)
			return false;
	}

	args.clear();
	args += name;
	args += "--modversion";
	ret = doCommand("pkg-config", args, &out);
	if(ret != 0)
		return false;

	QString version_out = QString::fromLatin1(out).trimmed();

	args.clear();
	args += name;
	args += "--libs";
	ret = doCommand("pkg-config", args, &out);
	if(ret != 0)
		return false;

	QString libs_out = QString::fromLatin1(out).trimmed();

	args.clear();
	args += name;
	args += "--cflags";
	ret = doCommand("pkg-config", args, &out);
	if(ret != 0)
		return false;

	QString cflags = QString::fromLatin1(out).trimmed();

	QStringList incs_out, otherflags_out;
	qc_splitcflags(cflags, &incs_out, &otherflags_out);

	*version = version_out;
	*incs = incs_out;
	*libs = libs_out;
	*otherflags = otherflags_out.join(QLatin1String(" "));
	return true;
}

void Conf::addDefine(const QString &str)
{
	if(DEFINES.isEmpty())
		DEFINES = str;
	else
		DEFINES += QString(" ") + str;
	debug(QString("DEFINES += %1").arg(str));
}

void Conf::addLib(const QString &str)
{
	QStringList libs = qc_splitflags(str);
	foreach (const QString &lib, libs) {
		if (lib.startsWith("-l")) {
			LIBS.append(lib);
		} else {
			LIBS.append(qc_normalize_path(lib)); // we don't care about -L prefix since normalier does not touch it.
		}
	}
	debug(QString("LIBS += %1").arg(str));
}

void Conf::addIncludePath(const QString &str)
{
	INCLUDEPATH.append(qc_normalize_path(str));
	debug(QString("INCLUDEPATH += %1").arg(str));
}

void Conf::addExtra(const QString &str)
{
	extra += str + '\\n';
	debug(QString("extra += %1").arg(str));
}

//----------------------------------------------------------------------------
// main
//----------------------------------------------------------------------------
#include "conf4.moc"

#ifdef HAVE_MODULES
# include"modules.cpp"
#endif

int main(int argc, char ** argv)
{
	QCoreApplication app(argc, argv);
	Conf *conf = new Conf;
	ConfObj *o = 0;
	Q_UNUSED(o);
#ifdef HAVE_MODULES
# include"modules_new.cpp"
#endif

	conf->debug_enabled = (qc_getenv("QC_VERBOSE") == "Y") ? true: false;
	if(conf->debug_enabled)
		printf(" -> ok\\n");
	else
		printf("ok\\n");

	QString confCommand = qc_getenv("QC_COMMAND");
	QString proName = qc_getenv("QC_PROFILE");
	conf->qmake_path = qc_getenv("QC_QMAKE");
	conf->qmakespec = qc_getenv("QC_QMAKESPEC");
	conf->maketool = qc_getenv("QC_MAKETOOL");

	if(conf->debug_enabled)
		printf("conf command: [%s]\\n", qPrintable(confCommand));

	QString confPath = qc_findself(confCommand);
	if(confPath.isEmpty())
	{
		printf("Error: cannot find myself; rerun with an absolute path\\n");
		return 1;
	}

	QString srcdir = QFileInfo(confPath).absolutePath();
	QString builddir = QDir::current().absolutePath();
	QString proPath = QDir(srcdir).filePath(proName);

	if(conf->debug_enabled)
	{
		printf("conf path:    [%s]\\n", qPrintable(confPath));
		printf("srcdir:       [%s]\\n", qPrintable(srcdir));
		printf("builddir:     [%s]\\n", qPrintable(builddir));
		printf("profile:      [%s]\\n", qPrintable(proPath));
		printf("qmake path:   [%s]\\n", qPrintable(conf->qmake_path));
		printf("qmakespec:    [%s]\\n", qPrintable(conf->qmakespec));
		printf("make tool:    [%s]\\n", qPrintable(conf->maketool));
		printf("\\n");
	}

	bool success = false;
	if(conf->exec())
	{
		QFile f("conf.pri");
		if(!f.open(QFile::WriteOnly | QFile::Truncate))
		{
			printf("Error writing %s\\n", qPrintable(f.fileName()));
			return 1;
		}

		QString str;
		str += "# qconf\\n\\n";
		str += "greaterThan(QT_MAJOR_VERSION, 4):CONFIG += c++11\\n";

		QString var;
		var = qc_normalize_path(qc_getenv("PREFIX"));
		if(!var.isEmpty())
			str += QString("PREFIX = %1\\n").arg(var);
		var = qc_normalize_path(qc_getenv("BINDIR"));
		if(!var.isEmpty())
			str += QString("BINDIR = %1\\n").arg(var);
		var = qc_normalize_path(qc_getenv("INCDIR"));
		if(!var.isEmpty())
			str += QString("INCDIR = %1\\n").arg(var);
		var = qc_normalize_path(qc_getenv("LIBDIR"));
		if(!var.isEmpty())
			str += QString("LIBDIR = %1\\n").arg(var);
		var = qc_normalize_path(qc_getenv("DATADIR"));
		if(!var.isEmpty())
			str += QString("DATADIR = %1\\n").arg(var);
		str += '\\n';

		if(qc_getenv("QC_STATIC") == "Y")
			str += "CONFIG += staticlib\\n";

		// TODO: don't need this?
		//str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\\n';

		if(!conf->DEFINES.isEmpty())
			str += "DEFINES += " + conf->DEFINES + '\\n';
		if(!conf->INCLUDEPATH.isEmpty())
			str += "INCLUDEPATH += " + qc_prepare_includepath(conf->INCLUDEPATH) + '\\n';
		if(!conf->LIBS.isEmpty())
			str += "LIBS += " + qc_prepare_libs(conf->LIBS) + '\\n';
		if(!conf->extra.isEmpty())
			str += conf->extra;
		str += '\\n';

		var = qc_getenv("QC_EXTRACONF");
		if (!var.isEmpty())
			str += ("\\n# Extra conf from command line\\n" + var + "\\n");

		QByteArray cs = str.toLatin1();
		f.write(cs);
		f.close();
		success = true;
	}
	QString qmake_path = conf->qmake_path;
	QString qmakespec = conf->qmakespec;
	delete conf;

	if(!success)
		return 1;

	// run qmake on the project file
	QStringList args;
	if(!qmakespec.isEmpty())
	{
		args += "-spec";
		args += qmakespec;
	}
	args += proPath;
	int ret = qc_runprogram(qmake_path, args, 0, true);
	if(ret != 0)
		return 1;

	return 0;
}

EOT
cat >"$1/conf4.pro" <<EOT
CONFIG  += console
CONFIG  -= app_bundle
QT      -= gui
TARGET   = conf
DESTDIR  = \$\$PWD

HEADERS += conf4.h
SOURCES += conf4.cpp


DEFINES += HAVE_MODULES

greaterThan(QT_MAJOR_VERSION, 4):CONFIG += c++11

EOT
}

export PREFIX
export BINDIR
export LIBDIR
export DATADIR
export EX_QTDIR
export QC_EXTRACONF
export QC_RELEASE
export QC_DEBUG
export QC_NO_SEPARATE_DEBUG_INFO
export QC_SEPARATE_DEBUG_INFO
export QC_WITH_IDN_INC
export QC_WITH_IDN_LIB
export QC_WITH_QCA_INC
export QC_WITH_QCA_LIB
export QC_WITH_ZLIB_INC
export QC_WITH_ZLIB_LIB
export QC_WITH_QJDNS_INC
export QC_WITH_QJDNS_LIB
export QC_ENABLE_universal
export QC_DISABLE_qdbus
export QC_DISABLE_keychain
export QC_ENABLE_webkit
export QC_WITH_WEBKIT
export QC_WITH_HTTP_PARSER_INC
export QC_WITH_HTTP_PARSER_LIB
export QC_BUNDLED_HTTP_PARSER
export QC_DISABLE_growl
export QC_WITH_GROWL
export QC_ENABLE_whiteboarding
export QC_DISABLE_xss
export QC_DISABLE_aspell
export QC_WITH_ASPELL_INC
export QC_WITH_ASPELL_LIB
export QC_DISABLE_enchant
export QC_DISABLE_hunspell
export QC_WITH_HUNSPELL_INC
export QC_WITH_HUNSPELL_LIB
export QC_DISABLE_plugins
export QC_VERBOSE
export QC_QTSELECT
rm -rf ".qconftemp"
(
	mkdir ".qconftemp"
	gen_files ".qconftemp"
	cd ".qconftemp"
	if [ ! -z "$qm_spec" ]; then
		"$qm" -spec $qm_spec conf4.pro >/dev/null
	else
		"$qm" conf4.pro >/dev/null
	fi
	$MAKE clean >/dev/null 2>&1
	$MAKE >../conf.log 2>&1
)

if [ "$?" != "0" ]; then
	rm -rf ".qconftemp"
	if [ "$QC_VERBOSE" = "Y" ]; then
		echo " -> fail"
	else
		echo "fail"
	fi
	printf "\n"
	printf "Reason: There was an error compiling 'conf'.  See conf.log for details.\n"
	printf "\n"
	show_qt_info
	if [ "$QC_VERBOSE" = "Y" ]; then
		echo "conf.log:"
		cat conf.log
	fi
	exit 1;
fi

QC_COMMAND=$0
export QC_COMMAND
QC_PROFILE=psi.pro
export QC_PROFILE
QC_QMAKE="$qm"
export QC_QMAKE
QC_QMAKESPEC=$qm_spec
export QC_QMAKESPEC
QC_MAKETOOL=$MAKE
export QC_MAKETOOL
".qconftemp/conf"
ret="$?"
if [ "$ret" = "1" ]; then
	rm -rf ".qconftemp"
	echo
	exit 1;
else
	if [ "$ret" != "0" ]; then
		rm -rf ".qconftemp"
		if [ "$QC_VERBOSE" = "Y" ]; then
			echo " -> fail"
		else
			echo "fail"
		fi
		echo
		echo "Reason: Unexpected error launching 'conf'"
		echo
		exit 1;
	fi
fi
rm -rf ".qconftemp"

echo
echo "Good, your configure finished.  Now run $MAKE."
echo
