mirror of
https://github.com/matrix-construct/construct
synced 2025-03-13 21:10:32 +01:00
ircd::magick: Start a central header; add interface support infrastructure.
This commit is contained in:
parent
582cecccec
commit
16f6fbc352
3 changed files with 211 additions and 7 deletions
|
@ -62,6 +62,7 @@
|
|||
#include "m/m.h"
|
||||
#include "resource/resource.h"
|
||||
#include "client.h"
|
||||
#include "magick.h"
|
||||
|
||||
/// \brief Internet Relay Chat daemon. This is the principal namespace for IRCd.
|
||||
///
|
||||
|
|
20
include/ircd/magick.h
Normal file
20
include/ircd/magick.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_MAGICK_H
|
||||
|
||||
/// GraphicsMagick Library Interface
|
||||
namespace ircd::magick
|
||||
{
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
|
||||
std::tuple<ulong, string_view> version();
|
||||
}
|
|
@ -12,8 +12,20 @@
|
|||
|
||||
namespace ircd::magick
|
||||
{
|
||||
static void handle_exception(const ::ExceptionType, const char *, const char *);
|
||||
static void handle_fatal(const ::ExceptionType, const char *, const char *) noexcept;
|
||||
static void handle_error(const ::ExceptionType, const char *, const char *) noexcept;
|
||||
static void handle_warning(const ::ExceptionType, const char *, const char *) noexcept;
|
||||
static void handle_log(const ::ExceptionType, const char *) noexcept;
|
||||
|
||||
template<class R, class F, class... A> static R call(F&&, A&&...);
|
||||
template<class R, class F, class... A> static R callex(F&&, A&&...);
|
||||
template<class F, class... A> static void callpf(F&&, A&&...);
|
||||
|
||||
static void init();
|
||||
static void fini();
|
||||
|
||||
extern log::log log;
|
||||
}
|
||||
|
||||
ircd::mapi::header
|
||||
|
@ -24,6 +36,12 @@ IRCD_MODULE
|
|||
ircd::magick::fini
|
||||
};
|
||||
|
||||
decltype(ircd::magick::log)
|
||||
ircd::magick::log
|
||||
{
|
||||
"magick"
|
||||
};
|
||||
|
||||
//
|
||||
// init
|
||||
//
|
||||
|
@ -31,10 +49,9 @@ IRCD_MODULE
|
|||
void
|
||||
ircd::magick::init()
|
||||
{
|
||||
ulong lib_version(0);
|
||||
const char *const lib_version_text
|
||||
const auto version
|
||||
{
|
||||
::GetMagickVersion(&lib_version)
|
||||
magick::version()
|
||||
};
|
||||
|
||||
log::debug
|
||||
|
@ -42,19 +59,20 @@ ircd::magick::init()
|
|||
"Initializing Magick Library include:%lu [%s] library:%lu [%s]",
|
||||
ulong(MagickLibVersion),
|
||||
MagickLibVersionText,
|
||||
lib_version,
|
||||
lib_version_text,
|
||||
std::get<0>(version),
|
||||
std::get<1>(version),
|
||||
};
|
||||
|
||||
if(lib_version != ulong(MagickLibVersion))
|
||||
if(std::get<0>(version) != ulong(MagickLibVersion))
|
||||
log::warning
|
||||
{
|
||||
"Magick Library version mismatch headers:%lu library:%lu",
|
||||
ulong(MagickLibVersion),
|
||||
lib_version,
|
||||
std::get<0>(version),
|
||||
};
|
||||
|
||||
::InitializeMagick(nullptr);
|
||||
::SetLogMethod(handle_log); //XXX assuming global
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -67,3 +85,168 @@ ircd::magick::fini()
|
|||
|
||||
::DestroyMagick();
|
||||
}
|
||||
|
||||
std::tuple<ulong, ircd::string_view>
|
||||
ircd::magick::version()
|
||||
{
|
||||
ulong number(0);
|
||||
const char *const string
|
||||
{
|
||||
::GetMagickVersion(&number)
|
||||
};
|
||||
|
||||
return { number, string };
|
||||
}
|
||||
|
||||
//
|
||||
// util
|
||||
//
|
||||
|
||||
template<class return_t,
|
||||
class function,
|
||||
class... args>
|
||||
return_t
|
||||
ircd::magick::callex(function&& f,
|
||||
args&&... a)
|
||||
{
|
||||
const auto warning_handler(::SetWarningHandler(handle_warning));
|
||||
const auto fatal_handler(::SetFatalErrorHandler(handle_fatal));
|
||||
const auto error_handler(::SetErrorHandler(handle_exception));
|
||||
const unwind reset{[&]
|
||||
{
|
||||
::SetFatalErrorHandler(fatal_handler);
|
||||
::SetErrorHandler(error_handler);
|
||||
::SetWarningHandler(warning_handler);
|
||||
}};
|
||||
|
||||
::ExceptionInfo ei;
|
||||
GetExceptionInfo(&ei); // initializer
|
||||
const unwind destroy{[&ei]
|
||||
{
|
||||
::DestroyExceptionInfo(&ei);
|
||||
}};
|
||||
|
||||
const auto ret
|
||||
{
|
||||
f(std::forward<args>(a)..., &ei)
|
||||
};
|
||||
|
||||
// exception comes out of here; if this is not safe we'll have to
|
||||
// convey with a global or inspect ExceptionInfo manually.
|
||||
::CatchException(&ei);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class function,
|
||||
class... args>
|
||||
void
|
||||
ircd::magick::callpf(function&& f,
|
||||
args&&... a)
|
||||
{
|
||||
const auto warning_handler(::SetWarningHandler(handle_warning));
|
||||
const auto fatal_handler(::SetFatalErrorHandler(handle_fatal));
|
||||
const auto error_handler(::SetErrorHandler(handle_error));
|
||||
const unwind reset{[&]
|
||||
{
|
||||
::SetFatalErrorHandler(fatal_handler);
|
||||
::SetErrorHandler(error_handler);
|
||||
::SetWarningHandler(warning_handler);
|
||||
}};
|
||||
|
||||
if(!call(f, std::forward<args>(a)...))
|
||||
throw error{};
|
||||
}
|
||||
|
||||
template<class return_t,
|
||||
class function,
|
||||
class... args>
|
||||
return_t
|
||||
ircd::magick::call(function&& f,
|
||||
args&&... a)
|
||||
{
|
||||
const auto warning_handler(::SetWarningHandler(handle_warning));
|
||||
const auto fatal_handler(::SetFatalErrorHandler(handle_fatal));
|
||||
const auto error_handler(::SetErrorHandler(handle_error));
|
||||
const unwind reset{[&]
|
||||
{
|
||||
::SetFatalErrorHandler(fatal_handler);
|
||||
::SetErrorHandler(error_handler);
|
||||
::SetWarningHandler(warning_handler);
|
||||
}};
|
||||
|
||||
return f(std::forward<args>(a)...);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::magick::handle_log(const ::ExceptionType type,
|
||||
const char *const message)
|
||||
noexcept
|
||||
{
|
||||
log::debug
|
||||
{
|
||||
log, "%s :%s",
|
||||
::GetLocaleExceptionMessage(type, nullptr),
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::magick::handle_warning(const ::ExceptionType type,
|
||||
const char *const reason,
|
||||
const char *const description)
|
||||
noexcept
|
||||
{
|
||||
log::warning
|
||||
{
|
||||
log, "%s %s :%s",
|
||||
::GetLocaleExceptionMessage(type, nullptr),
|
||||
reason,
|
||||
description
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::magick::handle_error(const ::ExceptionType type,
|
||||
const char *const reason,
|
||||
const char *const description)
|
||||
noexcept
|
||||
{
|
||||
log::error
|
||||
{
|
||||
log, "%s %s :%s",
|
||||
::GetLocaleExceptionMessage(type, nullptr),
|
||||
reason,
|
||||
description
|
||||
};
|
||||
}
|
||||
|
||||
[[noreturn]] void
|
||||
ircd::magick::handle_fatal(const ::ExceptionType type,
|
||||
const char *const reason,
|
||||
const char *const description)
|
||||
noexcept
|
||||
{
|
||||
log::critical
|
||||
{
|
||||
log, "%s %s :%s",
|
||||
::GetLocaleExceptionMessage(type, nullptr),
|
||||
reason,
|
||||
description
|
||||
};
|
||||
|
||||
ircd::terminate();
|
||||
}
|
||||
|
||||
[[noreturn]] void
|
||||
ircd::magick::handle_exception(const ::ExceptionType type,
|
||||
const char *const reason,
|
||||
const char *const description)
|
||||
{
|
||||
throw error
|
||||
{
|
||||
"%s %s :%s",
|
||||
::GetLocaleExceptionMessage(type, nullptr),
|
||||
reason,
|
||||
description
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue