Reworked panic structuring (now has overloadable handler.) Started work on out-of-place shuffler. Started work on progress-bar. Fortune for shuffle3's current commit: Great curse − 大凶progress
parent
3e3b5d1cf6
commit
ecf72a7526
@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#error "C++ header only"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace pr {
|
||||||
|
|
||||||
|
namespace details [[gnu::visibility("inernal")]]{
|
||||||
|
template<typename T>
|
||||||
|
T* take(T*& ptr) noexcept { return std::exchange(ptr, nullptr); }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar {
|
||||||
|
Bar() noexcept = default;
|
||||||
|
Bar(const Bar&) noexcept = default;
|
||||||
|
Bar(Bar&&) noexcept = default;
|
||||||
|
Bar& operator=(const Bar&) noexcept = default;
|
||||||
|
Bar& operator=(Bar&&) noexcept = default;
|
||||||
|
virtual ~Bar() = default;
|
||||||
|
|
||||||
|
virtual void spin(int) =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bar_kind {
|
||||||
|
BRK_UNTRACKED,
|
||||||
|
BRK_TRACKED,
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bar_kind = BRK_UNTRACKED>
|
||||||
|
struct progress;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct progress<BRK_UNTRACKED>
|
||||||
|
: public virtual Bar {
|
||||||
|
|
||||||
|
progress(FILE* to);
|
||||||
|
progress(progress const&);
|
||||||
|
inline progress(progress&& mv) noexcept
|
||||||
|
: Bar()
|
||||||
|
, _perc(mv._perc)
|
||||||
|
, _output(details::take(mv._output)) {}
|
||||||
|
|
||||||
|
virtual ~progress();
|
||||||
|
|
||||||
|
void spin(int) override;
|
||||||
|
|
||||||
|
//TODO: this
|
||||||
|
protected:
|
||||||
|
union {
|
||||||
|
double _perc;
|
||||||
|
size_t _num; // not used here
|
||||||
|
};
|
||||||
|
FILE* _output;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class progress<BRK_TRACKED>
|
||||||
|
: public progress<BRK_UNTRACKED> {
|
||||||
|
using base_t = progress<BRK_UNTRACKED>;
|
||||||
|
public:
|
||||||
|
inline progress(FILE* to, size_t max) : base_t(to), _num(0), _max(max) {}
|
||||||
|
progress(const progress&) = default;
|
||||||
|
progress(progress&& m) : base_t(std::move(m)), _num(std::exchange(m._num, 0)), _max(m._max) {}
|
||||||
|
|
||||||
|
void spin(int) override;
|
||||||
|
//TODO: this
|
||||||
|
|
||||||
|
virtual ~progress() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using base_t::_output;
|
||||||
|
private:
|
||||||
|
using base_t::_num;
|
||||||
|
size_t _max;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <panic.h>
|
||||||
|
#include <map.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr inline auto MEMFD_DEFAULT_FLAGS = MFD_CLOEXEC;
|
||||||
|
int memfd_alloc(const char* name, size_t size = 0, int flags = MEMFD_DEFAULT_FLAGS)
|
||||||
|
{
|
||||||
|
int fd = memfd_create(name, flags);
|
||||||
|
if(fd < 0) panic("memfd_create() failed");
|
||||||
|
if(size)
|
||||||
|
if(ftruncate(fd, size)) { close(fd); panic("ftruncate() failed"); }
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mm {
|
||||||
|
vmap::vmap()
|
||||||
|
: mmap(create_raw_fd(memfd_alloc(__PRETTY_FUNCTION__))) {}
|
||||||
|
vmap::vmap(size_t sz)
|
||||||
|
: mmap(create_raw_fd(memfd_alloc(__PRETTY_FUNCTION__, sz))) {}
|
||||||
|
|
||||||
|
}
|
@ -1,18 +1,41 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <panic.h>
|
#include <panic.h>
|
||||||
|
|
||||||
#include <colours.h>
|
#include <colours.h>
|
||||||
|
|
||||||
__attribute__((noreturn)) void _do_panic(struct panicinfo info, const char* fmt, ...)
|
#ifndef DEFAULT_PANIC_HANDLER
|
||||||
|
#if __cpp_exceptions || 1 /* XXX: Cannot detect this here */
|
||||||
|
# define DEFAULT_PANIC_HANDLER "_panic__start_unwind_cxx"
|
||||||
|
#else
|
||||||
|
# define DEFAULT_PANIC_HANDLER "_panic__start_unwind_abort"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern void _panic__start_unwind_cxx(void);
|
||||||
|
static void _panic__start_unwind_abort(void*)
|
||||||
|
__attribute__((weakref("abort"), noreturn));
|
||||||
|
|
||||||
|
static void _panic__start_unwind(void* payload)
|
||||||
|
__attribute__((noreturn, weakref(DEFAULT_PANIC_HANDLER)));
|
||||||
|
|
||||||
|
__attribute__((noreturn, weak)) void _do_panic(struct panicinfo info, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list li;
|
va_list li;
|
||||||
va_start(li, fmt);
|
va_start(li, fmt);
|
||||||
fprintf(stderr, BOLD(UNDL(FRED("[!]"))) " (" BOLD("%s") "->" BOLD(FRED("%s")) ":" FYEL("%d") ") " BOLD(FRED("fatal error")) ": ", info.file, info.function, info.line);
|
#define FMT_TTY BOLD(UNDL(FRED("[!]"))) " (" BOLD("%s") "->" BOLD(FRED("%s")) ":" FYEL("%d") ") " BOLD(FRED("fatal error")) ": "
|
||||||
|
#define FMT_FIL "[!]" " (" "%s" "->" "%s" ":" "%d" ") " "fatal error" ": "
|
||||||
|
fprintf(stderr, isatty(fileno(stderr))
|
||||||
|
? FMT_TTY
|
||||||
|
: FMT_FIL , info.file, info.function, info.line);
|
||||||
vfprintf(stderr, fmt, li);
|
vfprintf(stderr, fmt, li);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
va_end(li);
|
va_end(li);
|
||||||
abort();
|
|
||||||
|
_panic__start_unwind(&info);
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
struct ErrorPayload {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FatalError {
|
||||||
|
FatalError(void* payload)
|
||||||
|
: payload(payload) {}
|
||||||
|
FatalError(FatalError&& m)
|
||||||
|
: payload(std::exchange(m.payload, nullptr)) {}
|
||||||
|
|
||||||
|
FatalError& operator=(FatalError&& m)
|
||||||
|
{
|
||||||
|
if(this != &m) {
|
||||||
|
if(payload) destroy();
|
||||||
|
payload = std::exchange(m.payload, nullptr);
|
||||||
|
} return *this;
|
||||||
|
}
|
||||||
|
virtual ~FatalError() noexcept {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual void destroy() noexcept
|
||||||
|
{
|
||||||
|
/*if(auto* p = dynamic_cast<ErrorPayload*>(payload))
|
||||||
|
delete p;*/
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
void* payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
[[noreturn, gnu::weak]]
|
||||||
|
void _panic__start_unwind_cxx(void* payload)
|
||||||
|
{
|
||||||
|
#if __EXCEPTIONS
|
||||||
|
throw FatalError(payload);
|
||||||
|
#else
|
||||||
|
::abort();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue