Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/atf/atf-c++/detail/exceptions.cpp
39563 views
1
// Copyright (c) 2007 The NetBSD Foundation, Inc.
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions
6
// are met:
7
// 1. Redistributions of source code must retain the above copyright
8
// notice, this list of conditions and the following disclaimer.
9
// 2. Redistributions in binary form must reproduce the above copyright
10
// notice, this list of conditions and the following disclaimer in the
11
// documentation and/or other materials provided with the distribution.
12
//
13
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26
#include "atf-c++/detail/exceptions.hpp"
27
28
#if defined(HAVE_CONFIG_H)
29
#include "config.h"
30
#endif
31
32
#include <cstdarg>
33
#include <cstdio>
34
#include <cstring>
35
#include <new>
36
37
extern "C" {
38
#include "atf-c/error.h"
39
}
40
41
#include "atf-c++/detail/sanity.hpp"
42
43
// ------------------------------------------------------------------------
44
// The "system_error" type.
45
// ------------------------------------------------------------------------
46
47
atf::system_error::system_error(const std::string& who,
48
const std::string& message,
49
int sys_err) :
50
std::runtime_error(who + ": " + message),
51
m_sys_err(sys_err)
52
{
53
}
54
55
atf::system_error::~system_error(void)
56
throw()
57
{
58
}
59
60
int
61
atf::system_error::code(void)
62
const
63
throw()
64
{
65
return m_sys_err;
66
}
67
68
const char*
69
atf::system_error::what(void)
70
const
71
throw()
72
{
73
try {
74
if (m_message.length() == 0) {
75
m_message = std::string(std::runtime_error::what()) + ": ";
76
m_message += ::strerror(m_sys_err);
77
}
78
79
return m_message.c_str();
80
} catch (...) {
81
return "Unable to format system_error message";
82
}
83
}
84
85
// ------------------------------------------------------------------------
86
// Free functions.
87
// ------------------------------------------------------------------------
88
89
static
90
void
91
throw_libc_error(atf_error_t err)
92
{
93
PRE(atf_error_is(err, "libc"));
94
95
const int ecode = atf_libc_error_code(err);
96
const std::string msg = atf_libc_error_msg(err);
97
atf_error_free(err);
98
throw atf::system_error("XXX", msg, ecode);
99
}
100
101
static
102
void
103
throw_no_memory_error(atf_error_t err)
104
{
105
PRE(atf_error_is(err, "no_memory"));
106
107
atf_error_free(err);
108
throw std::bad_alloc();
109
}
110
111
static
112
void
113
throw_unknown_error(atf_error_t err)
114
{
115
PRE(atf_is_error(err));
116
117
static char buf[4096];
118
atf_error_format(err, buf, sizeof(buf));
119
atf_error_free(err);
120
throw std::runtime_error(buf);
121
}
122
123
void
124
atf::throw_atf_error(atf_error_t err)
125
{
126
static struct handler {
127
const char* m_name;
128
void (*m_func)(atf_error_t);
129
} handlers[] = {
130
{ "libc", throw_libc_error },
131
{ "no_memory", throw_no_memory_error },
132
{ NULL, throw_unknown_error },
133
};
134
135
PRE(atf_is_error(err));
136
137
handler* h = handlers;
138
while (h->m_name != NULL) {
139
if (atf_error_is(err, h->m_name)) {
140
h->m_func(err);
141
UNREACHABLE;
142
} else
143
h++;
144
}
145
// XXX: I'm not sure that raising an "unknown" error is a wise thing
146
// to do here. The C++ binding is supposed to have feature parity
147
// with the C one, so all possible errors raised by the C library
148
// should have their counterpart in the C++ library. Still, removing
149
// this will require some code auditing that I can't afford at the
150
// moment.
151
INV(h->m_name == NULL && h->m_func != NULL);
152
h->m_func(err);
153
UNREACHABLE;
154
}
155
156