mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 23:44:01 +01:00
Add root exception + basic utilities.
This commit is contained in:
parent
73297c988b
commit
625fb277ca
6 changed files with 251 additions and 4 deletions
127
include/ircd/exception.h
Normal file
127
include/ircd/exception.h
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* charybdis: 21st Century IRCd
|
||||||
|
* exception.h: Exception root
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Charybdis Development Team
|
||||||
|
* Copyright (C) 2016 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_EXCEPTION_H
|
||||||
|
|
||||||
|
#include "stdinc.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace ircd {
|
||||||
|
|
||||||
|
|
||||||
|
IRCD_OVERLOAD(pass_name)
|
||||||
|
|
||||||
|
/** The root exception type.
|
||||||
|
*
|
||||||
|
* All exceptions in the project inherit from this type.
|
||||||
|
* To catch any exception from a project developer's code:
|
||||||
|
* catch(const ircd::exception &) {}
|
||||||
|
*
|
||||||
|
* Remember: not all exceptions are from project developer's code,
|
||||||
|
* such as std::out_of_range. In most contexts if you have to deal with this
|
||||||
|
* someone else was lazy, which is bad. To be sure and catch any exception:
|
||||||
|
* catch(const std::exception &) {}
|
||||||
|
*
|
||||||
|
* Remember: not all exceptions have to inherit from std::exception, but
|
||||||
|
* those are rogue exceptions. We do not allow this. To be sure nothing
|
||||||
|
* can possibly get through, add to the bottom:
|
||||||
|
* catch(...) {}
|
||||||
|
*
|
||||||
|
* Note: Prefer 'noexcept' instead of catch(...), noexcept is like an 'assert'
|
||||||
|
* for exceptions, and the rogue can be found-out in testing.
|
||||||
|
*/
|
||||||
|
struct exception
|
||||||
|
:std::exception
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
const char *what() const noexcept override { return buf; }
|
||||||
|
|
||||||
|
exception(const pass_name_t, const char *const &name = "exception", const char *fmt = " ", ...) noexcept AFP(4, 5);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Disambiguates the constructors in the macro below.
|
||||||
|
|
||||||
|
/** Exception generator convenience macro
|
||||||
|
*
|
||||||
|
* If you want to create your own exception type, you have found the right
|
||||||
|
* place! This macro allows creating an exception in the the hierarchy.
|
||||||
|
*
|
||||||
|
* To create an exception, invoke this macro in your header. Examples:
|
||||||
|
*
|
||||||
|
* IRCD_EXCEPTION(ircd::exception, my_exception)
|
||||||
|
* IRCD_EXCEPTION(my_exception, my_specific_exception)
|
||||||
|
*
|
||||||
|
* Then your catch sequence can look like the following:
|
||||||
|
*
|
||||||
|
* catch(const my_specific_exception &e)
|
||||||
|
* {
|
||||||
|
* log("something specifically bad happened: %s", e.what());
|
||||||
|
* }
|
||||||
|
* catch(const my_exception &e)
|
||||||
|
* {
|
||||||
|
* log("something generically bad happened: %s", e.what());
|
||||||
|
* }
|
||||||
|
* catch(const ircd::exception &e)
|
||||||
|
* {
|
||||||
|
* log("unrelated bad happened: %s", e.what());
|
||||||
|
* }
|
||||||
|
* catch(const std::exception &e)
|
||||||
|
* {
|
||||||
|
* log("unhandled bad happened: %s", e.what());
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Remember: the order of the catch blocks is important.
|
||||||
|
*/
|
||||||
|
#define IRCD_EXCEPTION(parent, name) \
|
||||||
|
struct name \
|
||||||
|
:parent \
|
||||||
|
{ \
|
||||||
|
template<class... A> \
|
||||||
|
name(const pass_name_t &, A&&... a): \
|
||||||
|
parent { pass_name, std::forward<A>(a)... } {} \
|
||||||
|
\
|
||||||
|
template<class... A> \
|
||||||
|
name(A&&... a): \
|
||||||
|
parent { pass_name, #name, std::forward<A>(a)... } {} \
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Generic base exceptions.
|
||||||
|
* List your own exception somewhere else (unless you're overhauling libircd).
|
||||||
|
*
|
||||||
|
* These are useful for random places and spare you the effort of having to
|
||||||
|
* redefine them. You can also inherit from these if appropriate.
|
||||||
|
*/
|
||||||
|
IRCD_EXCEPTION(exception, error) // throw ircd::error("something bad")
|
||||||
|
IRCD_EXCEPTION(error, not_found) // throw ircd::not_found("looks like a 404")
|
||||||
|
IRCD_EXCEPTION(error, access_denied) // throw ircd::access_denied("you didn't say the magic word")
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace ircd
|
||||||
|
#endif // __cplusplus
|
|
@ -22,10 +22,14 @@
|
||||||
* USA
|
* USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _IRCD_H
|
#pragma once
|
||||||
#define _IRCD_H
|
#define HAVE_IRCD_H
|
||||||
|
|
||||||
#include "defaults.h"
|
#include "stdinc.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "exception.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
struct Client;
|
struct Client;
|
||||||
|
|
||||||
|
@ -104,4 +108,4 @@ extern int maxconnections;
|
||||||
|
|
||||||
void ircd_shutdown(const char *reason) __attribute__((noreturn));
|
void ircd_shutdown(const char *reason) __attribute__((noreturn));
|
||||||
|
|
||||||
#endif // _IRCD_H
|
#endif // __cplusplus
|
||||||
|
|
65
include/ircd/util.h
Normal file
65
include/ircd/util.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* charybdis: 21st Century IRC++d
|
||||||
|
* util.h: Miscellaneous utilities
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Charybdis Development Team
|
||||||
|
* Copyright (C) 2016 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_UTIL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace ircd {
|
||||||
|
inline namespace util {
|
||||||
|
|
||||||
|
|
||||||
|
#define IRCD_EXPCAT(a, b) a ## b
|
||||||
|
#define IRCD_CONCAT(a, b) IRCD_EXPCAT(a, b)
|
||||||
|
#define IRCD_UNIQUE(a) IRCD_CONCAT(a, __COUNTER__)
|
||||||
|
|
||||||
|
|
||||||
|
#define IRCD_OVERLOAD(NAME) \
|
||||||
|
struct NAME##_t {}; \
|
||||||
|
static constexpr NAME##_t NAME {};
|
||||||
|
|
||||||
|
|
||||||
|
#define IRCD_STRONG_TYPEDEF(TYPE, NAME) \
|
||||||
|
struct NAME \
|
||||||
|
{ \
|
||||||
|
TYPE val; \
|
||||||
|
\
|
||||||
|
operator const TYPE &() const { return val; } \
|
||||||
|
operator TYPE &() { return val; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ex: using foo_t = IRCD_STRONG_T(int)
|
||||||
|
#define IRCD_STRONG_T(TYPE) \
|
||||||
|
IRCD_STRONG_TYPEDEF(TYPE, IRCD_UNIQUE(strong_t))
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using custom_ptr = std::unique_ptr<T, std::function<void (T *)>>;
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
|
} // namespace ircd
|
||||||
|
#endif // __cplusplus
|
|
@ -48,6 +48,7 @@ libircd_la_SOURCES = \
|
||||||
class.cc \
|
class.cc \
|
||||||
client.cc \
|
client.cc \
|
||||||
dns.cc \
|
dns.cc \
|
||||||
|
exception.cc \
|
||||||
extban.cc \
|
extban.cc \
|
||||||
fs.cc \
|
fs.cc \
|
||||||
getopt.cc \
|
getopt.cc \
|
||||||
|
|
48
ircd/exception.cc
Normal file
48
ircd/exception.cc
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* charybdis: 21st Century IRCd
|
||||||
|
* exception.cc: Exception root
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Charybdis Development Team
|
||||||
|
* Copyright (C) 2016 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ircd/exception.h>
|
||||||
|
|
||||||
|
using namespace ircd;
|
||||||
|
|
||||||
|
|
||||||
|
exception::exception(const pass_name_t,
|
||||||
|
const char *const &name,
|
||||||
|
const char *const fmt,
|
||||||
|
...)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
size_t size(0);
|
||||||
|
const bool empty(!fmt || !fmt[0] || fmt[0] == ' ');
|
||||||
|
size = rb_strlcpy(buf, name, sizeof(buf));
|
||||||
|
size = rb_strlcat(buf, empty? "." : ": ", sizeof(buf));
|
||||||
|
if(size < sizeof(buf))
|
||||||
|
vsnprintf(buf + size, sizeof(buf) - size, fmt, ap);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}
|
|
@ -24,6 +24,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ircd/stdinc.h>
|
#include <ircd/stdinc.h>
|
||||||
|
#include <ircd/fs.h>
|
||||||
|
#include <ircd/logger.h>
|
||||||
|
|
||||||
using namespace ircd;
|
using namespace ircd;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue