/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "option.h"
#include "cachekeys.h"
#include <ioutils.h>
#include <qdir.h>
#include <qregexp.h>
#include <qhash.h>
#include <qdebug.h>
#include <qlibraryinfo.h>
#include <stdlib.h>
#include <stdarg.h>

QT_BEGIN_NAMESPACE

using namespace QMakeInternal;

EvalHandler Option::evalHandler;
QMakeGlobals *Option::globals;
ProFileCache *Option::proFileCache;
QMakeVfs *Option::vfs;
QMakeParser *Option::parser;

//convenience
QString Option::prf_ext;
QString Option::prl_ext;
QString Option::libtool_ext;
QString Option::pkgcfg_ext;
QString Option::ui_ext;
QStringList Option::h_ext;
QString Option::cpp_moc_ext;
QStringList Option::cpp_ext;
QStringList Option::c_ext;
QString Option::objc_ext;
QString Option::objcpp_ext;
QString Option::obj_ext;
QString Option::lex_ext;
QString Option::yacc_ext;
QString Option::pro_ext;
QString Option::dir_sep;
QString Option::h_moc_mod;
QString Option::yacc_mod;
QString Option::lex_mod;
QString Option::res_ext;
char Option::field_sep;

//mode
Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING;

//all modes
int Option::warn_level = WarnLogic | WarnDeprecated;
int Option::debug_level = 0;
QFile Option::output;
QString Option::output_dir;
bool Option::recursive = false;

//QMAKE_*_PROPERTY stuff
QStringList Option::prop::properties;

//QMAKE_GENERATE_PROJECT stuff
bool Option::projfile::do_pwd = true;
QStringList Option::projfile::project_dirs;

//QMAKE_GENERATE_MAKEFILE stuff
int Option::mkfile::cachefile_depth = -1;
bool Option::mkfile::do_deps = true;
bool Option::mkfile::do_mocs = true;
bool Option::mkfile::do_dep_heuristics = true;
bool Option::mkfile::do_preprocess = false;
QStringList Option::mkfile::project_files;

static Option::QMAKE_MODE default_mode(QString progname)
{
    int s = progname.lastIndexOf(QDir::separator());
    if(s != -1)
        progname = progname.right(progname.length() - (s + 1));
    if(progname == "qmakegen")
        return Option::QMAKE_GENERATE_PROJECT;
    else if(progname == "qt-config")
        return Option::QMAKE_QUERY_PROPERTY;
    return Option::QMAKE_GENERATE_MAKEFILE;
}

static QString detectProjectFile(const QString &path)
{
    QString ret;
    QDir dir(path);
    if(dir.exists(dir.dirName() + Option::pro_ext)) {
        ret = dir.filePath(dir.dirName()) + Option::pro_ext;
    } else { //last try..
        QStringList profiles = dir.entryList(QStringList("*" + Option::pro_ext));
        if(profiles.count() == 1)
            ret = dir.filePath(profiles.at(0));
    }
    return ret;
}

bool usage(const char *a0)
{
    fprintf(stdout, "Usage: %s [mode] [options] [files]\n"
            "\n"
            "QMake has two modes, one mode for generating project files based on\n"
            "some heuristics, and the other for generating makefiles. Normally you\n"
            "shouldn't need to specify a mode, as makefile generation is the default\n"
            "mode for qmake, but you may use this to test qmake on an existing project\n"
            "\n"
            "Mode:\n"
            "  -project       Put qmake into project file generation mode%s\n"
            "                 In this mode qmake interprets [files] as files to\n"
            "                 be added to the .pro file. By default, all files with\n"
            "                 known source extensions are added.\n"
            "                 Note: The created .pro file probably will \n"
            "                 need to be edited. For example add the QT variable to \n"
            "                 specify what modules are required.\n"
            "  -makefile      Put qmake into makefile generation mode%s\n"
            "                 In this mode qmake interprets files as project files to\n"
            "                 be processed, if skipped qmake will try to find a project\n"
            "                 file in your current working directory\n"
            "\n"
            "Warnings Options:\n"
            "  -Wnone         Turn off all warnings; specific ones may be re-enabled by\n"
            "                 later -W options\n"
            "  -Wall          Turn on all warnings\n"
            "  -Wparser       Turn on parser warnings\n"
            "  -Wlogic        Turn on logic warnings (on by default)\n"
            "  -Wdeprecated   Turn on deprecation warnings (on by default)\n"
            "\n"
            "Options:\n"
            "   * You can place any variable assignment in options and it will be *\n"
            "   * processed as if it was in [files]. These assignments will be    *\n"
            "   * processed before [files] by default.                            *\n"
            "  -o file        Write output to file\n"
            "  -d             Increase debug level\n"
            "  -t templ       Overrides TEMPLATE as templ\n"
            "  -tp prefix     Overrides TEMPLATE so that prefix is prefixed into the value\n"
            "  -help          This help\n"
            "  -v             Version information\n"
            "  -early         All subsequent variable assignments will be\n"
            "                 parsed right before default_pre.prf\n"
            "  -before        All subsequent variable assignments will be\n"
            "                 parsed right before [files] (the default)\n"
            "  -after         All subsequent variable assignments will be\n"
            "                 parsed after [files]\n"
            "  -late          All subsequent variable assignments will be\n"
            "                 parsed right after default_post.prf\n"
            "  -norecursive   Don't do a recursive search\n"
            "  -recursive     Do a recursive search\n"
            "  -set <prop> <value> Set persistent property\n"
            "  -unset <prop>  Unset persistent property\n"
            "  -query <prop>  Query persistent property. Show all if <prop> is empty.\n"
            "  -qtconf file   Use file instead of looking for qt.conf\n"
            "  -cache file    Use file as cache           [makefile mode only]\n"
            "  -spec spec     Use spec as QMAKESPEC       [makefile mode only]\n"
            "  -nocache       Don't use a cache file      [makefile mode only]\n"
            "  -nodepend      Don't generate dependencies [makefile mode only]\n"
            "  -nomoc         Don't generate moc targets  [makefile mode only]\n"
            "  -nopwd         Don't look for files in pwd [project mode only]\n"
            ,a0,
            default_mode(a0) == Option::QMAKE_GENERATE_PROJECT  ? " (default)" : "",
            default_mode(a0) == Option::QMAKE_GENERATE_MAKEFILE ? " (default)" : ""
        );
    return false;
}

