summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/features/configure.prf4
-rw-r--r--mkspecs/features/default_post.prf4
-rw-r--r--mkspecs/features/incredibuild_xge.prf2
-rw-r--r--mkspecs/features/qt_functions.prf4
-rw-r--r--mkspecs/features/testcocoon.prf2
-rw-r--r--mkspecs/features/win32/embed_manifest_dll.prf2
-rw-r--r--mkspecs/features/win32/embed_manifest_exe.prf2
-rw-r--r--qmake/option.cpp1
-rw-r--r--qmake/project.cpp96
-rw-r--r--tests/auto/tools/qmake/testdata/functions/functions.pro16
10 files changed, 84 insertions, 49 deletions
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index 651f0ad256..ff52c6b373 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -44,7 +44,7 @@ defineTest(qtCompileTest) {
test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$1
test_out_dir = $$shadowed($$test_dir)
- test_cmd_base = "cd $$shell_quote($$native_path($$test_out_dir)) &&"
+ test_cmd_base = "cd $$system_quote($$system_path($$test_out_dir)) &&"
# Disable qmake features which are typically counterproductive for tests
qmake_configs = "\"CONFIG -= qt debug_and_release app_bundle lib_bundle\""
@@ -54,7 +54,7 @@ defineTest(qtCompileTest) {
mkpath($$test_out_dir)|error("Aborting.")
- qtRunLoggedCommand("$$test_cmd_base $$shell_quote($$native_path($$QMAKE_QMAKE)) $$qmake_configs $$shell_quote($$test_dir)") {
+ qtRunLoggedCommand("$$test_cmd_base $$system_quote($$system_path($$QMAKE_QMAKE)) $$qmake_configs $$shell_quote($$test_dir)") {
qtRunLoggedCommand("$$test_cmd_base $$QMAKE_MAKE") {
log("yes$$escape_expand(\\n)")
msg = "test $$1 succeeded"
diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf
index 63daff64bc..d0a2d61607 100644
--- a/mkspecs/features/default_post.prf
+++ b/mkspecs/features/default_post.prf
@@ -31,8 +31,8 @@ breakpad {
load(resolve_target)
win32: QMAKE_CLEAN += $$replace(QMAKE_RESOLVED_TARGET, ...$, pdb) # for the debug case it is hardcoded in qmake
- DEBUGFILENAME = $$shell_quote($$native_path($$QMAKE_RESOLVED_TARGET))
- PROJECTPATH = $$shell_quote($$native_path($$OUT_PWD))
+ DEBUGFILENAME = $$shell_quote($$shell_path($$QMAKE_RESOLVED_TARGET))
+ PROJECTPATH = $$shell_quote($$shell_path($$OUT_PWD))
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)
QMAKE_POST_LINK = $$QMAKE_POST_LINK$$quote($${QT_BREAKPAD_ROOT_PATH}$${QMAKE_DIR_SEP}qtbreakpadsymbols $$DEBUGFILENAME $$PROJECTPATH)
diff --git a/mkspecs/features/incredibuild_xge.prf b/mkspecs/features/incredibuild_xge.prf
index 28a58cafce..028f39d7b6 100644
--- a/mkspecs/features/incredibuild_xge.prf
+++ b/mkspecs/features/incredibuild_xge.prf
@@ -6,6 +6,6 @@ contains(TEMPLATE, "vc.*") {
win32-msvc2*|wince*msvc*: EOC = $$escape_expand(\\r\\h)
for(xge, INCREDIBUILD_XGE) {
- $${xge}.commands = Rem IncrediBuild_AllowRemote $$EOC Rem IncrediBuild_OutputFile $$native_path($${xge}.output) $$EOC $$eval($${xge}.commands)
+ $${xge}.commands = Rem IncrediBuild_AllowRemote $$EOC Rem IncrediBuild_OutputFile $$shell_path($${xge}.output) $$EOC $$eval($${xge}.commands)
}
}
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 649bea0f80..b6a3b0ada4 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -137,12 +137,12 @@ defineTest(qtPrepareTool) {
}
}
}
- $$1 = $$native_path($$eval($$1))
+ $$1 = $$shell_path($$eval($$1))
deps = $$resolve_depends(QT_TOOL.$${2}.depends, "QT.")
!isEmpty(deps) {
for(dep, deps): \
- deppath += $$native_path($$eval(QT.$${dep}.libs))
+ deppath += $$shell_path($$eval(QT.$${dep}.libs))
deppath = $$unique(deppath)
equals(QMAKE_DIR_SEP, /) {
equals(QMAKE_HOST.os, Windows): \
diff --git a/mkspecs/features/testcocoon.prf b/mkspecs/features/testcocoon.prf
index bf7e3dd463..efa33ecb08 100644
--- a/mkspecs/features/testcocoon.prf
+++ b/mkspecs/features/testcocoon.prf
@@ -25,7 +25,7 @@ TESTCOCOON_COVERAGE_OPTIONS = \
# is built directly in target.path and there is no need to move the csmes.
!isEmpty(DESTDIR):contains(TEMPLATE, lib) {
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK
- QMAKE_POST_LINK = -$(MOVE) $${TARGET_BASENAME}.csmes $$native_path($${QMAKE_RESOLVED_TARGET}.csmes)$$QMAKE_POST_LINK
+ QMAKE_POST_LINK = -$(MOVE) $${TARGET_BASENAME}.csmes $$shell_path($${QMAKE_RESOLVED_TARGET}.csmes)$$QMAKE_POST_LINK
}
QMAKE_CLEAN += *.csexe *.csmes
diff --git a/mkspecs/features/win32/embed_manifest_dll.prf b/mkspecs/features/win32/embed_manifest_dll.prf
index 783dc6708d..e50783d20a 100644
--- a/mkspecs/features/win32/embed_manifest_dll.prf
+++ b/mkspecs/features/win32/embed_manifest_dll.prf
@@ -7,6 +7,6 @@
NOPATH_TARGET ~= s,^(.*/)+,, # Remove all paths
QMAKE_LFLAGS += /MANIFEST $$quote(/MANIFESTFILE:\"$${MANIFEST_DIR}\\$${NOPATH_TARGET}.intermediate.manifest\")
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK
- QMAKE_POST_LINK = $$quote(mt.exe -nologo -manifest $$shell_quote($$native_path($$MANIFEST_DIR/$${NOPATH_TARGET}.intermediate.manifest)) -outputresource:$(DESTDIR_TARGET);2)$$QMAKE_POST_LINK
+ QMAKE_POST_LINK = $$quote(mt.exe -nologo -manifest $$shell_quote($$shell_path($$MANIFEST_DIR/$${NOPATH_TARGET}.intermediate.manifest)) -outputresource:$(DESTDIR_TARGET);2)$$QMAKE_POST_LINK
QMAKE_CLEAN += $$MANIFEST_DIR/$${NOPATH_TARGET}.intermediate.manifest
}
diff --git a/mkspecs/features/win32/embed_manifest_exe.prf b/mkspecs/features/win32/embed_manifest_exe.prf
index c496a53f91..526fc009d9 100644
--- a/mkspecs/features/win32/embed_manifest_exe.prf
+++ b/mkspecs/features/win32/embed_manifest_exe.prf
@@ -7,6 +7,6 @@ if(win32-msvc2005*|win32-msvc2008*|win32-msvc2010*):equals(TEMPLATE, "app") {
NOPATH_TARGET ~= s,^(.*/)+,, # Remove all paths
QMAKE_LFLAGS += /MANIFEST $$quote(/MANIFESTFILE:\"$${MANIFEST_DIR}\\$${NOPATH_TARGET}.intermediate.manifest\")
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK
- QMAKE_POST_LINK = $$quote(mt.exe -nologo -manifest $$shell_quote($$native_path($$MANIFEST_DIR/$${NOPATH_TARGET}.intermediate.manifest)) -outputresource:$(DESTDIR_TARGET);1)$$QMAKE_POST_LINK
+ QMAKE_POST_LINK = $$quote(mt.exe -nologo -manifest $$shell_quote($$shell_path($$MANIFEST_DIR/$${NOPATH_TARGET}.intermediate.manifest)) -outputresource:$(DESTDIR_TARGET);1)$$QMAKE_POST_LINK
QMAKE_CLEAN += $$MANIFEST_DIR/$${NOPATH_TARGET}.intermediate.manifest
}
diff --git a/qmake/option.cpp b/qmake/option.cpp
index b01b4eded5..3bfec96087 100644
--- a/qmake/option.cpp
+++ b/qmake/option.cpp
@@ -555,7 +555,6 @@ bool Option::postProcessProject(QMakeProject *project)
Option::h_moc_mod = project->first("QMAKE_H_MOD_MOC");
Option::lex_mod = project->first("QMAKE_MOD_LEX");
Option::yacc_mod = project->first("QMAKE_MOD_YACC");
- Option::dir_sep = project->first("QMAKE_DIR_SEP");
if (Option::output_dir.startsWith(project->buildRoot()))
Option::mkfile::cachefile_depth =
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 26ab0d0f35..0681697a96 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -82,8 +82,8 @@ enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_CAT, E_FROMFILE, E_EVAL, E_LIST
E_FIND, E_SYSTEM, E_UNIQUE, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND,
E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, E_REPLACE,
E_SIZE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
- E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH, E_NATIVE_PATH,
- E_SHELL_QUOTE };
+ E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH,
+ E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE };
QHash<QString, ExpandFunc> qmake_expandFunctions()
{
static QHash<QString, ExpandFunc> *qmake_expand_functions = 0;
@@ -125,7 +125,9 @@ QHash<QString, ExpandFunc> qmake_expandFunctions()
qmake_expand_functions->insert("absolute_path", E_ABSOLUTE_PATH);
qmake_expand_functions->insert("relative_path", E_RELATIVE_PATH);
qmake_expand_functions->insert("clean_path", E_CLEAN_PATH);
- qmake_expand_functions->insert("native_path", E_NATIVE_PATH);
+ qmake_expand_functions->insert("system_path", E_SYSTEM_PATH);
+ qmake_expand_functions->insert("shell_path", E_SHELL_PATH);
+ qmake_expand_functions->insert("system_quote", E_SYSTEM_QUOTE);
qmake_expand_functions->insert("shell_quote", E_SHELL_QUOTE);
}
return *qmake_expand_functions;
@@ -1498,6 +1500,8 @@ QMakeProject::read(uchar cmd)
doProjectInclude("spec_post", IncludeFlagFeature, vars);
// The spec extends the feature search path, so invalidate the cache.
invalidateFeatureRoots();
+ // The MinGW and x-build specs may change the separator; $$shell_{path,quote}() need it
+ Option::dir_sep = first(QLatin1String("QMAKE_DIR_SEP"));
if (!conffile.isEmpty()) {
debug_msg(1, "Project config file: reading %s", conffile.toLatin1().constData());
@@ -1895,45 +1899,54 @@ subAll(QStringList *val, const QStringList &diffval)
}
inline static
-bool isSpecialChar(ushort c)
+bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
+{
+ for (int x = arg.length() - 1; x >= 0; --x) {
+ ushort c = arg.unicode()[x].unicode();
+ if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
+ return true;
+ }
+ return false;
+}
+
+static QString
+shellQuoteUnix(const QString &arg)
{
// Chars that should be quoted (TM). This includes:
-#ifdef Q_OS_WIN
- // - control chars & space
- // - the shell meta chars "&()<>^|
- // - the potential separators ,;=
- static const uchar iqm[] = {
- 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
- };
-#else
static const uchar iqm[] = {
0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
}; // 0-32 \'"$`<>|;&(){}*?#!~[]
-#endif
- return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
-}
+ if (!arg.length())
+ return QString::fromLatin1("\"\"");
-inline static
-bool hasSpecialChars(const QString &arg)
-{
- for (int x = arg.length() - 1; x >= 0; --x)
- if (isSpecialChar(arg.unicode()[x].unicode()))
- return true;
- return false;
+ QString ret(arg);
+ if (hasSpecialChars(ret, iqm)) {
+ ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
+ ret.prepend(QLatin1Char('\''));
+ ret.append(QLatin1Char('\''));
+ }
+ return ret;
}
static QString
-shellQuote(const QString &arg)
+shellQuoteWin(const QString &arg)
{
+ // Chars that should be quoted (TM). This includes:
+ // - control chars & space
+ // - the shell meta chars "&()<>^|
+ // - the potential separators ,;=
+ static const uchar iqm[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
+ };
+
if (!arg.length())
return QString::fromLatin1("\"\"");
QString ret(arg);
- if (hasSpecialChars(ret)) {
-#ifdef Q_OS_WIN
+ if (hasSpecialChars(ret, iqm)) {
// Quotes are escaped and their preceding backslashes are doubled.
// It's impossible to escape anything inside a quoted string on cmd
// level, so the outer quoting must be "suspended".
@@ -1946,11 +1959,6 @@ shellQuote(const QString &arg)
--i;
ret.insert(i, QLatin1Char('"'));
ret.prepend(QLatin1Char('"'));
-#else // Q_OS_WIN
- ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
- ret.prepend(QLatin1Char('\''));
- ret.append(QLatin1Char('\''));
-#endif // Q_OS_WIN
}
return ret;
}
@@ -2738,19 +2746,39 @@ QMakeProject::doProjectExpand(QString func, QList<QStringList> args_list,
else
ret += QDir::cleanPath(args.at(0));
break;
- case E_NATIVE_PATH:
+ case E_SYSTEM_PATH:
if (args.count() != 1)
- fprintf(stderr, "%s:%d native_path(path) requires one argument.\n",
+ fprintf(stderr, "%s:%d system_path(path) requires one argument.\n",
+ parser.file.toLatin1().constData(), parser.line_no);
+ else
+ ret += Option::fixPathToLocalOS(args.at(0), false);
+ break;
+ case E_SHELL_PATH:
+ if (args.count() != 1)
+ fprintf(stderr, "%s:%d shell_path(path) requires one argument.\n",
parser.file.toLatin1().constData(), parser.line_no);
else
ret += Option::fixPathToTargetOS(args.at(0), false);
break;
+ case E_SYSTEM_QUOTE:
+ if (args.count() != 1)
+ fprintf(stderr, "%s:%d system_quote(args) requires one argument.\n",
+ parser.file.toLatin1().constData(), parser.line_no);
+ else
+#ifdef Q_OS_WIN
+ ret += shellQuoteWin(args.at(0));
+#else
+ ret += shellQuoteUnix(args.at(0));
+#endif
+ break;
case E_SHELL_QUOTE:
if (args.count() != 1)
fprintf(stderr, "%s:%d shell_quote(args) requires one argument.\n",
parser.file.toLatin1().constData(), parser.line_no);
+ else if (Option::dir_sep.at(0) != QLatin1Char('/'))
+ ret += shellQuoteWin(args.at(0));
else
- ret += shellQuote(args.at(0));
+ ret += shellQuoteUnix(args.at(0));
break;
default: {
fprintf(stderr, "%s:%d: Unknown replace function: %s\n",
diff --git a/tests/auto/tools/qmake/testdata/functions/functions.pro b/tests/auto/tools/qmake/testdata/functions/functions.pro
index 884113b95a..98e12b7650 100644
--- a/tests/auto/tools/qmake/testdata/functions/functions.pro
+++ b/tests/auto/tools/qmake/testdata/functions/functions.pro
@@ -131,7 +131,8 @@ testReplace($$format_number(13, width=5 padsign zeropad), " 0013", "zero-padded
testReplace($$clean_path("c:$${DIR_SEPARATOR}crazy//path/../trolls"), "c:/crazy/trolls", "clean_path")
-testReplace($$native_path("/crazy/trolls"), "$${DIR_SEPARATOR}crazy$${DIR_SEPARATOR}trolls", "native_path")
+testReplace($$shell_path("/crazy/trolls"), "$${QMAKE_DIR_SEP}crazy$${QMAKE_DIR_SEP}trolls", "shell_path")
+testReplace($$system_path("/crazy/trolls"), "$${DIR_SEPARATOR}crazy$${DIR_SEPARATOR}trolls", "system_path")
testReplace($$absolute_path("crazy/trolls"), "$$PWD/crazy/trolls", "absolute_path")
testReplace($$absolute_path("crazy/trolls", "/fake/path"), "/fake/path/crazy/trolls", "absolute_path with base")
@@ -142,10 +143,17 @@ testReplace($$relative_path(""), "", "relative_path of empty")
#this test is very rudimentary. the backend function is thoroughly tested in qt creator
in = "some nasty\" path\\"
-win32: \
- out = "\"some nasty\"\\^\"\" path\"\\"
+out_cmd = "\"some nasty\"\\^\"\" path\"\\"
+out_sh = "'some nasty\" path\\'"
+equals(QMAKE_HOST.os, Windows): \
+ out = $$out_cmd
else: \
- out = "'some nasty\" path\\'"
+ out = $$out_sh
+testReplace($$system_quote($$in), $$out, "system_quote")
+!equals(QMAKE_DIR_SEP, /): \
+ out = $$out_cmd
+else: \
+ out = $$out_sh
testReplace($$shell_quote($$in), $$out, "shell_quote")
testReplace($$reverse($$list(one two three)), three two one, "reverse")