Fix searchInPath in various ways

Search in path order not in extension order. That is prefer exec.bat to
exec.exe if exec.bat is earlier in the path.

On Windows only append extensions if the executable has none. (That's
how the shell works.)

Change-Id: I4774f47e5d8e71efccbce49f3facc360eb2a193e
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
Daniel Teske
2012-09-11 13:56:08 +02:00
parent c68c96fd23
commit d02d67d58c
2 changed files with 44 additions and 44 deletions

View File

@@ -228,59 +228,60 @@ void Environment::clear()
m_values.clear();
}
QString Environment::searchInDirectory(const QStringList &execs, QString directory) const
{
const QChar slash = QLatin1Char('/');
if (directory.isEmpty())
return QString();
// Avoid turing / into // on windows which triggers windows to check
// for network drives!
if (!directory.endsWith(slash))
directory += slash;
foreach (const QString &exec, execs) {
QFileInfo fi(directory + exec);
if (fi.exists() && fi.isFile() && fi.isExecutable())
return fi.absoluteFilePath();
}
return QString();
}
QString Environment::searchInPath(const QString &executable,
const QStringList &additionalDirs) const
{
QString exec = QDir::cleanPath(expandVariables(executable));
QFileInfo fi(exec);
if (fi.isAbsolute())
return exec;
if (executable.isEmpty())
return QString();
QStringList execs;
execs << executable;
#ifdef Q_OS_WIN
// Check all the executable extensions on windows:
QStringList extensions = value(QLatin1String("PATHEXT")).split(QLatin1Char(';'));
// PATHEXT is only used if the executable has no extension
if (fi.suffix().isEmpty()) {
QStringList extensions = value(QLatin1String("PATHEXT")).split(QLatin1Char(';'));
// .exe.bat is legal (and run when starting new.exe), so always go through the complete list once:
foreach (const QString &ext, extensions)
execs << executable + ext.toLower();
foreach (const QString &ext, extensions)
execs << executable + ext.toLower();
}
#endif
return searchInPath(execs, additionalDirs);
}
QString Environment::searchInPath(const QStringList &executables,
const QStringList &additionalDirs) const
{
const QChar slash = QLatin1Char('/');
foreach (const QString &executable, executables) {
QString exec = QDir::cleanPath(expandVariables(executable));
foreach (QString dir, additionalDirs) {
QString tmp = searchInDirectory(execs, dir);
if (!tmp.isEmpty())
return tmp;
}
if (exec.isEmpty())
continue;
if (executable.indexOf(QLatin1Char('/')) != -1)
return QString();
QFileInfo baseFi(exec);
if (baseFi.isAbsolute() && baseFi.exists())
return exec;
// Check in directories:
foreach (const QString &dir, additionalDirs) {
if (dir.isEmpty())
continue;
QFileInfo fi(dir + QLatin1Char('/') + exec);
if (fi.isFile() && fi.isExecutable())
return fi.absoluteFilePath();
}
// Check in path:
if (exec.indexOf(slash) != -1)
continue;
foreach (const QString &p, path()) {
QString fp = QDir::fromNativeSeparators(p);
// Avoid turing / into // on windows which triggers windows to check
// for network drives!
if (!fp.endsWith(slash))
fp += slash;
fp += exec;
const QFileInfo fi(fp);
if (fi.exists() && fi.isExecutable() && !fi.isDir())
return fi.absoluteFilePath();
}
foreach (const QString &p, path()) {
QString tmp = searchInDirectory(execs, QDir::fromNativeSeparators(p));
if (!tmp.isEmpty())
return tmp;
}
return QString();
}