1//===---------------------- system_error.cpp ------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#define _LIBCPP_BUILDING_SYSTEM_ERROR
11#include "system_error"
12#include "string"
13#include "cstring"
14
15_LIBCPP_BEGIN_NAMESPACE_STD
16
17// class error_category
18
19error_category::error_category() _NOEXCEPT
20{
21}
22
23error_category::~error_category() _NOEXCEPT
24{
25}
26
27error_condition
28error_category::default_error_condition(int ev) const _NOEXCEPT
29{
30    return error_condition(ev, *this);
31}
32
33bool
34error_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT
35{
36    return default_error_condition(code) == condition;
37}
38
39bool
40error_category::equivalent(const error_code& code, int condition) const _NOEXCEPT
41{
42    return *this == code.category() && code.value() == condition;
43}
44
45string
46__do_message::message(int ev) const
47{
48    return string(strerror(ev));
49}
50
51class _LIBCPP_HIDDEN __generic_error_category
52    : public __do_message
53{
54public:
55    virtual const char* name() const _NOEXCEPT;
56    virtual string message(int ev) const;
57};
58
59const char*
60__generic_error_category::name() const _NOEXCEPT
61{
62    return "generic";
63}
64
65string
66__generic_error_category::message(int ev) const
67{
68#ifdef ELAST
69    if (ev > ELAST)
70      return string("unspecified generic_category error");
71#elif defined(__linux__)
72    if (ev > 4095)
73      return string("unspecified generic_category error");
74#endif  // ELAST
75    return __do_message::message(ev);
76}
77
78const error_category&
79generic_category() _NOEXCEPT
80{
81    static __generic_error_category s;
82    return s;
83}
84
85class _LIBCPP_HIDDEN __system_error_category
86    : public __do_message
87{
88public:
89    virtual const char* name() const _NOEXCEPT;
90    virtual string message(int ev) const;
91    virtual error_condition default_error_condition(int ev) const _NOEXCEPT;
92};
93
94const char*
95__system_error_category::name() const _NOEXCEPT
96{
97    return "system";
98}
99
100string
101__system_error_category::message(int ev) const
102{
103#ifdef ELAST
104    if (ev > ELAST)
105      return string("unspecified system_category error");
106#elif defined(__linux__)
107    if (ev > 4095)
108      return string("unspecified system_category error");
109#endif  // ELAST
110    return __do_message::message(ev);
111}
112
113error_condition
114__system_error_category::default_error_condition(int ev) const _NOEXCEPT
115{
116#ifdef ELAST
117    if (ev > ELAST)
118      return error_condition(ev, system_category());
119#elif defined(__linux__)
120    if (ev > 4095)
121      return error_condition(ev, system_category());
122#endif  // ELAST
123    return error_condition(ev, generic_category());
124}
125
126const error_category&
127system_category() _NOEXCEPT
128{
129    static __system_error_category s;
130    return s;
131}
132
133// error_condition
134
135string
136error_condition::message() const
137{
138    return __cat_->message(__val_);
139}
140
141// error_code
142
143string
144error_code::message() const
145{
146    return __cat_->message(__val_);
147}
148
149// system_error
150
151string
152system_error::__init(const error_code& ec, string what_arg)
153{
154    if (ec)
155    {
156        if (!what_arg.empty())
157            what_arg += ": ";
158        what_arg += ec.message();
159    }
160    return _VSTD::move(what_arg);
161}
162
163system_error::system_error(error_code ec, const string& what_arg)
164    : runtime_error(__init(ec, what_arg)),
165      __ec_(ec)
166{
167}
168
169system_error::system_error(error_code ec, const char* what_arg)
170    : runtime_error(__init(ec, what_arg)),
171      __ec_(ec)
172{
173}
174
175system_error::system_error(error_code ec)
176    : runtime_error(__init(ec, "")),
177      __ec_(ec)
178{
179}
180
181system_error::system_error(int ev, const error_category& ecat, const string& what_arg)
182    : runtime_error(__init(error_code(ev, ecat), what_arg)),
183      __ec_(error_code(ev, ecat))
184{
185}
186
187system_error::system_error(int ev, const error_category& ecat, const char* what_arg)
188    : runtime_error(__init(error_code(ev, ecat), what_arg)),
189      __ec_(error_code(ev, ecat))
190{
191}
192
193system_error::system_error(int ev, const error_category& ecat)
194    : runtime_error(__init(error_code(ev, ecat), "")),
195      __ec_(error_code(ev, ecat))
196{
197}
198
199system_error::~system_error() _NOEXCEPT
200{
201}
202
203void
204__throw_system_error(int ev, const char* what_arg)
205{
206#ifndef _LIBCPP_NO_EXCEPTIONS
207    throw system_error(error_code(ev, system_category()), what_arg);
208#else
209    (void)ev;
210    (void)what_arg;
211#endif
212}
213
214_LIBCPP_END_NAMESPACE_STD
215