From f9b94a7ee13e7b8a1c1482391d935a2d5a754848 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 15 Nov 2011 10:34:38 +0200 Subject: qmake: Normalize paths instead of converting to native separators Task-number: QTBUG-22738 Change-Id: I40163a883d84beff79f52bff141d61dfe921c129 Reviewed-by: Oswald Buddenhagen --- qmake/main.cpp | 26 +++++++++++------- qmake/meta.cpp | 26 ++++++++++-------- qmake/option.cpp | 11 ++++++-- qmake/option.h | 12 +++++++- qmake/project.cpp | 82 ++++++++++++++++++++++++++----------------------------- 5 files changed, 89 insertions(+), 68 deletions(-) (limited to 'qmake') diff --git a/qmake/main.cpp b/qmake/main.cpp index 99015177b2..150e12bd3c 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -103,8 +103,8 @@ int runQMake(int argc, char **argv) if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/"))) #endif { - if(oldpwd.right(1) != QString(QChar(QDir::separator()))) - oldpwd += QDir::separator(); + if(!oldpwd.endsWith(QLatin1Char('/'))) + oldpwd += QLatin1Char('/'); } Option::output_dir = oldpwd; //for now this is the output dir @@ -141,28 +141,33 @@ int runQMake(int argc, char **argv) for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) { if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { - QString fn = Option::fixPathToLocalOS((*pfile)); + QString fn = Option::normalizePath(*pfile); if(!QFile::exists(fn)) { - fprintf(stderr, "Cannot find file: %s.\n", fn.toLatin1().constData()); + fprintf(stderr, "Cannot find file: %s.\n", + QDir::toNativeSeparators(fn).toLatin1().constData()); exit_val = 2; continue; } //setup pwd properly - debug_msg(1, "Resetting dir to: %s", oldpwd.toLatin1().constData()); + debug_msg(1, "Resetting dir to: %s", + QDir::toNativeSeparators(oldpwd).toLatin1().constData()); qmake_setpwd(oldpwd); //reset the old pwd - int di = fn.lastIndexOf(QDir::separator()); + int di = fn.lastIndexOf(QLatin1Char('/')); if(di != -1) { - debug_msg(1, "Changing dir to: %s", fn.left(di).toLatin1().constData()); + debug_msg(1, "Changing dir to: %s", + QDir::toNativeSeparators(fn.left(di)).toLatin1().constData()); if(!qmake_setpwd(fn.left(di))) - fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).toLatin1().constData()); + fprintf(stderr, "Cannot find directory: %s\n", + QDir::toNativeSeparators(fn.left(di)).toLatin1().constData()); fn = fn.right(fn.length() - di - 1); } // read project.. if(!project.read(fn)) { fprintf(stderr, "Error processing project file: %s\n", - fn == "-" ? "(stdin)" : (*pfile).toLatin1().constData()); + fn == QLatin1String("-") ? + "(stdin)" : QDir::toNativeSeparators(*pfile).toLatin1().constData()); exit_val = 3; continue; } @@ -179,7 +184,8 @@ int runQMake(int argc, char **argv) if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) fprintf(stderr, "Unable to generate project file.\n"); else - fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).toLatin1().constData()); + fprintf(stderr, "Unable to generate makefile for: %s\n", + QDir::toNativeSeparators(*pfile).toLatin1().constData()); exit_val = 5; } delete mkfile; diff --git a/qmake/meta.cpp b/qmake/meta.cpp index f5edff3ceb..477a826662 100644 --- a/qmake/meta.cpp +++ b/qmake/meta.cpp @@ -75,13 +75,14 @@ QMakeMetaInfo::readLib(QString lib) meta_type = "libtool"; } else if(meta_file.endsWith(Option::prl_ext)) { QMakeProject proj; - if(!proj.read(Option::fixPathToLocalOS(meta_file), QMakeProject::ReadProFile)) + if(!proj.read(Option::normalizePath(meta_file), QMakeProject::ReadProFile)) return false; meta_type = "qmake"; vars = proj.variables(); ret = true; } else { - warn_msg(WarnLogic, "QMakeMetaInfo: unknown file format for %s", meta_file.toLatin1().constData()); + warn_msg(WarnLogic, "QMakeMetaInfo: unknown file format for %s", + QDir::toNativeSeparators(meta_file).toLatin1().constData()); } } if(ret) @@ -102,8 +103,8 @@ QMakeMetaInfo::findLib(QString lib) { if((lib[0] == '\'' || lib[0] == '"') && lib[lib.length()-1] == lib[0]) - lib = lib.mid(1, lib.length()-2); - lib = Option::fixPathToLocalOS(lib); + lib = lib.mid(1, lib.length()-2); + lib = Option::normalizePath(lib); QString ret; QString extns[] = { Option::prl_ext, /*Option::pkgcfg_ext, Option::libtool_ext,*/ QString() }; @@ -133,13 +134,14 @@ QMakeMetaInfo::readLibtoolFile(const QString &f) { /* I can just run the .la through the .pro parser since they are compatible.. */ QMakeProject proj; - if(!proj.read(Option::fixPathToLocalOS(f), QMakeProject::ReadProFile)) + QString nf = Option::normalizePath(f); + if(!proj.read(nf, QMakeProject::ReadProFile)) return false; - QString dirf = Option::fixPathToTargetOS(f).section(Option::dir_sep, 0, -2); - if(dirf == f) + QString dirf = nf.section(QLatin1Char('/'), 0, -2); + if(dirf == nf) dirf = ""; else if(!dirf.isEmpty() && !dirf.endsWith(Option::output_dir)) - dirf += Option::dir_sep; + dirf += QLatin1Char('/'); QHash &v = proj.variables(); for(QHash::Iterator it = v.begin(); it != v.end(); ++it) { QStringList lst = it.value(); @@ -152,18 +154,18 @@ QMakeMetaInfo::readLibtoolFile(const QString &f) if((dir.startsWith("'") || dir.startsWith("\"")) && dir.endsWith(QString(dir[0]))) dir = dir.mid(1, dir.length() - 2); dir = dir.trimmed(); - if(!dir.isEmpty() && !dir.endsWith(Option::dir_sep)) - dir += Option::dir_sep; + if(!dir.isEmpty() && !dir.endsWith(QLatin1Char('/'))) + dir += QLatin1Char('/'); if(lst.count() == 1) lst = lst.first().split(" "); for(QStringList::Iterator lst_it = lst.begin(); lst_it != lst.end(); ++lst_it) { bool found = false; - QString dirs[] = { "", dir, dirf, dirf + ".libs" + QDir::separator(), "(term)" }; + QString dirs[] = { "", dir, dirf, dirf + ".libs/", "(term)" }; for(int i = 0; !found && dirs[i] != "(term)"; i++) { if(QFile::exists(dirs[i] + (*lst_it))) { QString targ = dirs[i] + (*lst_it); if(QDir::isRelativePath(targ)) - targ.prepend(qmake_getpwd() + QDir::separator()); + targ.prepend(qmake_getpwd() + QLatin1Char('/')); vars["QMAKE_PRL_TARGET"] << targ; found = true; } diff --git a/qmake/option.cpp b/qmake/option.cpp index 8ad8a22f79..d450c19f6d 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -659,9 +659,16 @@ Option::fixString(QString string, uchar flags) if(string.length() > 2 && string[0].isLetter() && string[1] == QLatin1Char(':')) string[0] = string[0].toLower(); + bool localSep = (flags & Option::FixPathToLocalSeparators) != 0; + bool targetSep = (flags & Option::FixPathToTargetSeparators) != 0; + bool normalSep = (flags & Option::FixPathToNormalSeparators) != 0; + + // either none or only one active flag + Q_ASSERT(localSep + targetSep + normalSep <= 1); //fix separators - Q_ASSERT(!((flags & Option::FixPathToLocalSeparators) && (flags & Option::FixPathToTargetSeparators))); - if(flags & Option::FixPathToLocalSeparators) { + if (flags & Option::FixPathToNormalSeparators) { + string = string.replace('\\', '/'); + } else if (flags & Option::FixPathToLocalSeparators) { #if defined(Q_OS_WIN32) string = string.replace('/', '\\'); #else diff --git a/qmake/option.h b/qmake/option.h index ffccb8efc5..3899ea84d0 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -115,7 +115,8 @@ struct Option FixEnvVars = 0x01, FixPathCanonicalize = 0x02, FixPathToLocalSeparators = 0x04, - FixPathToTargetSeparators = 0x08 + FixPathToTargetSeparators = 0x08, + FixPathToNormalSeparators = 0x10 }; static QString fixString(QString string, uchar flags); @@ -138,6 +139,15 @@ struct Option flags |= FixPathCanonicalize; return fixString(in, flags); } + inline static QString normalizePath(const QString &in, bool fix_env=true, bool canonical=true) + { + uchar flags = FixPathToNormalSeparators; + if (fix_env) + flags |= FixEnvVars; + if (canonical) + flags |= FixPathCanonicalize; + return fixString(in, flags); + } inline static bool hasFileExtension(const QString &str, const QStringList &extensions) { diff --git a/qmake/project.cpp b/qmake/project.cpp index eb2b10b92f..0489b5d7af 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -532,24 +532,24 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) { QStringList concat; { - const QString base_concat = QDir::separator() + QString("features"); + const QString base_concat = QLatin1String("/features"); switch(Option::target_mode) { case Option::TARG_MACX_MODE: //also a unix - concat << base_concat + QDir::separator() + "mac"; - concat << base_concat + QDir::separator() + "macx"; - concat << base_concat + QDir::separator() + "unix"; + concat << base_concat + QLatin1String("/mac"); + concat << base_concat + QLatin1String("/macx"); + concat << base_concat + QLatin1String("/unix"); break; default: // Can't happen, just make the compiler shut up case Option::TARG_UNIX_MODE: - concat << base_concat + QDir::separator() + "unix"; + concat << base_concat + QLatin1String("/unix"); break; case Option::TARG_WIN_MODE: - concat << base_concat + QDir::separator() + "win32"; + concat << base_concat + QLatin1String("/win32"); break; } concat << base_concat; } - const QString mkspecs_concat = QDir::separator() + QString("mkspecs"); + const QString mkspecs_concat = QLatin1String("/mkspecs"); QStringList feature_roots; QByteArray mkspec_path = qgetenv("QMAKEFEATURES"); if(!mkspec_path.isNull()) @@ -558,9 +558,9 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) feature_roots += splitPathList(prop->value("QMAKEFEATURES")); if(!Option::mkfile::cachefile.isEmpty()) { QString path; - int last_slash = Option::mkfile::cachefile.lastIndexOf(QDir::separator()); + int last_slash = Option::mkfile::cachefile.lastIndexOf(QLatin1Char('/')); if(last_slash != -1) - path = Option::fixPathToLocalOS(Option::mkfile::cachefile.left(last_slash), false); + path = Option::normalizePath(Option::mkfile::cachefile.left(last_slash), false); for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) feature_roots << (path + (*concat_it)); @@ -575,14 +575,14 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) } } if(!Option::mkfile::qmakespec.isEmpty()) - feature_roots << Option::mkfile::qmakespec + QDir::separator() + "features"; + feature_roots << Option::mkfile::qmakespec + QLatin1String("/features"); if(!Option::mkfile::qmakespec.isEmpty()) { QFileInfo specfi(Option::mkfile::qmakespec); QDir specdir(specfi.absoluteFilePath()); while(!specdir.isRoot()) { if(!specdir.cdUp() || specdir.isRoot()) break; - if(QFile::exists(specdir.path() + QDir::separator() + "features")) { + if(QFile::exists(specdir.path() + QLatin1String("/features"))) { for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) feature_roots << (specdir.path() + (*concat_it)); @@ -604,7 +604,7 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) QStringList qmake_mkspec_paths() { QStringList ret; - const QString concat = QDir::separator() + QString("mkspecs"); + const QString concat = QLatin1String("/mkspecs"); QByteArray qmakepath = qgetenv("QMAKEPATH"); if (!qmakepath.isEmpty()) { const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath)); @@ -1232,10 +1232,10 @@ QMakeProject::read(const QString &file, QHash &place) reset(); const QString oldpwd = qmake_getpwd(); - QString filename = Option::fixPathToLocalOS(file, false); + QString filename = Option::normalizePath(file, false); bool ret = false, using_stdin = false; QFile qfile; - if(!strcmp(filename.toLatin1(), "-")) { + if(filename == QLatin1String("-")) { qfile.setFileName(""); ret = qfile.open(stdin, QIODevice::ReadOnly); using_stdin = true; @@ -1288,10 +1288,10 @@ QMakeProject::read(uchar cmd) int cache_depth = -1; QString qmake_cache = Option::mkfile::cachefile; if(qmake_cache.isEmpty()) { //find it as it has not been specified - QString dir = QDir::toNativeSeparators(Option::output_dir); - while(!QFile::exists((qmake_cache = dir + QDir::separator() + ".qmake.cache"))) { - dir = dir.left(dir.lastIndexOf(QDir::separator())); - if(dir.isEmpty() || dir.indexOf(QDir::separator()) == -1) { + QString dir = Option::output_dir; + while(!QFile::exists((qmake_cache = dir + QLatin1String("/.qmake.cache")))) { + dir = dir.left(dir.lastIndexOf(QLatin1Char('/'))); + if(dir.isEmpty() || dir.indexOf(QLatin1Char('/')) == -1) { qmake_cache = ""; break; } @@ -1321,7 +1321,7 @@ QMakeProject::read(uchar cmd) mkspec_roots.join("::").toLatin1().constData()); if(qmakespec.isEmpty()) { for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { - QString mkspec = (*it) + QDir::separator() + "default"; + QString mkspec = (*it) + QLatin1String("/default"); QFileInfo default_info(mkspec); if(default_info.exists() && default_info.isDir()) { qmakespec = mkspec; @@ -1343,7 +1343,7 @@ QMakeProject::read(uchar cmd) } else { bool found_mkspec = false; for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { - QString mkspec = (*it) + QDir::separator() + qmakespec; + QString mkspec = (*it) + QLatin1Char('/') + qmakespec; if(QFile::exists(mkspec)) { found_mkspec = true; Option::mkfile::qmakespec = qmakespec = mkspec; @@ -1359,9 +1359,9 @@ QMakeProject::read(uchar cmd) } // parse qmake configuration - while(qmakespec.endsWith(QString(QChar(QDir::separator())))) + while(qmakespec.endsWith(QLatin1Char('/'))) qmakespec.truncate(qmakespec.length()-1); - QString spec = qmakespec + QDir::separator() + "qmake.conf"; + QString spec = qmakespec + QLatin1String("/qmake.conf"); debug_msg(1, "QMAKESPEC conf: reading %s", spec.toLatin1().constData()); if(!read(spec, base_vars)) { fprintf(stderr, "Failure to read QMAKESPEC conf file %s.\n", spec.toLatin1().constData()); @@ -1635,7 +1635,7 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QHashsize(); ++root) { prfFile = QFileInfo(feature_roots->at(root) + - QDir::separator() + file).canonicalFilePath(); + QLatin1Char('/') + file).canonicalFilePath(); if(prfFile == currFile) { start_root = root+1; break; @@ -1659,7 +1659,7 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QHashsize(); ++root) { - QString prf(feature_roots->at(root) + QDir::separator() + file); + QString prf(feature_roots->at(root) + QLatin1Char('/') + file); if(QFile::exists(prf + Option::js_ext)) { format = JSFormat; file = prf + Option::js_ext; @@ -1683,9 +1683,9 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QHash args_list, fprintf(stderr, "%s:%d: cat(file) requires one argument.\n", parser.file.toLatin1().constData(), parser.line_no); } else { - QString file = args[0]; - file = Option::fixPathToLocalOS(file); + QString file = Option::normalizePath(args[0]); bool singleLine = true; if(args.count() > 1) @@ -1927,8 +1926,7 @@ QMakeProject::doProjectExpand(QString func, QList args_list, fprintf(stderr, "%s:%d: fromfile(file, variable) requires two arguments.\n", parser.file.toLatin1().constData(), parser.line_no); } else { - QString file = args[0], seek_var = args[1]; - file = Option::fixPathToLocalOS(file); + QString seek_var = args[1], file = Option::normalizePath(args[0]); QHash tmp; if(doProjectInclude(file, IncludeFlagNewParser, tmp) == IncludeSuccess) { @@ -2171,8 +2169,8 @@ QMakeProject::doProjectExpand(QString func, QList args_list, if(args.count() == 2) recursive = (args[1].toLower() == "true" || args[1].toInt()); QStringList dirs; - QString r = Option::fixPathToLocalOS(args[0]); - int slash = r.lastIndexOf(QDir::separator()); + QString r = Option::normalizePath(args[0]); + int slash = r.lastIndexOf(QLatin1Char('/')); if(slash != -1) { dirs.append(r.left(slash)); r = r.mid(slash+1); @@ -2183,7 +2181,7 @@ QMakeProject::doProjectExpand(QString func, QList args_list, const QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard); for(int d = 0; d < dirs.count(); d++) { QString dir = dirs[d]; - if(!dir.isEmpty() && !dir.endsWith(QDir::separator())) + if (!dir.isEmpty() && !dir.endsWith(QLatin1Char('/'))) dir += "/"; QDir qdir(dir); @@ -2411,14 +2409,13 @@ QMakeProject::doProjectTest(QString func, QList args_list, QHash args_list, QHash tmp; - if(doProjectInclude(Option::fixPathToLocalOS(args[0]), IncludeFlagNewParser, tmp) == IncludeSuccess) { + if(doProjectInclude(Option::normalizePath(args[0]), IncludeFlagNewParser, tmp) == IncludeSuccess) { if(tmp.contains("QMAKE_INTERNAL_INCLUDED_FILES")) { QStringList &out = place["QMAKE_INTERNAL_INCLUDED_FILES"]; const QStringList &in = tmp["QMAKE_INTERNAL_INCLUDED_FILES"]; @@ -2658,8 +2655,7 @@ QMakeProject::doProjectTest(QString func, QList args_list, QHash