Bring into compliance with N2066, TR2 Diagnostics Enhancements. Tests passing on Win32, Linux, on most modern compilers.

[SVN r35823]
This commit is contained in:
Beman Dawes
2006-11-03 16:57:30 +00:00
commit f3c8c74656
11 changed files with 1445 additions and 0 deletions

96
.gitattributes vendored Normal file
View 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
View 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
View 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>
&nbsp;&nbsp;&nbsp; <a href="#Class-error_category-members">Members</a><br>
<a href="#Class-error_code">Class <code>error_code</code></a><br>
&nbsp;&nbsp;&nbsp; <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&nbsp;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&nbsp;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 &amp;&amp; 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 &amp;&amp; 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 &amp;&amp; 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>&nbsp;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>&nbsp;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>&nbsp;<code>errno_decoder ed;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message_decoder md;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wmessage_decoder wmd;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool ok( get_decoders( category(), ed, md,
wmd ) );</code></p>
<p><i>Returns:</i>&nbsp; If <code>ok &amp;&amp; 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>&nbsp;<code>errno_decoder ed;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message_decoder md;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wmessage_decoder wmd;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool ok( get_decoders( category(), ed, md,
wmd ) );</code></p>
<p><i>Returns:</i>&nbsp; If <code>ok &amp;&amp; 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>.&nbsp; <i>--end note.]</i></p>
</blockquote>
<pre>wstring_t <a name="wmessage">wmessage</a>() const;</pre>
<blockquote>
<p><i>Effects: </i>&nbsp;<code>errno_decoder ed;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message_decoder md;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wmessage_decoder wmd;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool ok( get_decoders( category(), ed, md,
wmd ) );</code></p>
<p><i>Returns:</i>&nbsp; If <code>ok &amp;&amp; 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>.&nbsp; <i>--end note.]</i></p>
</blockquote>
<pre>bool <a name="operator-eq">operator</a>==(const error_code &amp; rhs) const;</pre>
<blockquote>
<p><i>Returns:</i> <code>value() == rhs.value() &amp;&amp; category() == rhs.category()</code>.</p>
</blockquote>
<pre>bool <a name="operator-ne">operator!</a>=(const error_code &amp; rhs) const;</pre>
<blockquote>
<p><i>Returns:</i> <code>!(*this == rhs)</code>.</p>
</blockquote>
<pre>bool <a name="operator-lt">operator</a>&lt;(const error_code &amp; rhs) const;</pre>
<blockquote>
<p><i>Returns:</i> <code>category() &lt; rhs.category() || ( category() ==
rhs.category() &amp;&amp; value() &lt; rhs.value() )</code>.</p>
</blockquote>
<pre>bool <a name="operator-le">operator</a>&lt;=(const error_code &amp; rhs) const;</pre>
<blockquote>
<p><i>Returns:</i> <code>*this == rhs || *this &lt; rhs</code>.</p>
</blockquote>
<pre>bool <a name="operator-gt">operator</a>&gt;(const error_code &amp; rhs) const;</pre>
<blockquote>
<p><i>Returns:</i> <code>!(*this &lt;= rhs)</code>.</p>
</blockquote>
<pre>bool <a name="operator-ge">operator</a>&gt;=(const error_code &amp; rhs) const;</pre>
<blockquote>
<p><i>Returns:</i> <code>!(*this &lt; 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>&nbsp;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>&nbsp;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>,&nbsp;
<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 &amp; ed, message_decoder &amp; md, wmessage_decoder &amp; wmd );</pre>
<blockquote>
<p><i>Effects:</i> If <code>cat</code> was created by <code>new_category()</code>,
sets <code>ed</code>,&nbsp; <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 &amp; ec );</pre>
<blockquote>
<p><i>Returns: </i>&nbsp;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
View 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>
&nbsp;&nbsp;&nbsp; <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 &amp; 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 &amp; what_arg, message_action ma = append_message );
virtual ~system_error() throw() {}
const error_code &amp; <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 &amp;&amp; *runtime_error::what() == '\0'
&amp;&amp; </code><code>m_append_message</code>.</p>
</blockquote>
<pre><a name="system_error-2">system_error</a>( error_code ec, const std::string &amp; 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 &amp;&amp; std::string(runtime_error::what())
== </code><code>what_arg</code><code> &amp;&amp; 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) &amp;&amp; *runtime_error::what()
== '\0' &amp;&amp; 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 &amp; 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) &amp;&amp; std::string(runtime_error::what())
== </code><code>what_arg</code><code> &amp;&amp; m_append_message == ma</code>.</p>
</blockquote>
<pre>const error_code &amp; <a name="code">code</a>() const throw();</pre>
<blockquote>
<p><i>Returns: </i>&nbsp;<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 += &quot;: &quot;;
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>

View 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

View 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

View 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
View 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
View 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;
}

View 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;
}

View 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;
}