int
Option::parseCommandLine(QStringList &args, QMakeCmdLineParserState &state)
{
    enum { ArgNone, ArgOutput } argState = ArgNone;
    int x = 0;
    while (x < args.count()) {
        switch (argState) {
        case ArgOutput:
            Option::output.setFileName(args.at(x--));
            args.erase(args.begin() + x, args.begin() + x + 2);
            argState = ArgNone;
            continue;
        default:
            QMakeGlobals::ArgumentReturn cmdRet = globals->addCommandLineArguments(state, args, &x);
            if (cmdRet == QMakeGlobals::ArgumentsOk)
                break;
            if (cmdRet == QMakeGlobals::ArgumentMalformed) {
                fprintf(stderr, "***Option %s requires a parameter\n", qPrintable(args.at(x - 1)));
                return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
            }
            Q_ASSERT(cmdRet == QMakeGlobals::ArgumentUnknown);
            QString arg = args.at(x);
            if (arg.startsWith(QLatin1Char('-'))) {
                if (arg == "-d") {
                    Option::debug_level++;
                } else if (arg == "-v" || arg == "-version" || arg == "--version") {
                    fprintf(stdout,
                            "QMake version %s\n"
                            "Using Qt version %s in %s\n",
                            QMAKE_VERSION_STR, QT_VERSION_STR,
                            QLibraryInfo::location(QLibraryInfo::LibrariesPath).toLatin1().constData());
#ifdef QMAKE_OPENSOURCE_VERSION
                    fprintf(stdout, "QMake is Open Source software from The Qt Company Ltd and/or its subsidiary(-ies).\n");
#endif
                    return Option::QMAKE_CMDLINE_BAIL;
                } else if (arg == "-h" || arg == "-help" || arg == "--help") {
                    return Option::QMAKE_CMDLINE_SHOW_USAGE;
                } else if (arg == "-Wall") {
                    Option::warn_level |= WarnAll;
                } else if (arg == "-Wparser") {
                    Option::warn_level |= WarnParser;
                } else if (arg == "-Wlogic") {
                    Option::warn_level |= WarnLogic;
                } else if (arg == "-Wdeprecated") {
                    Option::warn_level |= WarnDeprecated;
                } else if (arg == "-Wnone") {
                    Option::warn_level = WarnNone;
                } else if (arg == "-r" || arg == "-recursive") {
                    Option::recursive = true;
                    args.removeAt(x);
                    continue;
                } else if (arg == "-nr" || arg == "-norecursive") {
                    Option::recursive = false;
                    args.removeAt(x);
                    continue;
                } else if (arg == "-o" || arg == "-output") {
                    argState = ArgOutput;
                } else {
                    if (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
                        Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
                        if (arg == "-nodepend" || arg == "-nodepends") {
                            Option::mkfile::do_deps = false;
                        } else if (arg == "-nomoc") {
                            Option::mkfile::do_mocs = false;
                        } else if (arg == "-nodependheuristics") {
                            Option::mkfile::do_dep_heuristics = false;
                        } else if (arg == "-E") {
                            Option::mkfile::do_preprocess = true;
                        } else {
                            fprintf(stderr, "***Unknown option %s\n", arg.toLatin1().constData());
                            return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
                        }
                    } else if (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
                        if (arg == "-nopwd") {
                            Option::projfile::do_pwd = false;
                        } else {
                            fprintf(stderr, "***Unknown option %s\n", arg.toLatin1().constData());
                            return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
                        }
                    }
                }
            } else {
                bool handled = true;
                if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
                    Option::qmake_mode == Option::QMAKE_SET_PROPERTY ||
                    Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY) {
                    Option::prop::properties.append(arg);
                } else {
                    QFileInfo fi(arg);
                    if(!fi.makeAbsolute()) //strange
                        arg = fi.filePath();
                    if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
                       Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
                        if(fi.isDir()) {
                            QString proj = detectProjectFile(arg);
                            if (!proj.isNull())
                                arg = proj;
                        }
                        Option::mkfile::project_files.append(arg);
                    } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
                        Option::projfile::project_dirs.append(arg);
                    } else {
                        handled = false;
                    }
                }
                if(!handled) {
                    return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
                }
                args.removeAt(x);
                continue;
            }
        }
        x++;
    }
    if (argState != ArgNone) {
        fprintf(stderr, "***Option %s requires a parameter\n", qPrintable(args.at(x - 1)));
        return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
    }
    return Option::QMAKE_CMDLINE_SUCCESS;
}

int
Option::init(int argc, char **argv)
{
    Option::prf_ext = ".prf";
    Option::pro_ext = ".pro";
    Option::field_sep = ' ';

    if(argc && argv) {
        QString argv0 = argv[0];
#ifdef Q_OS_WIN
        if (!argv0.endsWith(QLatin1String(".exe"), Qt::CaseInsensitive))
            argv0 += QLatin1String(".exe");
#endif
        if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
            Option::qmake_mode = default_mode(argv0);
        if (!argv0.isEmpty() && IoUtils::isAbsolutePath(argv0)) {
            globals->qmake_abslocation = argv0;
        } else if (argv0.contains(QLatin1Char('/'))
#ifdef Q_OS_WIN
                   || argv0.contains(QLatin1Char('\\'))
#endif
            ) { //relative PWD
            globals->qmake_abslocation = QDir::current().absoluteFilePath(argv0);
        } else { //in the PATH
            QByteArray pEnv = qgetenv("PATH");
            QDir currentDir = QDir::current();
#ifdef Q_OS_WIN
            QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";"));
            paths.prepend(QLatin1String("."));
#else
            QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":"));
#endif
            for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
                if ((*p).isEmpty())
                    continue;
                QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
                if (QFile::exists(candidate)) {
                    globals->qmake_abslocation = candidate;
                    break;
                }
            }
        }
        if (Q_UNLIKELY(globals->qmake_abslocation.isNull())) {
            // This is rather unlikely to ever happen on a modern system ...
            globals->qmake_abslocation = QLibraryInfo::rawLocation(
                                                QLibraryInfo::HostBinariesPath,
                                                QLibraryInfo::EffectivePaths)
#ifdef Q_OS_WIN
                                         + "/qmake.exe";
#else
                                         + "/qmake";
#endif
        } else {
            globals->qmake_abslocation = QDir::cleanPath(globals->qmake_abslocation);
        }
    } else {
        Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
    }

    QMakeCmdLineParserState cmdstate(QDir::currentPath());
    const QByteArray envflags = qgetenv("QMAKEFLAGS");
    if (!envflags.isNull()) {
        QStringList args;
        QByteArray buf = "";
        char quote = 0;
        bool hasWord = false;
        for (int i = 0; i < envflags.size(); ++i) {
            char c = envflags.at(i);
            if (!quote && (c == '\'' || c == '"')) {
                quote = c;
            } else if (c == quote) {
                quote = 0;
            } else if (!quote && c == ' ') {
                if (hasWord) {
                    args << QString::fromLocal8Bit(buf);
                    hasWord = false;
                    buf = "";
                }
            } else {
                buf += c;
                hasWord = true;
            }
        }
        if (hasWord)
            args << QString::fromLocal8Bit(buf);
        parseCommandLine(args, cmdstate);
        cmdstate.flush();
    }
    if(argc && argv) {
        QStringList args;
        args.reserve(argc - 1);
        for (int i = 1; i < argc; i++)
            args << QString::fromLocal8Bit(argv[i]);

        while (!args.isEmpty()) {
            QString opt = args.at(0);
            if (opt == "-project") {
                Option::recursive = true;
                Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT;
            } else if (opt == "-prl") {
                Option::mkfile::do_deps = false;
                Option::mkfile::do_mocs = false;
                Option::qmake_mode = Option::QMAKE_GENERATE_PRL;
            } else if (opt == "-set") {
                Option::qmake_mode = Option::QMAKE_SET_PROPERTY;
            } else if (opt == "-unset") {
                Option::qmake_mode = Option::QMAKE_UNSET_PROPERTY;
            } else if (opt == "-query") {
                Option::qmake_mode = Option::QMAKE_QUERY_PROPERTY;
            } else if (opt == "-makefile") {
                Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
            } else {
                break;
            }
            args.takeFirst();
            break;
        }

        int ret = parseCommandLine(args, cmdstate);
        if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
            if ((ret & Option::QMAKE_CMDLINE_SHOW_USAGE) != 0)
                usage(argv[0]);
            return ret;
            //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
        }
        globals->qmake_args = args;
        globals->qmake_extra_args = cmdstate.extraargs;
    }
    globals->commitCommandLineArguments(cmdstate);
    globals->debugLevel = Option::debug_level;

    //last chance for defaults
    if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
        Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
        globals->useEnvironment();

        //try REALLY hard to do it for them, lazy..
        if(Option::mkfile::project_files.isEmpty()) {
            QString proj = detectProjectFile(qmake_getpwd());
            if(!proj.isNull())
                Option::mkfile::project_files.append(proj);
#ifndef QT_BUILD_QMAKE_LIBRARY
            if(Option::mkfile::project_files.isEmpty()) {
                usage(argv[0]);
                return Option::QMAKE_CMDLINE_ERROR;
            }
#endif
        }
    }

    return QMAKE_CMDLINE_SUCCESS;
}

