*`--dump-manifest`* _PATH_::
- Dump manifest file at _PATH_ in text format. This is only useful when
- debugging ccache and its behavior.
+ Dump manifest file at _PATH_ in text format to standard output. This is
+ only useful when debugging ccache and its behavior.
*`--dump-result`* _PATH_::
- Dump result file at _PATH_ in text format. This is only useful when
- debugging ccache and its behavior.
+ Dump result file at _PATH_ in text format to standard output. This is only
+ useful when debugging ccache and its behavior.
+
+*`--extract-result`* _PATH_::
+
+ Extract data stored in the result file at _PATH_. The data will be written
+ to *ccache-result.** files in to the current working directory. This is
+ only useful when debugging ccache and its behavior.
*`-k`* _KEY_, *`--get-config`* _KEY_::
ProgressBar.cpp
Result.cpp
ResultDumper.cpp
+ ResultExtractor.cpp
ResultRetriever.cpp
SignalHandler.cpp
Stat.cpp
const uint8_t k_magic[4] = {'c', 'C', 'r', 'S'};
const uint8_t k_version = 1;
+const char* const k_unknown_file_type = "<unknown type>";
const char*
file_type_to_string(FileType type)
return ".dwo";
}
- return "<unknown type>";
+ return k_unknown_file_type;
}
Result::Reader::Reader(const std::string& result_path)
extern const uint8_t k_magic[4];
extern const uint8_t k_version;
+extern const char* const k_unknown_file_type;
using UnderlyingFileTypeInt = uint8_t;
enum class FileType : UnderlyingFileTypeInt {
--- /dev/null
+// Copyright (C) 2020 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "ResultExtractor.hpp"
+
+#include "Context.hpp"
+#include "logging.hpp"
+
+#include "third_party/nonstd/string_view.hpp"
+
+using string_view = nonstd::string_view;
+
+ResultExtractor::ResultExtractor(const std::string& directory)
+ : m_directory(directory)
+{
+}
+
+void
+ResultExtractor::on_header(CacheEntryReader& /*cache_entry_reader*/)
+{
+}
+
+void
+ResultExtractor::on_entry_start(uint32_t /*entry_number*/,
+ Result::FileType file_type,
+ uint64_t /*file_len*/,
+ nonstd::optional<std::string> raw_file)
+{
+ std::string suffix = Result::file_type_to_string(file_type);
+ if (suffix == Result::k_unknown_file_type) {
+ suffix = fmt::format(".type_{}", file_type);
+ } else if (suffix[0] == '<') {
+ suffix[0] = '.';
+ suffix.resize(suffix.length() - 1);
+ }
+
+ m_dest_path = fmt::format("{}/ccache-result{}", m_directory, suffix);
+
+ if (!raw_file) {
+ m_dest_fd = Fd(
+ open(m_dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666));
+ if (!m_dest_fd) {
+ throw Error(fmt::format(
+ "Failed to open {} for writing: {}", m_dest_path, strerror(errno)));
+ }
+
+ } else if (!copy_file(raw_file->c_str(), m_dest_path.c_str(), false)) {
+ throw Error(fmt::format(
+ "Failed to copy {} to {}: {}", *raw_file, m_dest_path, strerror(errno)));
+ }
+}
+
+void
+ResultExtractor::on_entry_data(const uint8_t* data, size_t size)
+{
+ assert(m_dest_fd);
+
+ if (!write_fd(*m_dest_fd, data, size)) {
+ throw Error(fmt::format("Failed to write to {}", m_dest_path));
+ }
+}
+
+void
+ResultExtractor::on_entry_end()
+{
+ if (m_dest_fd) {
+ m_dest_fd.close();
+ }
+}
--- /dev/null
+// Copyright (C) 2020 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#pragma once
+
+#include "system.hpp"
+
+#include "Fd.hpp"
+#include "Result.hpp"
+
+class Context;
+
+// This class extracts the parts of a result entry to a directory.
+class ResultExtractor : public Result::Reader::Consumer
+{
+public:
+ ResultExtractor(const std::string& directory);
+
+ virtual void on_header(CacheEntryReader& cache_entry_reader);
+ virtual void on_entry_start(uint32_t entry_number,
+ Result::FileType file_type,
+ uint64_t file_len,
+ nonstd::optional<std::string> raw_file);
+ virtual void on_entry_data(const uint8_t* data, size_t size);
+ virtual void on_entry_end();
+
+private:
+ const std::string m_directory;
+ Fd m_dest_fd;
+ std::string m_dest_path;
+};
class Context;
-// This class retrieves an result entry to the local file system.
+// This class retrieves a result entry to the local file system.
class ResultRetriever : public Result::Reader::Consumer
{
public:
#include "ProgressBar.hpp"
#include "Result.hpp"
#include "ResultDumper.hpp"
+#include "ResultExtractor.hpp"
#include "ResultRetriever.hpp"
#include "SignalHandler.hpp"
#include "StdMakeUnique.hpp"
Options for scripting or debugging:
--dump-manifest PATH dump manifest file at PATH in text format
--dump-result PATH dump result file at PATH in text format
+ --extract-result PATH extract data stored in result file at PATH to the
+ current working directory
-k, --get-config KEY print the value of configuration key KEY
--hash-file PATH print the hash (160 bit BLAKE3) of the file at
PATH
enum longopts {
DUMP_MANIFEST,
DUMP_RESULT,
+ EXTRACT_RESULT,
HASH_FILE,
PRINT_STATS,
};
{"clear", no_argument, nullptr, 'C'},
{"dump-manifest", required_argument, nullptr, DUMP_MANIFEST},
{"dump-result", required_argument, nullptr, DUMP_RESULT},
+ {"extract-result", required_argument, nullptr, EXTRACT_RESULT},
{"get-config", required_argument, nullptr, 'k'},
{"hash-file", required_argument, nullptr, HASH_FILE},
{"help", no_argument, nullptr, 'h'},
return error ? EXIT_FAILURE : EXIT_SUCCESS;
}
+ case EXTRACT_RESULT: {
+ ResultExtractor result_extractor(".");
+ Result::Reader result_reader(optarg);
+ auto error = result_reader.read(result_extractor);
+ if (error) {
+ fmt::print(stderr, "Error: {}\n", *error);
+ }
+ return error ? EXIT_FAILURE : EXIT_SUCCESS;
+ }
+
case HASH_FILE: {
struct hash* hash = hash_init();
if (str_eq(optarg, "-")) {