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 
error_category()19 error_category::error_category() _NOEXCEPT
20 {
21 }
22 
~error_category()23 error_category::~error_category() _NOEXCEPT
24 {
25 }
26 
27 error_condition
default_error_condition(int ev) const28 error_category::default_error_condition(int ev) const _NOEXCEPT
29 {
30     return error_condition(ev, *this);
31 }
32 
33 bool
equivalent(int code,const error_condition & condition) const34 error_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT
35 {
36     return default_error_condition(code) == condition;
37 }
38 
39 bool
equivalent(const error_code & code,int condition) const40 error_category::equivalent(const error_code& code, int condition) const _NOEXCEPT
41 {
42     return *this == code.category() && code.value() == condition;
43 }
44 
45 string
message(int ev) const46 __do_message::message(int ev) const
47 {
48     return string(strerror(ev));
49 }
50 
51 class _LIBCPP_HIDDEN __generic_error_category
52     : public __do_message
53 {
54 public:
55     virtual const char* name() const _NOEXCEPT;
56     virtual string message(int ev) const;
57 };
58 
59 const char*
name() const60 __generic_error_category::name() const _NOEXCEPT
61 {
62     return "generic";
63 }
64 
65 string
message(int ev) const66 __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 
78 const error_category&
generic_category()79 generic_category() _NOEXCEPT
80 {
81     static __generic_error_category s;
82     return s;
83 }
84 
85 class _LIBCPP_HIDDEN __system_error_category
86     : public __do_message
87 {
88 public:
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 
94 const char*
name() const95 __system_error_category::name() const _NOEXCEPT
96 {
97     return "system";
98 }
99 
100 string
message(int ev) const101 __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 
113 error_condition
default_error_condition(int ev) const114 __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 
126 const error_category&
system_category()127 system_category() _NOEXCEPT
128 {
129     static __system_error_category s;
130     return s;
131 }
132 
133 // error_condition
134 
135 string
message() const136 error_condition::message() const
137 {
138     return __cat_->message(__val_);
139 }
140 
141 // error_code
142 
143 string
message() const144 error_code::message() const
145 {
146     return __cat_->message(__val_);
147 }
148 
149 // system_error
150 
151 string
__init(const error_code & ec,string what_arg)152 system_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 
system_error(error_code ec,const string & what_arg)163 system_error::system_error(error_code ec, const string& what_arg)
164     : runtime_error(__init(ec, what_arg)),
165       __ec_(ec)
166 {
167 }
168 
system_error(error_code ec,const char * what_arg)169 system_error::system_error(error_code ec, const char* what_arg)
170     : runtime_error(__init(ec, what_arg)),
171       __ec_(ec)
172 {
173 }
174 
system_error(error_code ec)175 system_error::system_error(error_code ec)
176     : runtime_error(__init(ec, "")),
177       __ec_(ec)
178 {
179 }
180 
system_error(int ev,const error_category & ecat,const string & what_arg)181 system_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 
system_error(int ev,const error_category & ecat,const char * what_arg)187 system_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 
system_error(int ev,const error_category & ecat)193 system_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 
~system_error()199 system_error::~system_error() _NOEXCEPT
200 {
201 }
202 
203 void
__throw_system_error(int ev,const char * what_arg)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