void Option::prepareProject(const QString &pfile)
{
    // Canonicalize only the directory, otherwise things will go haywire
    // if the file itself is a symbolic link.
    const QString srcpath = QFileInfo(QFileInfo(pfile).absolutePath()).canonicalFilePath();
    globals->setDirectories(srcpath, output_dir);
}

bool Option::postProcessProject(QMakeProject *project)
{
    Option::cpp_ext = project->values("QMAKE_EXT_CPP").toQStringList();
    Option::h_ext = project->values("QMAKE_EXT_H").toQStringList();
    Option::c_ext = project->values("QMAKE_EXT_C").toQStringList();
    Option::objc_ext = project->first("QMAKE_EXT_OBJC").toQString();
    Option::objcpp_ext = project->first("QMAKE_EXT_OBJCXX").toQString();
    Option::res_ext = project->first("QMAKE_EXT_RES").toQString();
    Option::pkgcfg_ext = project->first("QMAKE_EXT_PKGCONFIG").toQString();
    Option::libtool_ext = project->first("QMAKE_EXT_LIBTOOL").toQString();
    Option::prl_ext = project->first("QMAKE_EXT_PRL").toQString();
    Option::ui_ext = project->first("QMAKE_EXT_UI").toQString();
    Option::cpp_moc_ext = project->first("QMAKE_EXT_CPP_MOC").toQString();
    Option::lex_ext = project->first("QMAKE_EXT_LEX").toQString();
    Option::yacc_ext = project->first("QMAKE_EXT_YACC").toQString();
    Option::obj_ext = project->first("QMAKE_EXT_OBJ").toQString();
    Option::h_moc_mod = project->first("QMAKE_H_MOD_MOC").toQString();
    Option::lex_mod = project->first("QMAKE_MOD_LEX").toQString();
    Option::yacc_mod = project->first("QMAKE_MOD_YACC").toQString();

    Option::dir_sep = project->dirSep().toQString();

    if (!project->buildRoot().isEmpty() && Option::output_dir.startsWith(project->buildRoot()))
        Option::mkfile::cachefile_depth =
                Option::output_dir.mid(project->buildRoot().length()).count('/');

    return true;
}

QString
Option::fixString(QString string, uchar flags)
{
    //const QString orig_string = string;
    static QHash<FixStringCacheKey, QString> *cache = nullptr;
    if(!cache) {
        cache = new QHash<FixStringCacheKey, QString>;
        qmakeAddCacheClear(qmakeDeleteCacheClear<QHash<FixStringCacheKey, QString> >, (void**)&cache);
    }
    FixStringCacheKey cacheKey(string, flags);

    QHash<FixStringCacheKey, QString>::const_iterator it = cache->constFind(cacheKey);

    if (it != cache->constEnd()) {
        //qDebug() << "Fix (cached) " << orig_string << "->" << it.value();
        return it.value();
    }

    //fix the environment variables
    if(flags & Option::FixEnvVars) {
        int rep;
        static QRegExp reg_var("\\$\\(.*\\)");
        reg_var.setMinimal(true);
        while((rep = reg_var.indexIn(string)) != -1)
            string.replace(rep, reg_var.matchedLength(),
                           QString::fromLocal8Bit(qgetenv(string.mid(rep + 2, reg_var.matchedLength() - 3).toLatin1().constData()).constData()));
    }

    //canonicalize it (and treat as a path)
    if(flags & Option::FixPathCanonicalize) {
#if 0
        string = QFileInfo(string).canonicalFilePath();
#endif
        string = QDir::cleanPath(string);
    }

    // either none or only one active flag
    Q_ASSERT(((flags & Option::FixPathToLocalSeparators) != 0) +
             ((flags & Option::FixPathToTargetSeparators) != 0) +
             ((flags & Option::FixPathToNormalSeparators) != 0) <= 1);

    //fix separators
    if (flags & Option::FixPathToNormalSeparators) {
        string.replace('\\', '/');
    } else if (flags & Option::FixPathToLocalSeparators) {
#if defined(Q_OS_WIN32)
        string.replace('/', '\\');
#else
        string.replace('\\', '/');
#endif
    } else if(flags & Option::FixPathToTargetSeparators) {
        string.replace('/', Option::dir_sep).replace('\\', Option::dir_sep);
    }

    if ((string.startsWith("\"") && string.endsWith("\"")) ||
        (string.startsWith("\'") && string.endsWith("\'")))
        string = string.mid(1, string.length()-2);

    //cache
    //qDebug() << "Fix" << orig_string << "->" << string;
    cache->insert(cacheKey, string);
    return string;
}

