summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2019-04-05 19:10:53 (GMT)
committerSebastian Holtermann <sebholt@xwmw.org>2019-04-06 14:17:19 (GMT)
commit7cbde5c503f15bcc568a64239977b8e1f6f501cb (patch)
tree6078c007e8ec354c204ee43882f22e720f23adeb
parent7a5adae94dc8ca38fb2323742c6e4164682a876f (diff)
downloadCMake-7cbde5c503f15bcc568a64239977b8e1f6f501cb.zip
CMake-7cbde5c503f15bcc568a64239977b8e1f6f501cb.tar.gz
CMake-7cbde5c503f15bcc568a64239977b8e1f6f501cb.tar.bz2
AutoRcc: Add cmQtAutoGen::RccLister class
The new `cmQtAutoGen::RccLister` class provides a simple interface to list files in a `.qrc` resources file by either calling `rcc` with list options or by parsing the resources file content.
-rw-r--r--Source/cmQtAutoGen.cxx108
-rw-r--r--Source/cmQtAutoGen.h39
2 files changed, 144 insertions, 3 deletions
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index d71d82f..9880c02 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -1,9 +1,12 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGen.h"
+
#include "cmAlgorithms.h"
+#include "cmDuration.h"
+#include "cmProcessOutput.h"
#include "cmSystemTools.h"
-
+#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
@@ -309,7 +312,106 @@ void cmQtAutoGen::RccListConvertFullPath(std::string const& qrcFileDir,
std::vector<std::string>& files)
{
for (std::string& entry : files) {
- std::string tmp = cmSystemTools::CollapseFullPath(entry, qrcFileDir);
- entry = std::move(tmp);
+ entry = cmSystemTools::CollapseFullPath(entry, qrcFileDir);
+ }
+}
+
+cmQtAutoGen::RccLister::RccLister() = default;
+
+cmQtAutoGen::RccLister::RccLister(std::string rccExecutable,
+ std::vector<std::string> listOptions)
+ : RccExcutable_(std::move(rccExecutable))
+ , ListOptions_(std::move(listOptions))
+{
+}
+
+bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
+ std::vector<std::string>& files,
+ std::string& error, bool verbose) const
+{
+ error.clear();
+
+ if (!cmSystemTools::FileExists(qrcFile, true)) {
+ error = "The resource file ";
+ error += Quoted(qrcFile);
+ error += " does not exist.";
+ return false;
+ }
+
+ // Run rcc list command in the directory of the qrc file with the pathless
+ // qrc file name argument. This way rcc prints relative paths.
+ // This avoids issues on Windows when the qrc file is in a path that
+ // contains non-ASCII characters.
+ std::string const fileDir = cmSystemTools::GetFilenamePath(qrcFile);
+
+ if (!this->RccExcutable_.empty() &&
+ cmSystemTools::FileExists(this->RccExcutable_, true) &&
+ !this->ListOptions_.empty()) {
+
+ bool result = false;
+ int retVal = 0;
+ std::string rccStdOut;
+ std::string rccStdErr;
+ {
+ std::vector<std::string> cmd;
+ cmd.emplace_back(this->RccExcutable_);
+ cmd.insert(cmd.end(), this->ListOptions_.begin(),
+ this->ListOptions_.end());
+ cmd.emplace_back(cmSystemTools::GetFilenameName(qrcFile));
+
+ // Log command
+ if (verbose) {
+ std::string msg = "Running command:\n";
+ msg += QuotedCommand(cmd);
+ msg += '\n';
+ cmSystemTools::Stdout(msg);
+ }
+
+ result = cmSystemTools::RunSingleCommand(
+ cmd, &rccStdOut, &rccStdErr, &retVal, fileDir.c_str(),
+ cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
+ }
+ if (!result || retVal) {
+ error = "The rcc list process failed for ";
+ error += Quoted(qrcFile);
+ error += "\n";
+ if (!rccStdOut.empty()) {
+ error += rccStdOut;
+ error += "\n";
+ }
+ if (!rccStdErr.empty()) {
+ error += rccStdErr;
+ error += "\n";
+ }
+ return false;
+ }
+ if (!RccListParseOutput(rccStdOut, rccStdErr, files, error)) {
+ return false;
+ }
+ } else {
+ // We can't use rcc for the file listing.
+ // Read the qrc file content into string and parse it.
+ {
+ std::string qrcContents;
+ {
+ cmsys::ifstream ifs(qrcFile.c_str());
+ if (ifs) {
+ std::ostringstream osst;
+ osst << ifs.rdbuf();
+ qrcContents = osst.str();
+ } else {
+ error = "The resource file ";
+ error += Quoted(qrcFile);
+ error += " is not readable\n";
+ return false;
+ }
+ }
+ // Parse string content
+ RccListParseContent(qrcContents, files);
+ }
}
+
+ // Convert relative paths to absolute paths
+ RccListConvertFullPath(fileDir, files);
+ return true;
}
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index d127a71..0faf6b3 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -100,6 +100,45 @@ public:
/// @brief Converts relative qrc entry paths to full paths
static void RccListConvertFullPath(std::string const& qrcFileDir,
std::vector<std::string>& files);
+
+ /** @class RccLister
+ * @brief Lists files in qrc resource files
+ */
+ class RccLister
+ {
+ public:
+ RccLister();
+ RccLister(std::string rccExecutable, std::vector<std::string> listOptions);
+
+ //! The rcc executable
+ std::string const& RccExcutable() const { return RccExcutable_; }
+ void SetRccExecutable(std::string const& rccExecutable)
+ {
+ RccExcutable_ = rccExecutable;
+ }
+
+ //! The rcc executable list options
+ std::vector<std::string> const& ListOptions() const
+ {
+ return ListOptions_;
+ }
+ void SetListOptions(std::vector<std::string> const& listOptions)
+ {
+ ListOptions_ = listOptions;
+ }
+
+ /**
+ * @brief Lists a files in the qrcFile
+ * @arg files The file names are appended to this list
+ * @arg error contains the error message when the function fails
+ */
+ bool list(std::string const& qrcFile, std::vector<std::string>& files,
+ std::string& error, bool verbose = false) const;
+
+ private:
+ std::string RccExcutable_;
+ std::vector<std::string> ListOptions_;
+ };
};
#endif