summaryrefslogtreecommitdiff
path: root/src/other_tools/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/other_tools/utils')
-rw-r--r--src/other_tools/utils/TARGETS1
-rw-r--r--src/other_tools/utils/parse_archive.cpp65
-rw-r--r--src/other_tools/utils/parse_archive.hpp8
3 files changed, 74 insertions, 0 deletions
diff --git a/src/other_tools/utils/TARGETS b/src/other_tools/utils/TARGETS
index 27c4a6af..207dfb76 100644
--- a/src/other_tools/utils/TARGETS
+++ b/src/other_tools/utils/TARGETS
@@ -55,6 +55,7 @@
[ ["src/buildtool/build_engine/expression", "expression"]
, ["src/other_tools/ops_maps", "content_cas_map"]
]
+ , "private-deps": [["@", "fmt", "", "fmt"]]
, "stage": ["src", "other_tools", "utils"]
}
}
diff --git a/src/other_tools/utils/parse_archive.cpp b/src/other_tools/utils/parse_archive.cpp
index ff5d20bf..f0026eaa 100644
--- a/src/other_tools/utils/parse_archive.cpp
+++ b/src/other_tools/utils/parse_archive.cpp
@@ -14,6 +14,8 @@
#include "src/other_tools/utils/parse_archive.hpp"
+#include "fmt/core.h"
+
namespace {
auto ParseArchiveContent(ExpressionPtr const& repo_desc,
std::string const& origin,
@@ -89,6 +91,17 @@ auto ParseArchiveContent(ExpressionPtr const& repo_desc,
: std::nullopt,
.origin = origin};
}
+
+auto IsValidFileName(const std::string& s) -> bool {
+ if (s.find_first_of("/\0") != std::string::npos) {
+ return false;
+ }
+ if (s.empty() or s == "." or s == "..") {
+ return false;
+ }
+ return true;
+}
+
} // namespace
auto ParseArchiveDescription(ExpressionPtr const& repo_desc,
@@ -131,3 +144,55 @@ auto ParseArchiveDescription(ExpressionPtr const& repo_desc,
.pragma_special = pragma_special_value,
.absent = pragma_absent_value};
}
+
+auto ParseForeignFileDescription(ExpressionPtr const& repo_desc,
+ std::string const& origin,
+ const AsyncMapConsumerLoggerPtr& logger)
+ -> std::optional<ForeignFileInfo> {
+ auto archive_content = ParseArchiveContent(repo_desc, origin, logger);
+ if (not archive_content) {
+ return std::nullopt;
+ }
+ auto name = repo_desc->At("name");
+ if (not name) {
+ (*logger)(
+ "Mandatory field \"name\" for foreign file repository is missing",
+ true);
+ return std::nullopt;
+ }
+ if (not name->get()->IsString()) {
+ (*logger)(fmt::format("Field \"name\" has to be a file name, given as "
+ "string, but found {}",
+ name->get()->ToString()),
+ true);
+ return std::nullopt;
+ }
+ if (not IsValidFileName(name->get()->String())) {
+ (*logger)(fmt::format("Field \"name\" has to be valid a file name, but "
+ "found {}",
+ name->get()->ToString()),
+ true);
+ return std::nullopt;
+ }
+ auto executable = repo_desc->Get("executable", Expression::kFalse);
+ if (not executable->IsBool()) {
+ (*logger)(fmt::format(
+ "Field \"executable\" has to be a boolean, but found {}",
+ executable->ToString()),
+ true);
+ return std::nullopt;
+ }
+ bool absent{};
+ auto pragma = repo_desc->Get("pragma", Expression::kEmptyMap);
+ if (pragma->IsMap()) {
+ auto pragma_absent = pragma->Get("absent", Expression::kFalse);
+ if (pragma_absent->IsBool()) {
+ absent = pragma_absent->Bool();
+ }
+ }
+
+ return ForeignFileInfo{.archive = *archive_content,
+ .name = name->get()->String(),
+ .executable = executable->Bool(),
+ .absent = absent};
+}
diff --git a/src/other_tools/utils/parse_archive.hpp b/src/other_tools/utils/parse_archive.hpp
index 91f3e280..6d356dd4 100644
--- a/src/other_tools/utils/parse_archive.hpp
+++ b/src/other_tools/utils/parse_archive.hpp
@@ -30,4 +30,12 @@ auto ParseArchiveDescription(ExpressionPtr const& repo_desc,
const AsyncMapConsumerLoggerPtr& logger)
-> std::optional<ArchiveRepoInfo>;
+// Parse the description of a foreign-file repository; if an error
+// occurs, call the logger with fatal set to true and return std::nullopt
+// instead.
+auto ParseForeignFileDescription(ExpressionPtr const& repo_desc,
+ std::string const& origin,
+ const AsyncMapConsumerLoggerPtr& logger)
+ -> std::optional<ForeignFileInfo>;
+
#endif