void debug_msg_internal(int level, const char *fmt, ...)
{
    if(Option::debug_level < level)
        return;
    fprintf(stderr, "DEBUG %d: ", level);
    {
        va_list ap;
        va_start(ap, fmt);
        vfprintf(stderr, fmt, ap);
        va_end(ap);
    }
    fprintf(stderr, "\n");
}

void warn_msg(QMakeWarn type, const char *fmt, ...)
{
    if(!(Option::warn_level & type))
        return;
    fprintf(stderr, "WARNING: ");
    {
        va_list ap;
        va_start(ap, fmt);
        vfprintf(stderr, fmt, ap);
        va_end(ap);
    }
    fprintf(stderr, "\n");
}

void EvalHandler::message(int type, const QString &msg, const QString &fileName, int lineNo)
{
    QString pfx;
    if ((type & QMakeHandler::CategoryMask) == QMakeHandler::WarningMessage) {
        int code = (type & QMakeHandler::CodeMask);
        if ((code == QMakeHandler::WarnLanguage && !(Option::warn_level & WarnParser))
            || (code == QMakeHandler::WarnDeprecated && !(Option::warn_level & WarnDeprecated)))
            return;
        pfx = QString::fromLatin1("WARNING: ");
    }
    if (lineNo > 0)
        fprintf(stderr, "%s%s:%d: %s\n", qPrintable(pfx), qPrintable(fileName), lineNo, qPrintable(msg));
    else if (lineNo)
        fprintf(stderr, "%s%s: %s\n", qPrintable(pfx), qPrintable(fileName), qPrintable(msg));
    else
        fprintf(stderr, "%s%s\n", qPrintable(pfx), qPrintable(msg));
}

void EvalHandler::fileMessage(int type, const QString &msg)
{
    Q_UNUSED(type)
    fprintf(stderr, "%s\n", qPrintable(msg));
}

void EvalHandler::aboutToEval(ProFile *, ProFile *, EvalFileType)
{
}

void EvalHandler::doneWithEval(ProFile *)
{
}

class QMakeCacheClearItem {
private:
    qmakeCacheClearFunc func;
    void **data;
public:
    QMakeCacheClearItem(qmakeCacheClearFunc f, void **d) : func(f), data(d) { }
    ~QMakeCacheClearItem() {
        (*func)(*data);
        *data = nullptr;
    }
};
static QList<QMakeCacheClearItem*> cache_items;

void
qmakeClearCaches()
{
    qDeleteAll(cache_items);
    cache_items.clear();
}

void
qmakeAddCacheClear(qmakeCacheClearFunc func, void **data)
{
    cache_items.append(new QMakeCacheClearItem(func, data));
}

QString qmake_libraryInfoFile()
{
    if (!Option::globals->qtconf.isEmpty())
        return Option::globals->qtconf;
    if (!Option::globals->qmake_abslocation.isEmpty())
        return QDir(QFileInfo(Option::globals->qmake_abslocation).absolutePath()).filePath("qt.conf");
    return QString();
}

QString qmake_abslocation()
{
    return Option::globals->qmake_abslocation;
}

QT_END_NAMESPACE
