mirror of
https://github.com/cemu-project/vcpkg.git
synced 2025-02-23 02:57:09 +01:00
improve logic expression evaluation (#7508)
* better logic expression evaluation Improve the logic expression evaluation currently used when filtering dependencies. Biggest improvements: + Allow '|' operator + Support nested '()' + Allow whitespace + Useful error message for malformed expressions Also changed names of types to RawParagraph when that is what the original author was using.
This commit is contained in:
parent
4d551ff4b3
commit
22e0b9f376
@ -2,4 +2,4 @@ Source: pango
|
|||||||
Version: 1.40.11-4
|
Version: 1.40.11-4
|
||||||
Homepage: https://ftp.gnome.org/pub/GNOME/sources/pango/
|
Homepage: https://ftp.gnome.org/pub/GNOME/sources/pango/
|
||||||
Description: Text and font handling library.
|
Description: Text and font handling library.
|
||||||
Build-Depends: glib, gettext, cairo, fontconfig, freetype, harfbuzz[glib] (!windows-static)
|
Build-Depends: glib, gettext, cairo, fontconfig, freetype, harfbuzz[glib] (!(windows&static))
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <vcpkg/packagespec.h>
|
#include <vcpkg/packagespec.h>
|
||||||
#include <vcpkg/sourceparagraph.h>
|
#include <vcpkg/sourceparagraph.h>
|
||||||
|
#include <vcpkg/parse.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ namespace vcpkg
|
|||||||
struct BinaryParagraph
|
struct BinaryParagraph
|
||||||
{
|
{
|
||||||
BinaryParagraph();
|
BinaryParagraph();
|
||||||
explicit BinaryParagraph(std::unordered_map<std::string, std::string> fields);
|
explicit BinaryParagraph(Parse::RawParagraph fields);
|
||||||
BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag);
|
BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag);
|
||||||
BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet);
|
BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet);
|
||||||
|
|
||||||
|
10
toolsrc/include/vcpkg/logicexpression.h
Normal file
10
toolsrc/include/vcpkg/logicexpression.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace vcpkg
|
||||||
|
{
|
||||||
|
// Evaluate simple vcpkg logic expressions. An identifier in the expression is considered 'true'
|
||||||
|
// if it is a substring of the evaluation_context (typically the name of the triplet)
|
||||||
|
bool evaluate_expression(const std::string& expression, const std::string& evaluation_context);
|
||||||
|
}
|
@ -12,7 +12,6 @@ namespace vcpkg::Paragraphs
|
|||||||
|
|
||||||
Expected<RawParagraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path);
|
Expected<RawParagraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path);
|
||||||
Expected<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path);
|
Expected<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path);
|
||||||
Expected<RawParagraph> parse_single_paragraph(const std::string& str);
|
|
||||||
Expected<std::vector<RawParagraph>> parse_paragraphs(const std::string& str);
|
Expected<std::vector<RawParagraph>> parse_paragraphs(const std::string& str);
|
||||||
|
|
||||||
Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path);
|
Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path);
|
||||||
|
@ -30,7 +30,7 @@ namespace vcpkg
|
|||||||
struct StatusParagraph
|
struct StatusParagraph
|
||||||
{
|
{
|
||||||
StatusParagraph() noexcept;
|
StatusParagraph() noexcept;
|
||||||
explicit StatusParagraph(std::unordered_map<std::string, std::string>&& fields);
|
explicit StatusParagraph(Parse::RawParagraph&& fields);
|
||||||
|
|
||||||
bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; }
|
bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; }
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace vcpkg
|
|||||||
|
|
||||||
BinaryParagraph::BinaryParagraph() = default;
|
BinaryParagraph::BinaryParagraph() = default;
|
||||||
|
|
||||||
BinaryParagraph::BinaryParagraph(std::unordered_map<std::string, std::string> fields)
|
BinaryParagraph::BinaryParagraph(Parse::RawParagraph fields)
|
||||||
{
|
{
|
||||||
using namespace vcpkg::Parse;
|
using namespace vcpkg::Parse;
|
||||||
|
|
||||||
|
@ -938,7 +938,7 @@ namespace vcpkg::Build
|
|||||||
Commands::Version::version());
|
Commands::Version::version());
|
||||||
}
|
}
|
||||||
|
|
||||||
static BuildInfo inner_create_buildinfo(std::unordered_map<std::string, std::string> pgh)
|
static BuildInfo inner_create_buildinfo(Parse::RawParagraph pgh)
|
||||||
{
|
{
|
||||||
Parse::ParagraphParser parser(std::move(pgh));
|
Parse::ParagraphParser parser(std::move(pgh));
|
||||||
|
|
||||||
@ -995,7 +995,7 @@ namespace vcpkg::Build
|
|||||||
|
|
||||||
BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath)
|
BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath)
|
||||||
{
|
{
|
||||||
const Expected<std::unordered_map<std::string, std::string>> pghs =
|
const Expected<Parse::RawParagraph> pghs =
|
||||||
Paragraphs::get_single_paragraph(fs, filepath);
|
Paragraphs::get_single_paragraph(fs, filepath);
|
||||||
Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package");
|
Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package");
|
||||||
return inner_create_buildinfo(*pghs.get());
|
return inner_create_buildinfo(*pghs.get());
|
||||||
|
@ -14,7 +14,7 @@ namespace vcpkg::Commands::Cache
|
|||||||
std::vector<BinaryParagraph> output;
|
std::vector<BinaryParagraph> output;
|
||||||
for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages))
|
for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages))
|
||||||
{
|
{
|
||||||
const Expected<std::unordered_map<std::string, std::string>> pghs =
|
const Expected<Parse::RawParagraph> pghs =
|
||||||
Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL");
|
Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL");
|
||||||
if (const auto p = pghs.get())
|
if (const auto p = pghs.get())
|
||||||
{
|
{
|
||||||
|
@ -108,7 +108,7 @@ namespace vcpkg::Commands::Import
|
|||||||
const fs::path include_directory(args.command_arguments[1]);
|
const fs::path include_directory(args.command_arguments[1]);
|
||||||
const fs::path project_directory(args.command_arguments[2]);
|
const fs::path project_directory(args.command_arguments[2]);
|
||||||
|
|
||||||
const Expected<std::unordered_map<std::string, std::string>> pghs =
|
const Expected<Parse::RawParagraph> pghs =
|
||||||
Paragraphs::get_single_paragraph(paths.get_filesystem(), control_file_path);
|
Paragraphs::get_single_paragraph(paths.get_filesystem(), control_file_path);
|
||||||
Checks::check_exit(VCPKG_LINE_INFO,
|
Checks::check_exit(VCPKG_LINE_INFO,
|
||||||
pghs.get() != nullptr,
|
pghs.get() != nullptr,
|
||||||
|
285
toolsrc/src/vcpkg/logicexpression.cpp
Normal file
285
toolsrc/src/vcpkg/logicexpression.cpp
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include <vcpkg/logicexpression.h>
|
||||||
|
#include <vcpkg/base/checks.h>
|
||||||
|
#include <vcpkg/base/system.print.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace vcpkg
|
||||||
|
{
|
||||||
|
struct ParseError
|
||||||
|
{
|
||||||
|
ParseError(int column, std::string line, std::string message)
|
||||||
|
:column(column), line(line), message(message)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const int column;
|
||||||
|
const std::string line;
|
||||||
|
const std::string message;
|
||||||
|
|
||||||
|
void print_error() const
|
||||||
|
{
|
||||||
|
System::print2(System::Color::error,
|
||||||
|
"Error: ", message, "\n"
|
||||||
|
" on expression: \"", line, "\"\n",
|
||||||
|
" ", std::string(column, ' '), "^\n");
|
||||||
|
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// logic expression supports the following :
|
||||||
|
// primary-expression:
|
||||||
|
// ( logic-expression )
|
||||||
|
// identifier
|
||||||
|
// identifier:
|
||||||
|
// alpha-numeric string of characters
|
||||||
|
// logic-expression: <- this is the entry point
|
||||||
|
// not-expression
|
||||||
|
// not-expression | logic-expression
|
||||||
|
// not-expression & logic-expression
|
||||||
|
// not-expression:
|
||||||
|
// ! primary-expression
|
||||||
|
// primary-expression
|
||||||
|
//
|
||||||
|
// | and & have equal precidence and cannot be used together at the same nesting level
|
||||||
|
// for example a|b&c is not allowd but (a|b)&c and a|(b&c) are allowed.
|
||||||
|
class ExpressionParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExpressionParser(const std::string& str, const std::string& evaluation_context)
|
||||||
|
: raw_text(str), evaluation_context(evaluation_context)
|
||||||
|
{
|
||||||
|
go_to_begin();
|
||||||
|
|
||||||
|
final_result = logic_expression();
|
||||||
|
|
||||||
|
if (current_iter != raw_text.end())
|
||||||
|
{
|
||||||
|
add_error("Invalid logic expression");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
err->print_error();
|
||||||
|
final_result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_result() const
|
||||||
|
{
|
||||||
|
return final_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_error() const
|
||||||
|
{
|
||||||
|
return err == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool final_result;
|
||||||
|
|
||||||
|
std::string::const_iterator current_iter;
|
||||||
|
const std::string& raw_text;
|
||||||
|
char current_char;
|
||||||
|
|
||||||
|
const std::string& evaluation_context;
|
||||||
|
|
||||||
|
std::unique_ptr<ParseError> err;
|
||||||
|
|
||||||
|
void add_error(std::string message, int column = -1)
|
||||||
|
{
|
||||||
|
// avoid castcading errors by only saving the first
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
if (column < 0)
|
||||||
|
{
|
||||||
|
column = current_column();
|
||||||
|
}
|
||||||
|
err = std::make_unique<ParseError>(column, raw_text, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid error loops by skipping to the end
|
||||||
|
skip_to_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int current_column() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(current_iter - raw_text.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void go_to_begin()
|
||||||
|
{
|
||||||
|
current_iter = raw_text.begin();
|
||||||
|
current_char = (current_iter != raw_text.end() ? *current_iter : current_char);
|
||||||
|
|
||||||
|
if (current_char == ' ' || current_char == '\t')
|
||||||
|
{
|
||||||
|
next_skip_whitespace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void skip_to_end()
|
||||||
|
{
|
||||||
|
current_iter = raw_text.end();
|
||||||
|
current_char = '\0';
|
||||||
|
}
|
||||||
|
char current() const
|
||||||
|
{
|
||||||
|
return current_char;
|
||||||
|
}
|
||||||
|
char next()
|
||||||
|
{
|
||||||
|
if (current_char != '\0')
|
||||||
|
{
|
||||||
|
current_iter++;
|
||||||
|
current_char = (current_iter != raw_text.end() ? *current_iter : '\0');
|
||||||
|
}
|
||||||
|
return current();
|
||||||
|
}
|
||||||
|
void skip_whitespace()
|
||||||
|
{
|
||||||
|
while (current_char == ' ' || current_char == '\t')
|
||||||
|
{
|
||||||
|
current_char = next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char next_skip_whitespace()
|
||||||
|
{
|
||||||
|
next();
|
||||||
|
skip_whitespace();
|
||||||
|
return current_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_alphanum(char ch)
|
||||||
|
{
|
||||||
|
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool evaluate_identifier(const std::string name) const
|
||||||
|
{
|
||||||
|
return evaluation_context.find(name) != std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// identifier:
|
||||||
|
// alpha-numeric string of characters
|
||||||
|
bool identifier_expression()
|
||||||
|
{
|
||||||
|
auto curr = current();
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
for (curr = current(); is_alphanum(curr); curr = next())
|
||||||
|
{
|
||||||
|
name += curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.empty())
|
||||||
|
{
|
||||||
|
add_error("Invalid logic expression, unexpected character");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = evaluate_identifier(name);
|
||||||
|
skip_whitespace();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not-expression:
|
||||||
|
// ! primary-expression
|
||||||
|
// primary-expression
|
||||||
|
bool not_expression()
|
||||||
|
{
|
||||||
|
if (current() == '!')
|
||||||
|
{
|
||||||
|
next_skip_whitespace();
|
||||||
|
return !primary_expression();
|
||||||
|
}
|
||||||
|
|
||||||
|
return primary_expression();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <char oper, char other, bool operation(bool, bool)>
|
||||||
|
bool logic_expression_helper(bool seed)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Support chains of the operator to avoid breaking backwards compatability
|
||||||
|
while (next() == oper) {};
|
||||||
|
seed = operation(not_expression(), seed);
|
||||||
|
|
||||||
|
} while (current() == oper);
|
||||||
|
|
||||||
|
if (current() == other)
|
||||||
|
{
|
||||||
|
add_error("Mixing & and | is not allowed, Use () to specify order of operations.");
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_whitespace();
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
static bool and_helper(bool left, bool right)
|
||||||
|
{
|
||||||
|
return left && right;
|
||||||
|
}
|
||||||
|
static bool or_helper(bool left, bool right)
|
||||||
|
{
|
||||||
|
return left || right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// logic-expression: <- entry point
|
||||||
|
// not-expression
|
||||||
|
// not-expression | logic-expression
|
||||||
|
// not-expression & logic-expression
|
||||||
|
bool logic_expression()
|
||||||
|
{
|
||||||
|
auto result = not_expression();
|
||||||
|
|
||||||
|
switch (current())
|
||||||
|
{
|
||||||
|
case '|':
|
||||||
|
{
|
||||||
|
return logic_expression_helper< '|', '&', or_helper > (result);
|
||||||
|
}
|
||||||
|
case '&':
|
||||||
|
{
|
||||||
|
return logic_expression_helper< '&', '|', and_helper > (result);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// primary-expression:
|
||||||
|
// ( logic-expression )
|
||||||
|
// identifier
|
||||||
|
bool primary_expression()
|
||||||
|
{
|
||||||
|
if (current() == '(')
|
||||||
|
{
|
||||||
|
next_skip_whitespace();
|
||||||
|
bool result = logic_expression();
|
||||||
|
if (current() != ')')
|
||||||
|
{
|
||||||
|
add_error("Error: missing closing )");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
next_skip_whitespace();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return identifier_expression();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool evaluate_expression(const std::string& expression, const std::string& evaluation_context)
|
||||||
|
{
|
||||||
|
ExpressionParser parser(expression, evaluation_context);
|
||||||
|
|
||||||
|
return parser.get_result();
|
||||||
|
}
|
||||||
|
}
|
@ -116,7 +116,7 @@ namespace vcpkg::Paragraphs
|
|||||||
skip_spaces(ch);
|
skip_spaces(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_paragraph(char& ch, std::unordered_map<std::string, std::string>& fields)
|
void get_paragraph(char& ch, RawParagraph& fields)
|
||||||
{
|
{
|
||||||
fields.clear();
|
fields.clear();
|
||||||
std::string fieldname;
|
std::string fieldname;
|
||||||
@ -141,9 +141,9 @@ namespace vcpkg::Paragraphs
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<std::unordered_map<std::string, std::string>> get_paragraphs()
|
std::vector<RawParagraph> get_paragraphs()
|
||||||
{
|
{
|
||||||
std::vector<std::unordered_map<std::string, std::string>> paragraphs;
|
std::vector<RawParagraph> paragraphs;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
peek(ch);
|
peek(ch);
|
||||||
@ -164,7 +164,20 @@ namespace vcpkg::Paragraphs
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Expected<std::unordered_map<std::string, std::string>> get_single_paragraph(const Files::Filesystem& fs,
|
Expected<RawParagraph> parse_single_paragraph(const std::string& str)
|
||||||
|
{
|
||||||
|
const std::vector<RawParagraph> p =
|
||||||
|
Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
|
||||||
|
|
||||||
|
if (p.size() == 1)
|
||||||
|
{
|
||||||
|
return p.at(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::error_code(ParagraphParseResult::EXPECTED_ONE_PARAGRAPH);
|
||||||
|
}
|
||||||
|
|
||||||
|
Expected<RawParagraph> get_single_paragraph(const Files::Filesystem& fs,
|
||||||
const fs::path& control_path)
|
const fs::path& control_path)
|
||||||
{
|
{
|
||||||
const Expected<std::string> contents = fs.read_contents(control_path);
|
const Expected<std::string> contents = fs.read_contents(control_path);
|
||||||
@ -176,7 +189,7 @@ namespace vcpkg::Paragraphs
|
|||||||
return contents.error();
|
return contents.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<std::vector<std::unordered_map<std::string, std::string>>> get_paragraphs(const Files::Filesystem& fs,
|
Expected<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs,
|
||||||
const fs::path& control_path)
|
const fs::path& control_path)
|
||||||
{
|
{
|
||||||
const Expected<std::string> contents = fs.read_contents(control_path);
|
const Expected<std::string> contents = fs.read_contents(control_path);
|
||||||
@ -188,27 +201,14 @@ namespace vcpkg::Paragraphs
|
|||||||
return contents.error();
|
return contents.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<std::unordered_map<std::string, std::string>> parse_single_paragraph(const std::string& str)
|
Expected<std::vector<RawParagraph>> parse_paragraphs(const std::string& str)
|
||||||
{
|
|
||||||
const std::vector<std::unordered_map<std::string, std::string>> p =
|
|
||||||
Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
|
|
||||||
|
|
||||||
if (p.size() == 1)
|
|
||||||
{
|
|
||||||
return p.at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::error_code(ParagraphParseResult::EXPECTED_ONE_PARAGRAPH);
|
|
||||||
}
|
|
||||||
|
|
||||||
Expected<std::vector<std::unordered_map<std::string, std::string>>> parse_paragraphs(const std::string& str)
|
|
||||||
{
|
{
|
||||||
return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
|
return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path)
|
ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path)
|
||||||
{
|
{
|
||||||
Expected<std::vector<std::unordered_map<std::string, std::string>>> pghs = get_paragraphs(fs, path / "CONTROL");
|
Expected<std::vector<RawParagraph>> pghs = get_paragraphs(fs, path / "CONTROL");
|
||||||
if (auto vector_pghs = pghs.get())
|
if (auto vector_pghs = pghs.get())
|
||||||
{
|
{
|
||||||
return SourceControlFile::parse_control_file(std::move(*vector_pghs));
|
return SourceControlFile::parse_control_file(std::move(*vector_pghs));
|
||||||
@ -221,7 +221,7 @@ namespace vcpkg::Paragraphs
|
|||||||
|
|
||||||
Expected<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
|
Expected<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
|
||||||
{
|
{
|
||||||
Expected<std::vector<std::unordered_map<std::string, std::string>>> pghs =
|
Expected<std::vector<RawParagraph>> pghs =
|
||||||
get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL");
|
get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL");
|
||||||
|
|
||||||
if (auto p = pghs.get())
|
if (auto p = pghs.get())
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace vcpkg::Parse
|
namespace vcpkg::Parse
|
||||||
{
|
{
|
||||||
static Optional<std::string> remove_field(std::unordered_map<std::string, std::string>* fields,
|
static Optional<std::string> remove_field(RawParagraph* fields,
|
||||||
const std::string& fieldname)
|
const std::string& fieldname)
|
||||||
{
|
{
|
||||||
auto it = fields->find(fieldname);
|
auto it = fields->find(fieldname);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <vcpkg/packagespec.h>
|
#include <vcpkg/packagespec.h>
|
||||||
#include <vcpkg/sourceparagraph.h>
|
#include <vcpkg/sourceparagraph.h>
|
||||||
#include <vcpkg/triplet.h>
|
#include <vcpkg/triplet.h>
|
||||||
|
#include <vcpkg/logicexpression.h>
|
||||||
|
|
||||||
#include <vcpkg/base/checks.h>
|
#include <vcpkg/base/checks.h>
|
||||||
#include <vcpkg/base/expected.h>
|
#include <vcpkg/base/expected.h>
|
||||||
@ -142,7 +143,7 @@ namespace vcpkg
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParseExpected<SourceControlFile> SourceControlFile::parse_control_file(
|
ParseExpected<SourceControlFile> SourceControlFile::parse_control_file(
|
||||||
std::vector<std::unordered_map<std::string, std::string>>&& control_paragraphs)
|
std::vector<Parse::RawParagraph>&& control_paragraphs)
|
||||||
{
|
{
|
||||||
if (control_paragraphs.size() == 0)
|
if (control_paragraphs.size() == 0)
|
||||||
{
|
{
|
||||||
@ -222,18 +223,11 @@ namespace vcpkg
|
|||||||
std::vector<std::string> ret;
|
std::vector<std::string> ret;
|
||||||
for (auto&& dep : deps)
|
for (auto&& dep : deps)
|
||||||
{
|
{
|
||||||
auto qualifiers = Strings::split(dep.qualifier, "&");
|
const auto & qualifier = dep.qualifier;
|
||||||
if (std::all_of(qualifiers.begin(), qualifiers.end(), [&](const std::string& qualifier) {
|
if (qualifier.empty() || evaluate_expression(qualifier, t.canonical_name()))
|
||||||
if (qualifier.empty()) return true;
|
{
|
||||||
if (qualifier[0] == '!')
|
ret.emplace_back(dep.name());
|
||||||
{
|
}
|
||||||
return t.canonical_name().find(qualifier.substr(1)) == std::string::npos;
|
|
||||||
}
|
|
||||||
return t.canonical_name().find(qualifier) != std::string::npos;
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
ret.emplace_back(dep.name());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -244,18 +238,11 @@ namespace vcpkg
|
|||||||
std::vector<Features> ret;
|
std::vector<Features> ret;
|
||||||
for (auto&& dep : deps)
|
for (auto&& dep : deps)
|
||||||
{
|
{
|
||||||
auto qualifiers = Strings::split(dep.qualifier, "&");
|
const auto & qualifier = dep.qualifier;
|
||||||
if (std::all_of(qualifiers.begin(), qualifiers.end(), [&](const std::string& qualifier) {
|
if (qualifier.empty() || evaluate_expression(qualifier, t.canonical_name()))
|
||||||
if (qualifier.empty()) return true;
|
{
|
||||||
if (qualifier[0] == '!')
|
ret.emplace_back(dep.depend);
|
||||||
{
|
}
|
||||||
return t.canonical_name().find(qualifier.substr(1)) == std::string::npos;
|
|
||||||
}
|
|
||||||
return t.canonical_name().find(qualifier) != std::string::npos;
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
ret.emplace_back(dep.depend);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace vcpkg
|
|||||||
.push_back('\n');
|
.push_back('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusParagraph::StatusParagraph(std::unordered_map<std::string, std::string>&& fields)
|
StatusParagraph::StatusParagraph(Parse::RawParagraph&& fields)
|
||||||
: want(Want::ERROR_STATE), state(InstallState::ERROR_STATE)
|
: want(Want::ERROR_STATE), state(InstallState::ERROR_STATE)
|
||||||
{
|
{
|
||||||
auto status_it = fields.find(BinaryParagraphRequiredField::STATUS);
|
auto status_it = fields.find(BinaryParagraphRequiredField::STATUS);
|
||||||
|
@ -51,7 +51,7 @@ namespace vcpkg
|
|||||||
{
|
{
|
||||||
const auto& pghs = *p_pghs;
|
const auto& pghs = *p_pghs;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> keys;
|
Parse::RawParagraph keys;
|
||||||
if (pghs.size() > 0) keys = pghs[0];
|
if (pghs.size() > 0) keys = pghs[0];
|
||||||
|
|
||||||
for (size_t x = 1; x < pghs.size(); ++x)
|
for (size_t x = 1; x < pghs.size(); ++x)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.25420.1
|
VisualStudioVersion = 14.0.25420.1
|
||||||
|
@ -249,6 +249,7 @@
|
|||||||
<ClCompile Include="..\src\vcpkg\help.cpp" />
|
<ClCompile Include="..\src\vcpkg\help.cpp" />
|
||||||
<ClCompile Include="..\src\vcpkg\input.cpp" />
|
<ClCompile Include="..\src\vcpkg\input.cpp" />
|
||||||
<ClCompile Include="..\src\vcpkg\install.cpp" />
|
<ClCompile Include="..\src\vcpkg\install.cpp" />
|
||||||
|
<ClCompile Include="..\src\vcpkg\logicexpression.cpp" />
|
||||||
<ClCompile Include="..\src\vcpkg\metrics.cpp" />
|
<ClCompile Include="..\src\vcpkg\metrics.cpp" />
|
||||||
<ClCompile Include="..\src\vcpkg\packagespec.cpp" />
|
<ClCompile Include="..\src\vcpkg\packagespec.cpp" />
|
||||||
<ClCompile Include="..\src\vcpkg\packagespecparseresult.cpp" />
|
<ClCompile Include="..\src\vcpkg\packagespecparseresult.cpp" />
|
||||||
|
@ -108,6 +108,9 @@
|
|||||||
<ClCompile Include="..\src\vcpkg\install.cpp">
|
<ClCompile Include="..\src\vcpkg\install.cpp">
|
||||||
<Filter>Source Files\vcpkg</Filter>
|
<Filter>Source Files\vcpkg</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\vcpkg\logicexpression.cpp">
|
||||||
|
<Filter>Source Files\vcpkg</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\src\vcpkg\metrics.cpp">
|
<ClCompile Include="..\src\vcpkg\metrics.cpp">
|
||||||
<Filter>Source Files\vcpkg</Filter>
|
<Filter>Source Files\vcpkg</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user