PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/qmake/library/ioutils.cpp

https://bitbucket.org/cvp2ri/qt5-tlsauth
C++ | 168 lines | 98 code | 17 blank | 53 comment | 26 complexity | 6ba05077f154175c4f9b46574eb400ab MD5 | raw file
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
  4. ** Contact: http://www.qt-project.org/legal
  5. **
  6. ** This file is part of the qmake application of the Qt Toolkit.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and Digia. For licensing terms and
  14. ** conditions see http://qt.digia.com/licensing. For further information
  15. ** use the contact form at http://qt.digia.com/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 2.1 as published by the Free Software
  20. ** Foundation and appearing in the file LICENSE.LGPL included in the
  21. ** packaging of this file. Please review the following information to
  22. ** ensure the GNU Lesser General Public License version 2.1 requirements
  23. ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  24. **
  25. ** In addition, as a special exception, Digia gives you certain additional
  26. ** rights. These rights are described in the Digia Qt LGPL Exception
  27. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  28. **
  29. ** GNU General Public License Usage
  30. ** Alternatively, this file may be used under the terms of the GNU
  31. ** General Public License version 3.0 as published by the Free Software
  32. ** Foundation and appearing in the file LICENSE.GPL included in the
  33. ** packaging of this file. Please review the following information to
  34. ** ensure the GNU General Public License version 3.0 requirements will be
  35. ** met: http://www.gnu.org/copyleft/gpl.html.
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #include "ioutils.h"
  42. #include <qdir.h>
  43. #include <qfile.h>
  44. #ifdef Q_OS_WIN
  45. # include <windows.h>
  46. #else
  47. # include <sys/types.h>
  48. # include <sys/stat.h>
  49. # include <unistd.h>
  50. #endif
  51. QT_BEGIN_NAMESPACE
  52. using namespace QMakeInternal;
  53. IoUtils::FileType IoUtils::fileType(const QString &fileName)
  54. {
  55. Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName));
  56. #ifdef Q_OS_WIN
  57. DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16());
  58. if (attr == INVALID_FILE_ATTRIBUTES)
  59. return FileNotFound;
  60. return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FileIsDir : FileIsRegular;
  61. #else
  62. struct ::stat st;
  63. if (::stat(fileName.toLocal8Bit().constData(), &st))
  64. return FileNotFound;
  65. return S_ISDIR(st.st_mode) ? FileIsDir : FileIsRegular;
  66. #endif
  67. }
  68. bool IoUtils::isRelativePath(const QString &path)
  69. {
  70. if (path.startsWith(QLatin1Char('/')))
  71. return false;
  72. #ifdef Q_OS_WIN
  73. if (path.startsWith(QLatin1Char('\\')))
  74. return false;
  75. // Unlike QFileInfo, this won't accept a relative path with a drive letter.
  76. // Such paths result in a royal mess anyway ...
  77. if (path.length() >= 3 && path.at(1) == QLatin1Char(':') && path.at(0).isLetter()
  78. && (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\')))
  79. return false;
  80. #endif
  81. return true;
  82. }
  83. QStringRef IoUtils::fileName(const QString &fileName)
  84. {
  85. return fileName.midRef(fileName.lastIndexOf(QLatin1Char('/')) + 1);
  86. }
  87. QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
  88. {
  89. if (fileName.isEmpty())
  90. return QString();
  91. if (isAbsolutePath(fileName))
  92. return QDir::cleanPath(fileName);
  93. return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
  94. }
  95. inline static
  96. bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
  97. {
  98. for (int x = arg.length() - 1; x >= 0; --x) {
  99. ushort c = arg.unicode()[x].unicode();
  100. if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
  101. return true;
  102. }
  103. return false;
  104. }
  105. QString IoUtils::shellQuoteUnix(const QString &arg)
  106. {
  107. // Chars that should be quoted (TM). This includes:
  108. static const uchar iqm[] = {
  109. 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
  110. 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
  111. }; // 0-32 \'"$`<>|;&(){}*?#!~[]
  112. if (!arg.length())
  113. return QString::fromLatin1("\"\"");
  114. QString ret(arg);
  115. if (hasSpecialChars(ret, iqm)) {
  116. ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
  117. ret.prepend(QLatin1Char('\''));
  118. ret.append(QLatin1Char('\''));
  119. }
  120. return ret;
  121. }
  122. QString IoUtils::shellQuoteWin(const QString &arg)
  123. {
  124. // Chars that should be quoted (TM). This includes:
  125. // - control chars & space
  126. // - the shell meta chars "&()<>^|
  127. // - the potential separators ,;=
  128. static const uchar iqm[] = {
  129. 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
  130. 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
  131. };
  132. if (!arg.length())
  133. return QString::fromLatin1("\"\"");
  134. QString ret(arg);
  135. if (hasSpecialChars(ret, iqm)) {
  136. // Quotes are escaped and their preceding backslashes are doubled.
  137. // It's impossible to escape anything inside a quoted string on cmd
  138. // level, so the outer quoting must be "suspended".
  139. ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\"\\1\\1\\^\"\""));
  140. // The argument must not end with a \ since this would be interpreted
  141. // as escaping the quote -- rather put the \ behind the quote: e.g.
  142. // rather use "foo"\ than "foo\"
  143. int i = ret.length();
  144. while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
  145. --i;
  146. ret.insert(i, QLatin1Char('"'));
  147. ret.prepend(QLatin1Char('"'));
  148. }
  149. return ret;
  150. }
  151. QT_END_NAMESPACE