mirror of
https://github.com/NixOS/nix
synced 2025-06-30 03:23:16 +02:00
Merge remote-tracking branch 'origin/master' into flakes
This commit is contained in:
commit
ecb3a1afa2
119 changed files with 3905 additions and 2250 deletions
|
@ -1,12 +1,18 @@
|
|||
#include "logging.hh"
|
||||
#include "rust-ffi.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
extern "C" std::exception_ptr * make_error(rust::StringSlice s)
|
||||
{
|
||||
// FIXME: leak
|
||||
return new std::exception_ptr(std::make_exception_ptr(Error(std::string(s.ptr, s.size))));
|
||||
return new std::exception_ptr(std::make_exception_ptr(nix::Error(std::string(s.ptr, s.size))));
|
||||
}
|
||||
|
||||
namespace rust {
|
||||
|
||||
std::ostream & operator << (std::ostream & str, const String & s)
|
||||
{
|
||||
str << (std::string_view) s;
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,91 @@
|
|||
#pragma once
|
||||
|
||||
#include "serialise.hh"
|
||||
|
||||
#include <string_view>
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
|
||||
namespace rust {
|
||||
|
||||
// Depending on the internal representation of Rust slices is slightly
|
||||
// evil...
|
||||
typedef void (*DropFun)(void *);
|
||||
|
||||
/* A Rust value of N bytes. It can be moved but not copied. When it
|
||||
goes out of scope, the C++ destructor will run the drop
|
||||
function. */
|
||||
template<std::size_t N, DropFun drop>
|
||||
struct Value
|
||||
{
|
||||
protected:
|
||||
|
||||
std::array<char, N> raw;
|
||||
|
||||
~Value()
|
||||
{
|
||||
if (!isEvacuated()) {
|
||||
drop(this);
|
||||
evacuate();
|
||||
}
|
||||
}
|
||||
|
||||
// Must not be called directly.
|
||||
Value()
|
||||
{ }
|
||||
|
||||
Value(Value && other)
|
||||
: raw(other.raw)
|
||||
{
|
||||
other.evacuate();
|
||||
}
|
||||
|
||||
void operator =(Value && other)
|
||||
{
|
||||
if (!isEvacuated())
|
||||
drop(this);
|
||||
raw = other.raw;
|
||||
other.evacuate();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/* FIXME: optimize these (ideally in such a way that the compiler
|
||||
can elide most calls to evacuate() / isEvacuated(). */
|
||||
inline void evacuate()
|
||||
{
|
||||
for (auto & i : raw) i = 0;
|
||||
}
|
||||
|
||||
inline bool isEvacuated()
|
||||
{
|
||||
for (auto & i : raw)
|
||||
if (i != 0) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/* A Rust vector. */
|
||||
template<typename T, DropFun drop>
|
||||
struct Vec : Value<3 * sizeof(void *), drop>
|
||||
{
|
||||
inline size_t size() const
|
||||
{
|
||||
return ((const size_t *) &this->raw)[2];
|
||||
}
|
||||
|
||||
const T * data() const
|
||||
{
|
||||
return ((const T * *) &this->raw)[0];
|
||||
}
|
||||
};
|
||||
|
||||
/* A Rust slice. */
|
||||
template<typename T>
|
||||
struct Slice
|
||||
{
|
||||
T * ptr;
|
||||
const T * ptr;
|
||||
size_t size;
|
||||
|
||||
Slice(T * ptr, size_t size) : ptr(ptr), size(size)
|
||||
Slice(const T * ptr, size_t size) : ptr(ptr), size(size)
|
||||
{
|
||||
assert(ptr);
|
||||
}
|
||||
|
@ -18,9 +93,44 @@ struct Slice
|
|||
|
||||
struct StringSlice : Slice<char>
|
||||
{
|
||||
StringSlice(const std::string & s): Slice((char *) s.data(), s.size()) {}
|
||||
StringSlice(const std::string & s): Slice(s.data(), s.size()) {}
|
||||
explicit StringSlice(std::string_view s): Slice(s.data(), s.size()) {}
|
||||
StringSlice(const char * s): Slice(s, strlen(s)) {}
|
||||
|
||||
operator std::string_view() const
|
||||
{
|
||||
return std::string_view(ptr, size);
|
||||
}
|
||||
};
|
||||
|
||||
/* A Rust string. */
|
||||
struct String;
|
||||
|
||||
extern "C" {
|
||||
void ffi_String_new(StringSlice s, String * out);
|
||||
void ffi_String_drop(void * s);
|
||||
}
|
||||
|
||||
struct String : Vec<char, ffi_String_drop>
|
||||
{
|
||||
String(std::string_view s)
|
||||
{
|
||||
ffi_String_new(StringSlice(s), this);
|
||||
}
|
||||
|
||||
String(const char * s)
|
||||
: String({s, std::strlen(s)})
|
||||
{
|
||||
}
|
||||
|
||||
operator std::string_view() const
|
||||
{
|
||||
return std::string_view(data(), size());
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream & operator << (std::ostream & str, const String & s);
|
||||
|
||||
struct Source
|
||||
{
|
||||
size_t (*fun)(void * source_this, rust::Slice<uint8_t> data);
|
||||
|
@ -33,7 +143,7 @@ struct Source
|
|||
// FIXME: how to propagate exceptions?
|
||||
static size_t sourceWrapper(void * _this, rust::Slice<uint8_t> data)
|
||||
{
|
||||
auto n = ((nix::Source *) _this)->read(data.ptr, data.size);
|
||||
auto n = ((nix::Source *) _this)->read((unsigned char *) data.ptr, data.size);
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
@ -49,11 +159,20 @@ struct Result
|
|||
std::exception_ptr * exc;
|
||||
};
|
||||
|
||||
~Result()
|
||||
{
|
||||
if (tag == 0)
|
||||
data.~T();
|
||||
else if (tag == 1)
|
||||
// FIXME: don't leak exc
|
||||
;
|
||||
}
|
||||
|
||||
/* Rethrow the wrapped exception or return the wrapped value. */
|
||||
T unwrap()
|
||||
{
|
||||
if (tag == 0)
|
||||
return data;
|
||||
return std::move(data);
|
||||
else if (tag == 1)
|
||||
std::rethrow_exception(*exc);
|
||||
else
|
||||
|
|
|
@ -17,7 +17,7 @@ void unpackTarfile(Source & source, const Path & destDir)
|
|||
void unpackTarfile(const Path & tarFile, const Path & destDir,
|
||||
std::optional<std::string> baseName)
|
||||
{
|
||||
if (!baseName) baseName = baseNameOf(tarFile);
|
||||
if (!baseName) baseName = std::string(baseNameOf(tarFile));
|
||||
|
||||
auto source = sinkToSource([&](Sink & sink) {
|
||||
// FIXME: look at first few bytes to determine compression type.
|
||||
|
|
|
@ -189,22 +189,22 @@ Path dirOf(const Path & path)
|
|||
}
|
||||
|
||||
|
||||
string baseNameOf(const Path & path)
|
||||
std::string_view baseNameOf(std::string_view path)
|
||||
{
|
||||
if (path.empty())
|
||||
return "";
|
||||
|
||||
Path::size_type last = path.length() - 1;
|
||||
auto last = path.size() - 1;
|
||||
if (path[last] == '/' && last > 0)
|
||||
last -= 1;
|
||||
|
||||
Path::size_type pos = path.rfind('/', last);
|
||||
auto pos = path.rfind('/', last);
|
||||
if (pos == string::npos)
|
||||
pos = 0;
|
||||
else
|
||||
pos += 1;
|
||||
|
||||
return string(path, pos, last - pos + 1);
|
||||
return path.substr(pos, last - pos + 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1307,9 +1307,10 @@ bool hasPrefix(const string & s, const string & prefix)
|
|||
}
|
||||
|
||||
|
||||
bool hasSuffix(const string & s, const string & suffix)
|
||||
bool hasSuffix(std::string_view s, std::string_view suffix)
|
||||
{
|
||||
return s.size() >= suffix.size() && string(s, s.size() - suffix.size()) == suffix;
|
||||
return s.size() >= suffix.size()
|
||||
&& s.substr(s.size() - suffix.size()) == suffix;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ Path dirOf(const Path & path);
|
|||
|
||||
/* Return the base name of the given canonical path, i.e., everything
|
||||
following the final `/'. */
|
||||
string baseNameOf(const Path & path);
|
||||
std::string_view baseNameOf(std::string_view path);
|
||||
|
||||
/* Check whether 'path' is a descendant of 'dir'. */
|
||||
bool isInDir(const Path & path, const Path & dir);
|
||||
|
@ -431,7 +431,7 @@ bool hasPrefix(const string & s, const string & prefix);
|
|||
|
||||
|
||||
/* Return true iff `s' ends in `suffix'. */
|
||||
bool hasSuffix(const string & s, const string & suffix);
|
||||
bool hasSuffix(std::string_view s, std::string_view suffix);
|
||||
|
||||
|
||||
/* Convert a string to lower case. */
|
||||
|
@ -474,10 +474,10 @@ string base64Decode(const string & s);
|
|||
/* Get a value for the specified key from an associate container, or a
|
||||
default value if the key doesn't exist. */
|
||||
template <class T>
|
||||
string get(const T & map, const string & key, const string & def = "")
|
||||
std::optional<std::string> get(const T & map, const std::string & key)
|
||||
{
|
||||
auto i = map.find(key);
|
||||
return i == map.end() ? def : i->second;
|
||||
return i == map.end() ? std::optional<std::string>() : i->second;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue