forked from boostorg/system
Bring into compliance with N2066, TR2 Diagnostics Enhancements. Tests passing on Win32, Linux, on most modern compilers.
[SVN r35823]
This commit is contained in:
96
.gitattributes
vendored
Normal file
96
.gitattributes
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
* text=auto !eol svneol=native#text/plain
|
||||
*.gitattributes text svneol=native#text/plain
|
||||
|
||||
# Scriptish formats
|
||||
*.bat text svneol=native#text/plain
|
||||
*.bsh text svneol=native#text/x-beanshell
|
||||
*.cgi text svneol=native#text/plain
|
||||
*.cmd text svneol=native#text/plain
|
||||
*.js text svneol=native#text/javascript
|
||||
*.php text svneol=native#text/x-php
|
||||
*.pl text svneol=native#text/x-perl
|
||||
*.pm text svneol=native#text/x-perl
|
||||
*.py text svneol=native#text/x-python
|
||||
*.sh eol=lf svneol=LF#text/x-sh
|
||||
configure eol=lf svneol=LF#text/x-sh
|
||||
|
||||
# Image formats
|
||||
*.bmp binary svneol=unset#image/bmp
|
||||
*.gif binary svneol=unset#image/gif
|
||||
*.ico binary svneol=unset#image/ico
|
||||
*.jpeg binary svneol=unset#image/jpeg
|
||||
*.jpg binary svneol=unset#image/jpeg
|
||||
*.png binary svneol=unset#image/png
|
||||
*.tif binary svneol=unset#image/tiff
|
||||
*.tiff binary svneol=unset#image/tiff
|
||||
*.svg text svneol=native#image/svg%2Bxml
|
||||
|
||||
# Data formats
|
||||
*.pdf binary svneol=unset#application/pdf
|
||||
*.avi binary svneol=unset#video/avi
|
||||
*.doc binary svneol=unset#application/msword
|
||||
*.dsp text svneol=crlf#text/plain
|
||||
*.dsw text svneol=crlf#text/plain
|
||||
*.eps binary svneol=unset#application/postscript
|
||||
*.gz binary svneol=unset#application/gzip
|
||||
*.mov binary svneol=unset#video/quicktime
|
||||
*.mp3 binary svneol=unset#audio/mpeg
|
||||
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
|
||||
*.ps binary svneol=unset#application/postscript
|
||||
*.psd binary svneol=unset#application/photoshop
|
||||
*.rdf binary svneol=unset#text/rdf
|
||||
*.rss text svneol=unset#text/xml
|
||||
*.rtf binary svneol=unset#text/rtf
|
||||
*.sln text svneol=native#text/plain
|
||||
*.swf binary svneol=unset#application/x-shockwave-flash
|
||||
*.tgz binary svneol=unset#application/gzip
|
||||
*.vcproj text svneol=native#text/xml
|
||||
*.vcxproj text svneol=native#text/xml
|
||||
*.vsprops text svneol=native#text/xml
|
||||
*.wav binary svneol=unset#audio/wav
|
||||
*.xls binary svneol=unset#application/vnd.ms-excel
|
||||
*.zip binary svneol=unset#application/zip
|
||||
|
||||
# Text formats
|
||||
.htaccess text svneol=native#text/plain
|
||||
*.bbk text svneol=native#text/xml
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
*.log text svneol=native#text/plain
|
||||
*.mak text svneol=native#text/plain
|
||||
*.qbk text svneol=native#text/plain
|
||||
*.rst text svneol=native#text/plain
|
||||
*.sql text svneol=native#text/x-sql
|
||||
*.txt text svneol=native#text/plain
|
||||
*.xhtml text svneol=native#text/xhtml%2Bxml
|
||||
*.xml text svneol=native#text/xml
|
||||
*.xsd text svneol=native#text/xml
|
||||
*.xsl text svneol=native#text/xml
|
||||
*.xslt text svneol=native#text/xml
|
||||
*.xul text svneol=native#text/xul
|
||||
*.yml text svneol=native#text/plain
|
||||
boost-no-inspect text svneol=native#text/plain
|
||||
CHANGES text svneol=native#text/plain
|
||||
COPYING text svneol=native#text/plain
|
||||
INSTALL text svneol=native#text/plain
|
||||
Jamfile text svneol=native#text/plain
|
||||
Jamroot text svneol=native#text/plain
|
||||
Jamfile.v2 text svneol=native#text/plain
|
||||
Jamrules text svneol=native#text/plain
|
||||
Makefile* text svneol=native#text/plain
|
||||
README text svneol=native#text/plain
|
||||
TODO text svneol=native#text/plain
|
||||
|
||||
# Code formats
|
||||
*.c text svneol=native#text/plain
|
||||
*.cpp text svneol=native#text/plain
|
||||
*.h text svneol=native#text/plain
|
||||
*.hpp text svneol=native#text/plain
|
||||
*.ipp text svneol=native#text/plain
|
||||
*.tpp text svneol=native#text/plain
|
||||
*.jam text svneol=native#text/plain
|
||||
*.java text svneol=native#text/plain
|
56
build/Jamfile
Normal file
56
build/Jamfile
Normal file
@ -0,0 +1,56 @@
|
||||
# Boost System Library Build Jamfile
|
||||
|
||||
# (C) Copyright Beman Dawes 2002, 2006
|
||||
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# See library home page at http://www.boost.org/libs/system
|
||||
|
||||
subproject libs/system/build ;
|
||||
|
||||
SOURCES = error_code ;
|
||||
|
||||
lib boost_system
|
||||
: ../src/$(SOURCES).cpp
|
||||
: # build requirements
|
||||
<define>BOOST_SYSTEM_STATIC_LINK
|
||||
<sysinclude>$(BOOST_AUX_ROOT) <sysinclude>$(BOOST_ROOT)
|
||||
# common-variant-tag ensures that the library will
|
||||
# be named according to the rules used by the install
|
||||
# and auto-link features:
|
||||
common-variant-tag
|
||||
: debug release # build variants
|
||||
;
|
||||
|
||||
dll boost_system
|
||||
: ../src/$(SOURCES).cpp
|
||||
: # build requirements
|
||||
<define>BOOST_SYSTEM_DYN_LINK=1 # tell source we're building dll's
|
||||
<runtime-link>dynamic # build only for dynamic runtimes
|
||||
<sysinclude>$(BOOST_AUX_ROOT) <sysinclude>$(BOOST_ROOT)
|
||||
# common-variant-tag ensures that the library will
|
||||
# be named according to the rules used by the install
|
||||
# and auto-link features:
|
||||
common-variant-tag
|
||||
: debug release # build variants
|
||||
;
|
||||
|
||||
install system lib
|
||||
: <lib>boost_system <dll>boost_system
|
||||
;
|
||||
|
||||
stage stage/lib : <lib>boost_system <dll>boost_system
|
||||
:
|
||||
# copy to a path rooted at BOOST_ROOT:
|
||||
<locate>$(BOOST_ROOT)
|
||||
# make sure the names of the libraries are correctly named:
|
||||
common-variant-tag
|
||||
# add this target to the "stage" and "all" psuedo-targets:
|
||||
<target>stage
|
||||
<target>all
|
||||
:
|
||||
debug release
|
||||
;
|
||||
|
||||
# end
|
265
doc/error_code.html
Normal file
265
doc/error_code.html
Normal file
@ -0,0 +1,265 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>Boost class error_code documentation
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF">
|
||||
|
||||
<h1>Header <a href="../../../boost/system/error_code.hpp">boost/system/error_code.hpp</a></h1>
|
||||
<p><a href="#Introduction">Introduction</a><br>
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Class-error_category">Class <code>error_category</code></a><br>
|
||||
<a href="#Class-error_category-members">Members</a><br>
|
||||
<a href="#Class-error_code">Class <code>error_code</code></a><br>
|
||||
<a href="#Class-error_code-members">Members</a><br>
|
||||
<a href="#Non-member">Non-member functions</a><br>
|
||||
<a href="#Acknowledgements">Acknowledgments</a></p>
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
<p>This header provides components used to report errors from the operating
|
||||
system or other low-level application program interface (API). It is based on the <i>Diagnostics</i> portion of the TR2 filesystem
|
||||
proposal.</p>
|
||||
<p>Class <code><a href="#Class-error_code">error_code</a></code> encapsulates an error
|
||||
code, usually one returned by an API. Class <code>
|
||||
<a href="#Class-error_category-members">error_category</a></code> encapsulates
|
||||
an identifier for a
|
||||
particular kind of error code. Users or
|
||||
third-parties may add additional error categories.</p>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<pre>namespace boost
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
class error_code;
|
||||
|
||||
typedef int (*errno_decoder)( const error_code & );
|
||||
typedef std::string (*message_decoder)( const error_code & );
|
||||
typedef wstring_t (*wmessage_decoder)( const error_code & );
|
||||
|
||||
class error_category : public <a href="../../utility/doc/identifier.html">identifier</a>< uint_least32_t, error_category >
|
||||
{
|
||||
public:
|
||||
error_category();
|
||||
explicit error_category( value_type v );
|
||||
};
|
||||
|
||||
const error_category errno_ecat = <i>unspecified-value</i>;
|
||||
const error_category native_ecat = <i>unspecified-value</i>;
|
||||
|
||||
class error_code
|
||||
{
|
||||
public:
|
||||
typedef boost::int_least32_t value_type;
|
||||
|
||||
// constructors:
|
||||
<a href="#error_code">error_code</a>();
|
||||
<a href="#error_code-2">error_code</a>( value_type val, error_category cat );
|
||||
void <a href="#error_code-assign">assign</a>(value_type val, error_category cat);
|
||||
|
||||
// observers:
|
||||
value_type <a href="#value">value</a>() const;
|
||||
error_category <a href="#category">category</a>() const;
|
||||
int <a href="#to_errno">to_errno</a>() const; // name chosen to limit surprises
|
||||
// see Kohlhoff June 28 '06 boost posting
|
||||
std::string <a href="#message">message</a>() const;
|
||||
std::wstring <a href="#wmessage">wmessage</a>() const;
|
||||
|
||||
// relationals:
|
||||
bool <a href="#operator-eq">operator==</a>( const error_code & rhs ) const;
|
||||
bool <a href="#operator-ne">operator!=</a>( const error_code & rhs ) const;
|
||||
bool <a href="#operator-lt">operator<</a> ( const error_code & rhs ) const;
|
||||
bool <a href="#operator-le">operator<=</a>( const error_code & rhs ) const;
|
||||
bool <a href="#operator-gt">operator></a> ( const error_code & rhs ) const;
|
||||
bool <a href="#operator-ge">operator>=</a>( const error_code & rhs ) const;
|
||||
|
||||
<a href="#operator-unspecified-bool-type">operator <i>unspecified-bool-type</i></a>() const;
|
||||
bool <a href="#operator-bang">operator!</a>() const;
|
||||
|
||||
// statics:
|
||||
static error_category <a href="#new_category">new_category</a>( errno_decoder ed = 0,
|
||||
message_decoder md = 0, wmessage_decoder wmd = 0 );
|
||||
static bool <a href="#get_decoders">get_decoders</a>( error_category cat, errno_decoder & ed,
|
||||
message_decoder & md, wmessage_decoder & wmd );
|
||||
|
||||
};
|
||||
|
||||
std::size_t <a href="#hash_value">hash_value</a>( const error_code & ec );
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost</pre>
|
||||
<h2><a name="Class-error_category">Class <code>error_category</code></a></h2>
|
||||
<p>Class <code><a href="#Class-error_category-members">error_category</a></code>
|
||||
encapsulates an identifier for a
|
||||
particular kind of error code. Users or
|
||||
third-parties may add additional error categories.</p>
|
||||
<p>For inherited members, see <a href="../../utility/doc/identifier.html">
|
||||
identifier documentation</a>.</p>
|
||||
<h3><a name="Class-error_category-members">Class <code>error_category</code>
|
||||
members</a></h3>
|
||||
<pre>error_category();</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>error_category</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>value() == value_type()</code>.</p>
|
||||
</blockquote>
|
||||
<pre>explicit error_category( value_type v );</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>error_category</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>value() == v</code>.</p>
|
||||
</blockquote>
|
||||
<h2><a name="Class-error_code">Class <code>error_code</code></a></h2>
|
||||
<p>The value contained by an <code>error_code</code> object is the underlying
|
||||
API error code itself if the API error code type can be stored in <code>
|
||||
value_type</code> without loss of any actual values and if 0 represents no
|
||||
error. Otherwise, the value is an integer that maps to the API error code, with
|
||||
the exact method of mapping unspecified.</p>
|
||||
<h3><a name="Class-error_code-members">Class <code>error_code</code> members</a></h3>
|
||||
<pre><a name="error_code">error_code</a>();</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>error_code</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>value() == 0 && category() == errno_ecat</code>.</p>
|
||||
</blockquote>
|
||||
<pre><a name="error_code-2">error_code</a>( value_type val, error_category cat );</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>error_code</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>value() == val && category() == cat</code>.</p>
|
||||
</blockquote>
|
||||
<pre>void <a name="error_code-assign">assign</a>(value_type val, error_category cat);</pre>
|
||||
<blockquote>
|
||||
<p><i>Postconditions:</i> <code>value() == val && category() == cat</code>.</p>
|
||||
</blockquote>
|
||||
<pre>value_type <a name="value">value</a>() const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>value()</code> as specified by <i>postconditions</i> of the most
|
||||
recent <code>assign</code>, if any, or of the constructor.</p>
|
||||
</blockquote>
|
||||
<pre>error_category <a name="category">category</a>() const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>category()</code> as specified by <i>postconditions</i> of the most
|
||||
recent <code>assign</code>, if any, or of the constructor.</p>
|
||||
</blockquote>
|
||||
<pre>int <a name="to_errno">to_errno</a>() const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects: </i> <code>errno_decoder ed;<br>
|
||||
message_decoder md;<br>
|
||||
wmessage_decoder wmd;<br>
|
||||
bool ok( get_decoders( category(), ed, md,
|
||||
wmd ) );</code></p>
|
||||
<p><i>Returns:</i> If <code>ok && ed</code>, <code>ed(*this)</code>,
|
||||
otherwise <code>EOTHER</code>.</p>
|
||||
<p><i>[Note:</i> The intent is to return the <a href="http://www.unix.org/single_unix_specification/">
|
||||
ISO/IEC 9945:2003, <i>Portable Operating System Interface (POSIX)</i></a> error
|
||||
number that the implementation determines most closely corresponds to <code>
|
||||
value()</code>. <i>--end note.]</i></p>
|
||||
</blockquote>
|
||||
<pre>std::string <a name="message">message</a>() const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects: </i> <code>errno_decoder ed;<br>
|
||||
message_decoder md;<br>
|
||||
wmessage_decoder wmd;<br>
|
||||
bool ok( get_decoders( category(), ed, md,
|
||||
wmd ) );</code></p>
|
||||
<p><i>Returns:</i> If <code>ok && md</code>, <code>md(*this)</code>,
|
||||
otherwise <code>std::string()</code>.</p>
|
||||
<p><i>Remarks:</i> If <code>category() == errno_ec</code>, the string is as
|
||||
returned by <code>strerror()</code>. Otherwise, the method used by the
|
||||
implementation to determine the string is unspecified.</p>
|
||||
<p><i>[Note:</i> The intent is to return a locale sensitive string that describes the error
|
||||
corresponding to <code>value()</code>. <i>--end note.]</i></p>
|
||||
</blockquote>
|
||||
<pre>wstring_t <a name="wmessage">wmessage</a>() const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects: </i> <code>errno_decoder ed;<br>
|
||||
message_decoder md;<br>
|
||||
wmessage_decoder wmd;<br>
|
||||
bool ok( get_decoders( category(), ed, md,
|
||||
wmd ) );</code></p>
|
||||
<p><i>Returns:</i> If <code>ok && wmd</code>, <code>wmd(*this)</code>,
|
||||
otherwise <code>std::wstring()</code>.</p>
|
||||
<p><i>Remarks:</i> If <code>category() == errno_ec</code>, the string is as
|
||||
returned by <code>strerror()</code>. Otherwise, the method used by the
|
||||
implementation to determine the string is unspecified.</p>
|
||||
<p><i>[Note:</i> The intent is to return a locale sensitive string that describes the error
|
||||
corresponding to <code>value()</code>. <i>--end note.]</i></p>
|
||||
</blockquote>
|
||||
<pre>bool <a name="operator-eq">operator</a>==(const error_code & rhs) const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>value() == rhs.value() && category() == rhs.category()</code>.</p>
|
||||
</blockquote>
|
||||
<pre>bool <a name="operator-ne">operator!</a>=(const error_code & rhs) const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>!(*this == rhs)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>bool <a name="operator-lt">operator</a><(const error_code & rhs) const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>category() < rhs.category() || ( category() ==
|
||||
rhs.category() && value() < rhs.value() )</code>.</p>
|
||||
</blockquote>
|
||||
<pre>bool <a name="operator-le">operator</a><=(const error_code & rhs) const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>*this == rhs || *this < rhs</code>.</p>
|
||||
</blockquote>
|
||||
<pre>bool <a name="operator-gt">operator</a>>(const error_code & rhs) const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>!(*this <= rhs)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>bool <a name="operator-ge">operator</a>>=(const error_code & rhs) const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>!(*this < rhs)</code>.</p>
|
||||
</blockquote>
|
||||
<pre><a name="operator-unspecified-bool-type">operator <i>unspecified-bool-type</i></a>() const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code> value() != value_type() ? <i>unspecified-bool-type</i>
|
||||
: 0</code>.</p>
|
||||
<p><i>Throws:</i> nothing.</p>
|
||||
<p>[ <i>Note: </i>This conversion can be used in contexts where a <code>bool</code>
|
||||
is expected (e.g., an <code>if</code> condition); however, implicit conversions
|
||||
(e.g., to <code>int</code>) that can occur with <code>bool</code> are not
|
||||
allowed, eliminating some sources of user error. One possible implementation
|
||||
choice for this type is pointer-to-member. <i><EFBFBD>end note </i>]</p>
|
||||
</blockquote>
|
||||
<pre>bool <a name="operator-bang">operator!</a>() const;</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code> value() == value_type()</code>.</p>
|
||||
</blockquote>
|
||||
<pre>static error_category <a name="new_category">new_category</a>( errno_decoder ed = 0, message_decoder md = 0, wmessage_decoder wmd = 0 );</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs a new <code>error_category</code> object.<code>
|
||||
</code>Creates an association between the object and <code>ed</code>,
|
||||
<code>md</code>, and <code>wmd</code>.</p>
|
||||
<p><i>Returns:</i> The object.</p>
|
||||
</blockquote>
|
||||
<pre>static bool <a name="get_decoders">get_decoders</a>( error_category cat, errno_decoder & ed, message_decoder & md, wmessage_decoder & wmd );</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> If <code>cat</code> was created by <code>new_category()</code>,
|
||||
sets <code>ed</code>, <code>md</code>, and <code>wmd</code>
|
||||
to the respective values associated with <code>cat</code> by <code>
|
||||
new_category()</code>. Otherwise, no effects.</p>
|
||||
<p><i>Returns:</i> If <code>cat</code> was created by <code>new_category()</code>,
|
||||
<code>true</code>, otherwise <code>false</code>.</p>
|
||||
</blockquote>
|
||||
<h2><a name="Non-member">Non-member</a> functions</h2>
|
||||
<pre>std::size_t <a name="hash_value">hash_value</a>( const error_code & ec );</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns: </i> A hash value representing <code>ec</code>.</p>
|
||||
</blockquote>
|
||||
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||||
<p>Christopher Kohlhoff and Peter Dimov made important contributions to the
|
||||
design. Comments and suggestions were also received from Pavel Vozenilek,
|
||||
Gennaro Prota, Dave Abrahams, Jeff Garland, Iain Hanson, Oliver Kowalke, and
|
||||
Oleg Abrosimov.</p>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->06 September, 2006<!--webbot bot="Timestamp" endspan i-checksum="39349" --></p>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2006</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a>)</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
127
doc/system_error.html
Normal file
127
doc/system_error.html
Normal file
@ -0,0 +1,127 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>Boost system/system_error.hpp documentation
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF">
|
||||
|
||||
<h1>Header <a href="../../../boost/system/system_error.hpp">boost/system/system_error.hpp</a></h1>
|
||||
<p><a href="#Introduction">Introduction</a><br>
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Class-system_error">Class <code>system_error</code></a><br>
|
||||
<a href="#Class-system_error-members">Members</a><br>
|
||||
<a href="#Acknowledgements">Acknowledgements</a></p>
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
<p>This header provides components used to report errors originating from the
|
||||
operating system or other low-level application program interfaces (API's). It is based on the <i>Diagnostics</i>
|
||||
portion of the TR2 filesystem proposal.</p>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<pre>namespace boost
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
enum message_action { append_message, no_message };
|
||||
|
||||
class system_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit <a href="#system_error-1">system_error</a>( error_code ec );
|
||||
|
||||
<a href="#system_error-2">system_error</a>( error_code ec, const std::string & what_arg,
|
||||
message_action ma = append_message );
|
||||
|
||||
<a href="#system_error-3">system_error</a>( error_code::value_type ev, error_category ecat );
|
||||
|
||||
<a href="#system_error-4">system_error</a>( error_code::value_type ev, error_category ecat,
|
||||
const std::string & what_arg, message_action ma = append_message );
|
||||
|
||||
virtual ~system_error() throw() {}
|
||||
|
||||
const error_code & <a href="#code">code</a>() const throw();
|
||||
|
||||
const char * <a href="#what">what</a>() const throw();
|
||||
|
||||
private:
|
||||
error_code m_error_code; // for exposition only
|
||||
bool m_append_message; // for exposition only
|
||||
mutable std::string m_what; // for exposition only
|
||||
};
|
||||
} // namespace system
|
||||
} // namespace boost</pre>
|
||||
<h2><a name="Class-system_error">Class <code>system_error</code></a></h2>
|
||||
<p>Class <code><a href="#Class-system_error-members">system_error</a></code> defines
|
||||
the type of an object that may be thrown as
|
||||
an exception to report errors originating from the operating system or other
|
||||
low-level API's, or used as a base class for more refined exception classes. It
|
||||
encapsulates an <code><a href="error_code.html">error_code</a></code> object.</p>
|
||||
<blockquote>
|
||||
<p><i>[Note:</i> A single low-level class, rather than a higher level exception
|
||||
class hierarchy, is provided to allow users access to low-level error codes
|
||||
originating from the operating system or other low-level API's, and to
|
||||
accommodate the open-ended set of errors that may be reported by such API's. <i>
|
||||
--end note.]</i></p>
|
||||
</blockquote>
|
||||
<h2><a name="Class-system_error-members">Class <code>system_error</code> Members</a></h2>
|
||||
<p><code>explicit <a name="system_error-1">system_error</a>( error_code ec );</code></p>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>system_error</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>code() == ec && *runtime_error::what() == '\0'
|
||||
&& </code><code>m_append_message</code>.</p>
|
||||
</blockquote>
|
||||
<pre><a name="system_error-2">system_error</a>( error_code ec, const std::string & what_arg, message_action ma = append_message );</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>system_error</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>code() == ec && std::string(runtime_error::what())
|
||||
== </code><code>what_arg</code><code> && m_append_message == ma</code>.</p>
|
||||
</blockquote>
|
||||
<pre><a name="system_error-3">system_error</a>( error_code::value_type ev, error_category ecat );</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>system_error</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>code() == error_code(ev,ecat) && *runtime_error::what()
|
||||
== '\0' && m_append_message</code>.</p>
|
||||
</blockquote>
|
||||
<pre><a name="system_error-4">system_error</a>( error_code::value_type ev, error_category ecat,
|
||||
const std::string & what_arg, message_action ma = append_message );</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of class <code>system_error</code>.</p>
|
||||
<p><i>Postcondition:</i> <code>code() == error_code(ev,ecat) && std::string(runtime_error::what())
|
||||
== </code><code>what_arg</code><code> && m_append_message == ma</code>.</p>
|
||||
</blockquote>
|
||||
<pre>const error_code & <a name="code">code</a>() const throw();</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns: </i> <code>m_error_code</code></p>
|
||||
</blockquote>
|
||||
<pre>const char * <a name="what">what</a>() const throw();</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns: </i>If <code>!m_error_code || !m_append_message</code>, <code>
|
||||
runtime_error::what()</code>. Otherwise, a string as if computed by:</p>
|
||||
<blockquote>
|
||||
<pre>m_what = runtime_error::what();
|
||||
if ( !m_what.empty() ) m_what += ": ";
|
||||
m_what += m_error_code.message();
|
||||
return m_what.c_str();</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||||
<p>Christopher Kohlhoff and Peter Dimov made important contributions to the
|
||||
design. Comments and suggestions were also received from Pavel Vozenilek,
|
||||
Gennaro Prota, Dave Abrahams, Jeff Garland, Iain Hanson, Jeremy Day, Bo
|
||||
Persson, Oliver Kowalke, and
|
||||
Oleg Abrosimov.</p>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->22 July, 2006<!--webbot bot="Timestamp" endspan i-checksum="21146" --></p>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2006</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a>)</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
75
include/boost/system/config.hpp
Normal file
75
include/boost/system/config.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
// boost/system/config.hpp -------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2003, 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/system for documentation.
|
||||
|
||||
#ifndef BOOST_SYSTEM_CONFIG_HPP
|
||||
#define BOOST_SYSTEM_CONFIG_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use.
|
||||
// If not specified, a sensible default will be applied.
|
||||
|
||||
# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API )
|
||||
# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined
|
||||
# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API )
|
||||
# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
|
||||
# define BOOST_WINDOWS_API
|
||||
# else
|
||||
# define BOOST_POSIX_API
|
||||
# endif
|
||||
# endif
|
||||
|
||||
// enable dynamic linking on Windows ---------------------------------------//
|
||||
|
||||
//# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__)
|
||||
//# error Dynamic linking Boost.Filesystem does not work for Borland; use static linking instead
|
||||
//# endif
|
||||
|
||||
#ifdef BOOST_HAS_DECLSPEC // defined in config system
|
||||
// we need to import/export our code only if the user has specifically
|
||||
// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
|
||||
// libraries to be dynamically linked, or BOOST_SYSTEM_DYN_LINK
|
||||
// if they want just this one to be dynamically liked:
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)
|
||||
// export if this is our own source, otherwise import:
|
||||
#ifdef BOOST_SYSTEM_SOURCE
|
||||
# define BOOST_SYSTEM_DECL __declspec(dllexport)
|
||||
#else
|
||||
# define BOOST_SYSTEM_DECL __declspec(dllimport)
|
||||
#endif // BOOST_SYSTEM_SOURCE
|
||||
#endif // DYN_LINK
|
||||
#endif // BOOST_HAS_DECLSPEC
|
||||
//
|
||||
// if BOOST_SYSTEM_DECL isn't defined yet define it now:
|
||||
#ifndef BOOST_SYSTEM_DECL
|
||||
#define BOOST_SYSTEM_DECL
|
||||
#endif
|
||||
|
||||
// enable automatic library variant selection ------------------------------//
|
||||
|
||||
#if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB)
|
||||
//
|
||||
// Set the name of our library, this will get undef'ed by auto_link.hpp
|
||||
// once it's done with it:
|
||||
//
|
||||
#define BOOST_LIB_NAME boost_system
|
||||
//
|
||||
// If we're importing code from a dll, then tell auto_link.hpp about it:
|
||||
//
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)
|
||||
# define BOOST_DYN_LINK
|
||||
#endif
|
||||
//
|
||||
// And include the header that does the work:
|
||||
//
|
||||
#include <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
#endif // BOOST_SYSTEM_CONFIG_HPP
|
||||
|
147
include/boost/system/error_code.hpp
Normal file
147
include/boost/system/error_code.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
// boost/system/error_code.hpp ---------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See library home page at http://www.boost.org/libs/filesystem
|
||||
|
||||
#ifndef BOOST_SYSTEM_ERROR_CODE_HPP
|
||||
#define BOOST_SYSTEM_ERROR_CODE_HPP
|
||||
|
||||
#include <boost/system/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/detail/identifier.hpp>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp> // must be the last #include
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
# ifndef BOOST_NO_STD_WSTRING // workaround Cygwin's lack of wstring_t
|
||||
typedef std::wstring wstring_t;
|
||||
# else
|
||||
typedef std::basic_string<wchar_t> wstring_t;
|
||||
# endif
|
||||
|
||||
class error_code;
|
||||
|
||||
// typedefs for registering additional decoders -------------------------//
|
||||
|
||||
typedef int (*errno_decoder)( const error_code & );
|
||||
typedef std::string (*message_decoder)( const error_code & );
|
||||
typedef wstring_t (*wmessage_decoder)( const error_code & );
|
||||
|
||||
// class error_category ------------------------------------------------//
|
||||
|
||||
class BOOST_SYSTEM_DECL error_category : public identifier< uint_least32_t, error_category >
|
||||
{
|
||||
public:
|
||||
error_category()
|
||||
: boost::identifier< uint_least32_t, error_category >(0){}
|
||||
explicit error_category( value_type v )
|
||||
: boost::identifier< uint_least32_t, error_category >(v){}
|
||||
};
|
||||
|
||||
// predefined error categories -----------------------------------------//
|
||||
|
||||
const error_category errno_ecat(0); // unspecified value
|
||||
|
||||
# ifdef BOOST_WINDOWS_API
|
||||
const error_category native_ecat(1); // unspecified value
|
||||
# else
|
||||
const error_category native_ecat(0); // unspecified value
|
||||
# endif
|
||||
|
||||
// class error_code ----------------------------------------------------//
|
||||
|
||||
class BOOST_SYSTEM_DECL error_code
|
||||
{
|
||||
public:
|
||||
typedef boost::int_least32_t value_type;
|
||||
|
||||
// constructors:
|
||||
error_code()
|
||||
: m_value(0), m_category(errno_ecat) {}
|
||||
error_code( value_type val, error_category cat )
|
||||
: m_value(val), m_category(cat) {}
|
||||
|
||||
|
||||
// observers:
|
||||
value_type value() const { return m_value; }
|
||||
error_category category() const { return m_category; }
|
||||
int to_errno() const; // name chosen to limit surprises
|
||||
// see Kohlhoff Jun 28 '06
|
||||
std::string message() const;
|
||||
wstring_t wmessage() const;
|
||||
|
||||
void assign( value_type val, const error_category & cat )
|
||||
{
|
||||
m_value = val;
|
||||
m_category = cat;
|
||||
}
|
||||
|
||||
// relationals:
|
||||
bool operator==( const error_code & rhs ) const
|
||||
{
|
||||
return value() == rhs.value() && category() == rhs.category();
|
||||
}
|
||||
bool operator!=( const error_code & rhs ) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
bool operator<( const error_code & rhs ) const
|
||||
{
|
||||
return category() < rhs.category()
|
||||
|| ( category() == rhs.category() && value() < rhs.value() );
|
||||
}
|
||||
bool operator<=( const error_code & rhs ) const { return *this == rhs || *this < rhs; }
|
||||
bool operator> ( const error_code & rhs ) const { return !(*this <= rhs); }
|
||||
bool operator>=( const error_code & rhs ) const { return !(*this < rhs); }
|
||||
|
||||
typedef void (*unspecified_bool_type)();
|
||||
static void unspecified_bool_true() {}
|
||||
|
||||
operator unspecified_bool_type() const // true if error
|
||||
{
|
||||
return m_value == value_type() ? 0 : unspecified_bool_true;
|
||||
}
|
||||
|
||||
bool operator!() const // true if no error
|
||||
{
|
||||
return m_value == value_type();
|
||||
}
|
||||
|
||||
// statics:
|
||||
static error_category new_category( errno_decoder ed = 0,
|
||||
message_decoder md = 0, wmessage_decoder wmd = 0 );
|
||||
static bool get_decoders( error_category cat, errno_decoder & ed,
|
||||
message_decoder & md, wmessage_decoder & wmd );
|
||||
|
||||
private:
|
||||
value_type m_value;
|
||||
error_category m_category;
|
||||
};
|
||||
|
||||
// non-member functions ------------------------------------------------//
|
||||
|
||||
inline std::size_t hash_value( const error_code & ec )
|
||||
{
|
||||
return static_cast<std::size_t>(ec.value())
|
||||
+ (static_cast<std::size_t>(ec.category().value()) << 16 );
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
|
||||
|
||||
#endif // BOOST_SYSTEM_ERROR_CODE_HPP
|
||||
|
||||
|
78
include/boost/system/system_error.hpp
Normal file
78
include/boost/system/system_error.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
// Boost system_error.hpp --------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_SYSTEM_ERROR_HPP
|
||||
#define BOOST_SYSTEM_ERROR_HPP
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
enum message_action { append_message, no_message };
|
||||
|
||||
// class system_error --------------------------------------------------//
|
||||
|
||||
class system_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit system_error( error_code ec )
|
||||
: std::runtime_error(std::string()), m_error_code(ec),
|
||||
m_append_message(true) {}
|
||||
|
||||
system_error( error_code ec, const std::string & what_arg,
|
||||
message_action ma = append_message )
|
||||
: std::runtime_error(what_arg), m_error_code(ec),
|
||||
m_append_message(ma==append_message) {}
|
||||
|
||||
system_error( error_code::value_type ev, error_category ecat )
|
||||
: std::runtime_error(std::string()), m_error_code(ev,ecat),
|
||||
m_append_message(true) {}
|
||||
|
||||
system_error( error_code::value_type ev, error_category ecat,
|
||||
const std::string & what_arg, message_action ma = append_message )
|
||||
: std::runtime_error(what_arg), m_error_code(ev,ecat),
|
||||
m_append_message(ma==append_message) {}
|
||||
|
||||
virtual ~system_error() throw() {}
|
||||
|
||||
const error_code & code() const throw() { return m_error_code; }
|
||||
|
||||
const char * what() const throw()
|
||||
// see http://www.boost.org/more/error_handling.html for lazy build rationale
|
||||
{
|
||||
if ( !m_error_code || !m_append_message ) return runtime_error::what();
|
||||
if ( m_what.empty() )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_what = runtime_error::what();
|
||||
if ( !m_what.empty() ) m_what += ": ";
|
||||
m_what += m_error_code.message();
|
||||
}
|
||||
catch (...) { return runtime_error::what(); }
|
||||
}
|
||||
return m_what.c_str();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
error_code m_error_code;
|
||||
mutable std::string m_what;
|
||||
bool m_append_message;
|
||||
};
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_SYSTEM_ERROR_HPP
|
||||
|
||||
|
310
src/error_code.cpp
Normal file
310
src/error_code.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
// error_code support implementation file ----------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2002, 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See library home page at http://www.boost.org/libs/system
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
// VC++ 8.0 warns on usage of certain Standard Library and API functions that
|
||||
// can be cause buffer overruns or other possible security issues if misused.
|
||||
// See http://msdn.microsoft.com/msdnmag/issues/05/05/SafeCandC/default.aspx
|
||||
// But the wording of the warning is misleading and unsettling, there are no
|
||||
// portable alternative functions, and VC++ 8.0's own libraries use the
|
||||
// functions in question. So turn off the warnings.
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _SCL_SECURE_NO_DEPRECATE
|
||||
|
||||
// define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows
|
||||
// the library is being built (possibly exporting rather than importing code)
|
||||
#define BOOST_SYSTEM_SOURCE
|
||||
|
||||
#include <boost/system/config.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/cerrno.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
#include <cstring> // for strerror/strerror_r
|
||||
|
||||
# ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::strerror; }
|
||||
# endif
|
||||
|
||||
# if defined( BOOST_WINDOWS_API )
|
||||
# include "windows.h"
|
||||
# ifndef ERROR_INCORRECT_SIZE
|
||||
# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
|
||||
# endif
|
||||
# endif
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#ifdef BOOST_WINDOWS_API
|
||||
struct native_to_errno_t
|
||||
{
|
||||
boost::int32_t native_value;
|
||||
int to_errno;
|
||||
};
|
||||
|
||||
const native_to_errno_t native_to_errno[] =
|
||||
{
|
||||
// see WinError.h comments for descriptions of errors
|
||||
|
||||
// most common errors first to speed sequential search
|
||||
{ ERROR_FILE_NOT_FOUND, ENOENT },
|
||||
{ ERROR_PATH_NOT_FOUND, ENOENT },
|
||||
|
||||
// rest are alphabetical for easy maintenance
|
||||
{ 0, 0 }, // no error
|
||||
{ ERROR_ACCESS_DENIED, EACCES },
|
||||
{ ERROR_ALREADY_EXISTS, EEXIST },
|
||||
{ ERROR_BAD_UNIT, ENODEV },
|
||||
{ ERROR_BUFFER_OVERFLOW, ENAMETOOLONG },
|
||||
{ ERROR_BUSY, EBUSY },
|
||||
{ ERROR_BUSY_DRIVE, EBUSY },
|
||||
{ ERROR_CANNOT_MAKE, EACCES },
|
||||
{ ERROR_CANTOPEN, EIO },
|
||||
{ ERROR_CANTREAD, EIO },
|
||||
{ ERROR_CANTWRITE, EIO },
|
||||
{ ERROR_CURRENT_DIRECTORY, EACCES },
|
||||
{ ERROR_DEV_NOT_EXIST, ENODEV },
|
||||
{ ERROR_DEVICE_IN_USE, EBUSY },
|
||||
{ ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
|
||||
{ ERROR_DIRECTORY, EINVAL }, // WinError.h: "The directory name is invalid"
|
||||
{ ERROR_DISK_FULL, ENOSPC },
|
||||
{ ERROR_FILE_EXISTS, EEXIST },
|
||||
{ ERROR_HANDLE_DISK_FULL, ENOSPC },
|
||||
{ ERROR_INVALID_ACCESS, EACCES },
|
||||
{ ERROR_INVALID_DRIVE, ENODEV },
|
||||
{ ERROR_INVALID_FUNCTION, ENOSYS },
|
||||
{ ERROR_INVALID_HANDLE, EBADHANDLE },
|
||||
{ ERROR_INVALID_NAME, EINVAL },
|
||||
{ ERROR_LOCK_VIOLATION, EACCES },
|
||||
{ ERROR_LOCKED, EACCES },
|
||||
{ ERROR_NEGATIVE_SEEK, EINVAL },
|
||||
{ ERROR_NOACCESS, EACCES },
|
||||
{ ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
|
||||
{ ERROR_NOT_READY, EAGAIN },
|
||||
{ ERROR_NOT_SAME_DEVICE, EXDEV },
|
||||
{ ERROR_OPEN_FAILED, EIO },
|
||||
{ ERROR_OPEN_FILES, EBUSY },
|
||||
{ ERROR_OUTOFMEMORY, ENOMEM },
|
||||
{ ERROR_READ_FAULT, EIO },
|
||||
{ ERROR_SEEK, EIO },
|
||||
{ ERROR_SHARING_VIOLATION, EACCES },
|
||||
{ ERROR_TOO_MANY_OPEN_FILES, ENFILE },
|
||||
{ ERROR_WRITE_FAULT, EIO },
|
||||
{ ERROR_WRITE_PROTECT, EROFS }
|
||||
};
|
||||
|
||||
int windows_ed( const error_code & ec )
|
||||
{
|
||||
const native_to_errno_t * cur = native_to_errno;
|
||||
do
|
||||
{
|
||||
if ( ec.value() == cur->native_value ) return cur->to_errno;
|
||||
++cur;
|
||||
} while ( cur != native_to_errno + sizeof(native_to_errno)/sizeof(native_to_errno_t) );
|
||||
return EOTHER;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
|
||||
//Some quick notes on the implementation (sorry for the noise if
|
||||
//someone has already mentioned them):
|
||||
//
|
||||
//- The ::LocalFree() usage isn't exception safe.
|
||||
//
|
||||
//See:
|
||||
//
|
||||
//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup>
|
||||
//
|
||||
//in the implementation of what() for an example.
|
||||
//
|
||||
//Cheers,
|
||||
//Chris
|
||||
|
||||
std::string windows_md( const error_code & ec )
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
::FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
ec.value(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
std::string str( static_cast<LPCSTR>(lpMsgBuf) );
|
||||
::LocalFree( lpMsgBuf ); // free the buffer
|
||||
while ( str.size()
|
||||
&& (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
|
||||
str.erase( str.size()-1 );
|
||||
return str;
|
||||
}
|
||||
|
||||
wstring_t windows_wmd( const error_code & ec )
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
::FormatMessageW(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
ec.value(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPWSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
wstring_t str( static_cast<LPCWSTR>(lpMsgBuf) );
|
||||
::LocalFree( lpMsgBuf ); // free the buffer
|
||||
while ( str.size()
|
||||
&& (str[str.size()-1] == L'\n' || str[str.size()-1] == L'\r') )
|
||||
str.erase( str.size()-1 );
|
||||
return str;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int errno_ed( const error_code & ec ) { return ec.value(); }
|
||||
|
||||
std::string errno_md( const error_code & ec )
|
||||
{
|
||||
# if defined(BOOST_WINDOWS_API) || defined(__hpux) || (defined(__linux) && !defined(__USE_XOPEN2K))
|
||||
const char * c_str = std::strerror( ec.value() );
|
||||
return std::string( c_str ? c_str : "EINVAL" );
|
||||
# else
|
||||
char buf[64];
|
||||
char * bp = buf;
|
||||
std::size_t sz = sizeof(buf);
|
||||
# if defined(__CYGWIN__) || defined(__USE_GNU)
|
||||
// Oddball version of strerror_r
|
||||
const char * c_str = strerror_r( ec.value(), bp, sz );
|
||||
return std::string( c_str ? c_str : "EINVAL" );
|
||||
# else
|
||||
// POSIX version of strerror_r
|
||||
int result;
|
||||
for (;;)
|
||||
{
|
||||
if ( (result = strerror_r( ec.value(), bp, sz )) != 0 )
|
||||
{
|
||||
# if defined(__linux)
|
||||
result = errno;
|
||||
# endif
|
||||
if ( result != ERANGE ) break;
|
||||
}
|
||||
if ( sz > sizeof(buf) ) std::free( bp );
|
||||
sz *= 2;
|
||||
if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
|
||||
return std::string( "ENOMEM" );
|
||||
}
|
||||
std::string msg( ( result == EINVAL ) ? "EINVAL" : bp );
|
||||
if ( sz > sizeof(buf) ) std::free( bp );
|
||||
return msg;
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
wstring_t errno_wmd( const error_code & ec )
|
||||
{
|
||||
// TODO: Implement this:
|
||||
assert( 0 && "sorry, not implemented yet" );
|
||||
wstring_t str;
|
||||
return str;
|
||||
}
|
||||
|
||||
struct decoder_element
|
||||
{
|
||||
errno_decoder ed;
|
||||
message_decoder md;
|
||||
wmessage_decoder wmd;
|
||||
|
||||
decoder_element( errno_decoder ed_,
|
||||
message_decoder md_, wmessage_decoder wmd_ )
|
||||
: ed(ed_), md(md_), wmd(wmd_) {}
|
||||
|
||||
decoder_element() : ed(0), md(0), wmd(0) {}
|
||||
};
|
||||
|
||||
const decoder_element init_decoders[] =
|
||||
#ifdef BOOST_WINDOWS_API
|
||||
{ decoder_element( errno_ed, errno_md, errno_wmd ),
|
||||
decoder_element( windows_ed, windows_md, windows_wmd) };
|
||||
#else
|
||||
{ decoder_element( errno_ed, errno_md, errno_wmd ) };
|
||||
#endif
|
||||
|
||||
typedef std::vector< decoder_element > decoder_vec_type;
|
||||
|
||||
decoder_vec_type & decoder_vec()
|
||||
{
|
||||
static decoder_vec_type dv( init_decoders,
|
||||
init_decoders + sizeof(init_decoders)/sizeof(decoder_element));
|
||||
return dv;
|
||||
}
|
||||
} // unnamed namespace
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
BOOST_SYSTEM_DECL error_code throw_on_error; // dummy meaningless value
|
||||
|
||||
error_category error_code::new_category(
|
||||
errno_decoder ed, message_decoder md, wmessage_decoder wmd )
|
||||
{
|
||||
decoder_vec().push_back( decoder_element( ed, md, wmd ) );
|
||||
return error_category( static_cast<value_type>(decoder_vec().size()) - 1 );
|
||||
}
|
||||
|
||||
bool error_code::get_decoders( error_category cat,
|
||||
errno_decoder & ed, message_decoder & md, wmessage_decoder & wmd )
|
||||
{
|
||||
if ( cat.value() < decoder_vec().size() )
|
||||
{
|
||||
ed = decoder_vec()[cat.value()].ed;
|
||||
md = decoder_vec()[cat.value()].md;
|
||||
wmd = decoder_vec()[cat.value()].wmd;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int error_code::to_errno() const
|
||||
{
|
||||
return (m_category.value() < decoder_vec().size()
|
||||
&& decoder_vec()[m_category.value()].ed)
|
||||
? decoder_vec()[m_category.value()].ed( *this )
|
||||
: EOTHER;
|
||||
}
|
||||
|
||||
std::string error_code::message() const
|
||||
{
|
||||
return (m_category.value() < decoder_vec().size()
|
||||
&& decoder_vec()[m_category.value()].md)
|
||||
? decoder_vec()[m_category.value()].md( *this )
|
||||
: std::string( "API error" );
|
||||
}
|
||||
|
||||
wstring_t error_code::wmessage() const
|
||||
{
|
||||
return (m_category.value() < decoder_vec().size()
|
||||
&& decoder_vec()[m_category.value()].wmd)
|
||||
? decoder_vec()[m_category.value()].wmd( *this )
|
||||
: wstring_t( L"API error" );
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost
|
115
test/error_code_test.cpp
Normal file
115
test/error_code_test.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
// error_code_test.cpp -----------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See library home page at http://www.boost.org/libs/system
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
// VC++ 8.0 warns on usage of certain Standard Library and API functions that
|
||||
// can be cause buffer overruns or other possible security issues if misused.
|
||||
// See http://msdn.microsoft.com/msdnmag/issues/05/05/SafeCandC/default.aspx
|
||||
// But the wording of the warning is misleading and unsettling, there are no
|
||||
// portable alternative functions, and VC++ 8.0's own libraries use the
|
||||
// functions in question. So turn off the warnings.
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _SCL_SECURE_NO_DEPRECATE
|
||||
|
||||
#include <boost/test/minimal.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
// Although using directives are not the best programming practice, testing
|
||||
// with a boost::system using directive increases use scenario coverage.
|
||||
using namespace boost::system;
|
||||
|
||||
# if defined( BOOST_WINDOWS_API )
|
||||
# include "winerror.h"
|
||||
# include <boost/cerrno.hpp>
|
||||
# endif
|
||||
|
||||
// test_main ---------------------------------------------------------------//
|
||||
|
||||
// TODO: supply a build jam file
|
||||
// TODO: supply a test jam file
|
||||
// TODO: same for bjam v2
|
||||
// TODO: add message decoder tests
|
||||
|
||||
int test_main( int, char ** )
|
||||
{
|
||||
error_code ec;
|
||||
error_code ec_0_native( 0, native_ecat );
|
||||
error_code ec_0_errno( 0, errno_ecat );
|
||||
error_code ec_1_native( 1, native_ecat );
|
||||
error_code ec_1_errno( 1, errno_ecat );
|
||||
|
||||
BOOST_CHECK( !ec );
|
||||
BOOST_CHECK( ec.value() == 0 );
|
||||
BOOST_CHECK( ec.to_errno() == 0 );
|
||||
|
||||
BOOST_CHECK( !ec_0_native );
|
||||
BOOST_CHECK( ec_0_native.value() == 0 );
|
||||
BOOST_CHECK( ec_0_native.to_errno() == 0 );
|
||||
|
||||
BOOST_CHECK( !ec_0_errno );
|
||||
BOOST_CHECK( ec_0_errno.value() == 0 );
|
||||
BOOST_CHECK( ec_0_errno.to_errno() == 0 );
|
||||
BOOST_CHECK( ec == ec_0_errno );
|
||||
BOOST_CHECK( native_ecat != errno_ecat || ec_0_native == ec_0_errno );
|
||||
BOOST_CHECK( native_ecat == errno_ecat || ec_0_native != ec_0_errno );
|
||||
|
||||
BOOST_CHECK( ec_1_native );
|
||||
BOOST_CHECK( ec_1_native.value() == 1 );
|
||||
BOOST_CHECK( ec_1_native.value() != 0 );
|
||||
BOOST_CHECK( ec_1_native.to_errno() != 0 );
|
||||
BOOST_CHECK( ec != ec_1_native );
|
||||
BOOST_CHECK( ec_0_native != ec_1_native );
|
||||
BOOST_CHECK( ec_0_errno != ec_1_native );
|
||||
|
||||
BOOST_CHECK( ec_1_errno );
|
||||
BOOST_CHECK( ec_1_errno.value() == 1 );
|
||||
BOOST_CHECK( ec_1_errno.to_errno() == 1 );
|
||||
BOOST_CHECK( ec_1_errno.to_errno() != 0 );
|
||||
BOOST_CHECK( ec != ec_1_errno );
|
||||
BOOST_CHECK( ec_0_native != ec_1_errno );
|
||||
BOOST_CHECK( ec_0_errno != ec_1_errno );
|
||||
|
||||
#ifdef BOOST_WINDOWS_API
|
||||
BOOST_CHECK( ec != ec_0_native );
|
||||
|
||||
// these tests probe the Windows to_errno decoder
|
||||
// test the first entry in the decoder table:
|
||||
ec = error_code( ERROR_FILE_NOT_FOUND, native_ecat );
|
||||
BOOST_CHECK( ec.value() == ERROR_FILE_NOT_FOUND );
|
||||
BOOST_CHECK( ec.to_errno() == ENOENT );
|
||||
|
||||
// test the second entry in the decoder table:
|
||||
ec = error_code( ERROR_PATH_NOT_FOUND, native_ecat );
|
||||
BOOST_CHECK( ec.value() == ERROR_PATH_NOT_FOUND );
|
||||
BOOST_CHECK( ec.to_errno() == ENOENT );
|
||||
|
||||
// test the third entry in the decoder table:
|
||||
ec = error_code( ERROR_ACCESS_DENIED, native_ecat );
|
||||
BOOST_CHECK( ec.value() == ERROR_ACCESS_DENIED );
|
||||
BOOST_CHECK( ec.to_errno() == EACCES );
|
||||
|
||||
// test the last regular entry in the decoder table:
|
||||
ec = error_code( ERROR_WRITE_PROTECT, native_ecat );
|
||||
BOOST_CHECK( ec.value() == ERROR_WRITE_PROTECT );
|
||||
BOOST_CHECK( ec.to_errno() == EROFS );
|
||||
|
||||
// test not-in-table condition:
|
||||
ec = error_code( 1234567890, native_ecat );
|
||||
BOOST_CHECK( ec.value() == 1234567890 );
|
||||
BOOST_CHECK( ec.to_errno() == EOTHER );
|
||||
|
||||
#else
|
||||
BOOST_CHECK( ec == ec_0_native );
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
92
test/error_code_user_test.cpp
Normal file
92
test/error_code_user_test.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
// error_code_user_test.cpp ------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See library home page at http://www.boost.org/libs/system
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
// This code demonstrates creation and use of a new category of error codes.
|
||||
|
||||
// The motivation was a Boost posting by Christopher Kohlhoff on June 28, 2006.
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/cerrno.hpp>
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
// header asio.hpp
|
||||
|
||||
#define BOO_BOO 12345 // this could also be a constant; a macro is used for
|
||||
// illustration because many older API's define errors
|
||||
// via macro.
|
||||
namespace boost
|
||||
{
|
||||
namespace asio
|
||||
{
|
||||
// asio declares have its own error_category:
|
||||
extern system::error_category asio_error;
|
||||
|
||||
namespace error
|
||||
{
|
||||
extern boost::system::error_code boo_boo;
|
||||
}
|
||||
|
||||
void boo_boo( boost::system::error_code & ec );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
// implementation file asio.cpp:
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace asio
|
||||
{
|
||||
|
||||
system::error_category asio_error = system::error_code::new_category();
|
||||
|
||||
namespace error
|
||||
{
|
||||
boost::system::error_code boo_boo( BOO_BOO, asio_error );
|
||||
}
|
||||
|
||||
// function sets ec arg to boo_boo
|
||||
void boo_boo( boost::system::error_code & ec )
|
||||
{
|
||||
ec = error::boo_boo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
// a user program:
|
||||
|
||||
|
||||
// #include <asio.hpp>
|
||||
#include <boost/test/minimal.hpp>
|
||||
|
||||
int test_main( int, char *[] )
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
boost::asio::boo_boo( ec );
|
||||
|
||||
BOOST_CHECK( ec );
|
||||
BOOST_CHECK( ec == boost::asio::error::boo_boo );
|
||||
BOOST_CHECK( ec.value() == BOO_BOO );
|
||||
BOOST_CHECK( ec.category() == boost::asio::asio_error );
|
||||
|
||||
// a real user can't rely on the value of an error_category object's value,
|
||||
// but in this test program that value is known, so test for it.
|
||||
BOOST_CHECK( ec.category().value() == boost::system::native_ecat.value()+1 );
|
||||
|
||||
// asio did not supply decoders, so test the defaults
|
||||
BOOST_CHECK( ec.to_errno() == EOTHER );
|
||||
BOOST_CHECK( ec.message() == "API error" );
|
||||
BOOST_CHECK( ec.wmessage() == L"API error" );
|
||||
return 0;
|
||||
}
|
84
test/system_error_test.cpp
Normal file
84
test/system_error_test.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
// system_error_test.cpp ---------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See library home page at http://www.boost.org/libs/system
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
// VC++ 8.0 warns on usage of certain Standard Library and API functions that
|
||||
// can be cause buffer overruns or other possible security issues if misused.
|
||||
// See http://msdn.microsoft.com/msdnmag/issues/05/05/SafeCandC/default.aspx
|
||||
// But the wording of the warning is misleading and unsettling, there are no
|
||||
// portable alternative functions, and VC++ 8.0's own libraries use the
|
||||
// functions in question. So turn off the warnings.
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _SCL_SECURE_NO_DEPRECATE
|
||||
|
||||
#include <boost/test/minimal.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <winerror.h>
|
||||
|
||||
using boost::system::system_error;
|
||||
using boost::system::error_code;
|
||||
using boost::system::errno_ecat;
|
||||
using boost::system::no_message;
|
||||
|
||||
#define TEST(x,v,w) test(#x,x,v,w)
|
||||
|
||||
namespace
|
||||
{
|
||||
void test( const char * desc, const system_error & ex,
|
||||
error_code::value_type v, const char * str )
|
||||
{
|
||||
std::cout << "test " << desc << "\n what() returns \"" << ex.what() << "\"\n";
|
||||
BOOST_CHECK( ex.code().value() == v );
|
||||
BOOST_CHECK( ex.code().category() == errno_ecat );
|
||||
# ifdef BOOST_WINDOWS_API
|
||||
BOOST_CHECK( std::string( ex.what() ) == str );
|
||||
if ( std::string( ex.what() ) != str )
|
||||
std::cout << "expected \"" << str << "\", but what() returned \""
|
||||
<< ex.what() << "\"\n";
|
||||
# endif
|
||||
}
|
||||
|
||||
const boost::uint_least32_t uvalue = 1u;
|
||||
}
|
||||
|
||||
int test_main( int, char *[] )
|
||||
{
|
||||
// all combinations of constructors:
|
||||
|
||||
system_error se_0( error_code(0, errno_ecat) );
|
||||
system_error se_1( 1, errno_ecat );
|
||||
system_error se_0_m( error_code(0, errno_ecat), "se_0_m" );
|
||||
system_error se_1_m( 1, errno_ecat, "se_1_m" );
|
||||
system_error se_0_nm( error_code(0, errno_ecat), "" );
|
||||
system_error se_1_nm( 1, errno_ecat, "" );
|
||||
system_error se_0_m_im( error_code(0, errno_ecat), "se_0_m_im", no_message );
|
||||
system_error se_1_m_im( 1, errno_ecat, "se_1_m_im", no_message );
|
||||
system_error se_0_nm_im( error_code(0, errno_ecat), "", no_message );
|
||||
system_error se_1_nm_im( 1, errno_ecat, "", no_message );
|
||||
system_error se_1u_m( uvalue, errno_ecat, "se_1u_m" );
|
||||
|
||||
TEST( se_0, 0, "" );
|
||||
TEST( se_1, 1, "Operation not permitted" );
|
||||
TEST( se_0_m, 0, "se_0_m" );
|
||||
TEST( se_1_m, 1, "se_1_m: Operation not permitted" );
|
||||
TEST( se_0_nm, 0, "" );
|
||||
TEST( se_1_nm, 1, "Operation not permitted" );
|
||||
TEST( se_0_m_im, 0, "se_0_m_im" );
|
||||
TEST( se_1_m_im, 1, "se_1_m_im" );
|
||||
TEST( se_0_nm_im, 0, "" );
|
||||
TEST( se_1_nm_im, 1, "" );
|
||||
TEST( se_1u_m, 1, "se_1u_m: Operation not permitted" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user