#!/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-----
*/

/*
Warning: libidn is somewhat deprecated in favor of libidn2, but we can't just
drop it since IDNA2008 doesn't include XMPP profiles and has nothing from
stringprep. This stuff was moved to RFC8264 and RFC8265 and its usage was
described in RFC7622. There are no known C/C++ implementations of these specs
at the moment of this writing. A partial and not sufficient implementation can
be found at https://gitlab.com/gnutls/gnutls/blob/master/lib/str-unicode.c. It
implements OpaqueString Profile but doesn't implement UsernameCaseMapped
profile required by RFC7622. Note it may be also desired to implement RFC8266.

Some implementations in other languages:
Go: https://godoc.org/golang.org/x/text/secure/precis
Python: https://pypi.org/project/precis-i18n/
Perl: https://metacpan.org/release/Unicode-Precis
PHP: https://github.com/tom--/precis

We can try to use https://github.com/lpereira/gomoku to convert from Go.
*/

//----------------------------------------------------------------------------
// 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;

    	bool found = conf->findPkgConfig("qjdns-qt5", VersionMin, "2.0.3", &version, &incs, &libs, &other);
    	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 webkitwidgets";
    		}

    		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
