[complement-svn] SF.net SVN: complement:[1951] trunk/complement/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2008-07-25 06:35:19
|
Revision: 1951 http://complement.svn.sourceforge.net/complement/?rev=1951&view=rev Author: complement Date: 2008-07-25 06:35:15 +0000 (Fri, 25 Jul 2008) Log Message: ----------- system_error basic functionality; libxmt version 2.0.8 basic functionality of system_error and friends, as described in http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2691.pdf; no locale support; no real difference between system_category and posix_category; basic trivial test for system_error. Modified Paths: -------------- trunk/complement/explore/include/mt/system_error trunk/complement/explore/lib/mt/ChangeLog trunk/complement/explore/lib/mt/Makefile.inc trunk/complement/explore/lib/mt/system_error.cc trunk/complement/explore/lib/mt/ut/Makefile.inc trunk/complement/explore/lib/mt/ut/mt_test_suite.cc Added Paths: ----------- trunk/complement/explore/lib/mt/ut/sys_err_test.cc trunk/complement/explore/lib/mt/ut/sys_err_test.h Modified: trunk/complement/explore/include/mt/system_error =================================================================== --- trunk/complement/explore/include/mt/system_error 2008-07-25 06:34:37 UTC (rev 1950) +++ trunk/complement/explore/include/mt/system_error 2008-07-25 06:35:15 UTC (rev 1951) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/07/20 19:12:24 ptr> +// -*- C++ -*- Time-stamp: <08/07/25 08:47:37 ptr> /* * Copyright (c) 2007-2008 @@ -25,6 +25,7 @@ #endif #include <cerrno> +#include <ostream> namespace std { @@ -413,6 +414,36 @@ static const error_category& posix_category = get_posix_category(); static const error_category& native_category = get_system_category(); +class error_condition +{ + public: + error_condition(); + error_condition( int val, const error_category& category ); + template <class ErrorConditionEnum> + error_condition( ErrorConditionEnum err, + typename std::tr1::enable_if<is_error_condition_enum<ErrorConditionEnum>::value,void>::type* = 0 ); + + void assign( int val, const error_category& category ); + template <class ErrorConditionEnum> + typename std::tr1::enable_if<is_error_condition_enum<ErrorConditionEnum>::value, error_code >::type& operator =( ErrorConditionEnum err ); + void clear(); + + int value() const + { return v; } + const error_category& category() const + { return *c; } + string message() const + { return c->message( v ); } + operator bool() const + { return v != 0; } + + private: + int v; + const error_category* c; +}; + +bool operator <( const error_condition&, const error_condition& ); + class error_code { public: @@ -426,57 +457,50 @@ typename std::tr1::enable_if<is_error_code_enum<ErrorCodeEnum>::value, error_code >::type& operator =( ErrorCodeEnum err ); void clear(); - int value() const; - const error_category& category() const; - error_condition default_error_condition() const; - string message() const; - operator bool() const; + int value() const + { return v; } + const error_category& category() const + { return *c; } + error_condition default_error_condition() const + { return c->default_error_condition( v ); } + string message() const + { return c->message( v ); } + operator bool() const + { return v != 0; } private: int v; - const error_category& c; + const error_category* c; }; bool operator <( const error_code&, const error_code& ); +template <class charT, class traits> +basic_ostream<charT,traits>& operator <<( basic_ostream<charT,traits>& os, const error_code& e ) +{ return os << e.category().name() << ':' << e.value(); } -class error_condition -{ - public: - error_condition(); - error_condition( int val, const error_category& category ); - template <class ErrorConditionEnum> - error_condition( ErrorConditionEnum err, - typename std::tr1::enable_if<is_error_condition_enum<ErrorConditionEnum>::value,void>::type* = 0 ); - - void assign( int val, const error_category& category ); - template <class ErrorConditionEnum> - typename std::tr1::enable_if<is_error_condition_enum<ErrorConditionEnum>::value, error_code >::type& operator =( ErrorConditionEnum err ); - void clear(); - - int value() const; - const error_category& category() const; - string message() const; - operator bool() const; - - private: - int val_; - const error_category& cat_; -}; - -bool operator <( const error_condition&, const error_condition& ); - class system_error : public runtime_error { public: system_error( error_code code, const string& what ); system_error( error_code code ); - system_error( error_code code, const error_category& category, + system_error( int code, const error_category& category, const string& what ); - system_error( error_code code, const error_category& category ); - error_code& code() const throw(); + system_error( int code, const error_category& category ); + ~system_error() throw(); + + const error_code& code() const throw() + { return ecode_; } const char* what() const throw(); + + private: + error_code ecode_; + + enum { _bufsize = 256 }; + + mutable char _buf[_bufsize]; + mutable char *_dbuf; }; } // namespace std Modified: trunk/complement/explore/lib/mt/ChangeLog =================================================================== --- trunk/complement/explore/lib/mt/ChangeLog 2008-07-25 06:34:37 UTC (rev 1950) +++ trunk/complement/explore/lib/mt/ChangeLog 2008-07-25 06:35:15 UTC (rev 1951) @@ -1,3 +1,16 @@ +2008-07-25 Petr Ovtchenkov <pt...@is...> + + * system_error, system_error.cc: basic functionality + of system_error and friends, as described in + http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2691.pdf; + no locale support; no real difference between system_category + and posix_category; + + * mt_test_suite.cc, sys_err_test.h, sys_err_test.cc: basic + trivial test for system_error; + + * libxmt: bump revision to 2.0.8. + 2008-07-21 Petr Ovtchenkov <pt...@is...> * mutex: avoid usage of error_catalog---interface in Modified: trunk/complement/explore/lib/mt/Makefile.inc =================================================================== --- trunk/complement/explore/lib/mt/Makefile.inc 2008-07-25 06:34:37 UTC (rev 1950) +++ trunk/complement/explore/lib/mt/Makefile.inc 2008-07-25 06:35:15 UTC (rev 1951) @@ -1,9 +1,9 @@ -# -*- Makefile -*- Time-stamp: <08/07/07 10:35:20 ptr> +# -*- Makefile -*- Time-stamp: <08/07/25 10:25:30 ptr> LIBNAME = xmt MAJOR = 2 MINOR = 0 -PATCH = 7 +PATCH = 8 SRC_CC = xmt.cc thr_mgr.cc time.cc uid.cc shm.cc callstack.cc system_error.cc thread.cc \ date_time.cc SRC_C = fl.c Modified: trunk/complement/explore/lib/mt/system_error.cc =================================================================== --- trunk/complement/explore/lib/mt/system_error.cc 2008-07-25 06:34:37 UTC (rev 1950) +++ trunk/complement/explore/lib/mt/system_error.cc 2008-07-25 06:35:15 UTC (rev 1951) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/07/20 19:55:22 ptr> +// -*- C++ -*- Time-stamp: <08/07/25 10:04:45 ptr> /* * Copyright (c) 2007-2008 @@ -8,8 +8,7 @@ * * Based on JTC1/SC22/WG21 C++ 0x working draft; * - * This is revision 2 of <system_error>: - * http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2007/n2303.html + * http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2691.pdf */ #include "mt/system_error" @@ -261,7 +260,7 @@ * An operation that would block was attempted on an object that has non-blocking mode selected. Trying the same operation again will block until some external condition makes it possible to read, write, or - connect (whatever the operation). You can use @code{select} to find out + connect (whatever the operation). You can use select to find out when the operation will be possible. Portability Note: In many older Unix systems, this condition @@ -543,10 +542,10 @@ _sys_err[EILSEQ] = "Invalid or incomplete multibyte or wide character"; #endif #ifdef EBACKGROUND - /* In the GNU system, servers supporting the @code{term} protocol return + /* In the GNU system, servers supporting the term protocol return this error for certain operations when the caller is not in the foreground process group of the terminal. Users do not usually see this - error because functions such as @code{read} and @code{write} translate + error because functions such as read and write translate it into a SIGTTIN or SIGTTOU signal. */ _sys_err[EBACKGROUND] = "Inappropriate operation for background process"; #endif @@ -824,7 +823,6 @@ public: virtual const char* name() const; virtual std::string message( int err ) const; - }; const char* posix_error_category::name() const @@ -867,6 +865,9 @@ using namespace detail; +error_category::~error_category() +{ } + error_condition error_category::default_error_condition( int err ) const { return error_condition( err, *this ); @@ -907,5 +908,171 @@ return detail::_system_error_category; } +error_code::error_code() : + v( 0 ), + c( &detail::_system_error_category ) +{ } + +error_code::error_code( int val, const error_category& cat ) : + v( val ), + c( &cat ) +{ } + +void error_code::assign( int val, const error_category& cat ) +{ + v = val; + c = &cat; +} + +void error_code::clear() +{ + v = 0; + c = &detail::_system_error_category; +} + +namespace posix_error { + +error_code make_error_code( posix_errno err ) +{ return error_code( err, detail::_posix_error_category ); } + +error_condition make_error_condition( posix_errno err ) +{ return error_condition( err, detail::_posix_error_category ); } + +} // namespace posix_error + +bool operator <( const error_code& l, const error_code& r ) +{ + return l.category() == r.category() ? l.value() < r.value() : l.category() < r.category(); +} + +error_condition::error_condition() : + v( 0 ), + c( &detail::_posix_error_category ) +{ } + +error_condition::error_condition( int val, const error_category& cat ) : + v( val ), + c( &cat ) +{ } + +void error_condition::assign( int val, const error_category& cat ) +{ + v = val; + c = &cat; +} + +void error_condition::clear() +{ + v = 0; + c = &detail::_posix_error_category; +} + +bool operator <( const error_condition& l, const error_condition& r ) +{ + return l.category() == r.category() ? l.value() < r.value() : l.category() < r.category(); +} + +bool operator ==( const error_code& l, const error_code& r ) +{ return l.category() == r.category() && l.value() == r.value(); } + +bool operator ==( const error_code& l, const error_condition& r ) +{ return l.category().equivalent( l.value(), r ) || r.category().equivalent( l, r.value() ); } + +bool operator ==( const error_condition& l, const error_code& r ) +{ return r.category().equivalent( r.value(), l ) || l.category().equivalent( r, l.value() ); } + +bool operator ==( const error_condition& l, const error_condition& r ) +{ return l.category() == r.category() && l.value() == r.value(); } + +bool operator !=( const error_code& l, const error_code& r ) +{ return !(l == r); } + +bool operator !=( const error_code& l, const error_condition& r ) +{ return !(l == r); } + +bool operator !=( const error_condition& l, const error_code& r ) +{ return !(l == r); } + +bool operator !=( const error_condition& l, const error_condition& r ) +{ return !(l == r); } + +system_error::system_error( error_code code, const string& what ) : + runtime_error( what ), + ecode_( code.value(), code.category() ), + _dbuf( 0 ) +{ } + +system_error::system_error( error_code code ) : + runtime_error( "" ), + ecode_( code.value(), code.category() ), + _dbuf( 0 ) +{ } + +system_error::system_error( int code, const error_category& category, + const string& what ) : + runtime_error( what ), + ecode_( code, category ), + _dbuf( 0 ) +{ } + +system_error::system_error( int code, const error_category& category ) : + runtime_error( "" ), + ecode_( code, category ), + _dbuf( 0 ) +{ } + +system_error::~system_error() throw() +{ + if ( _dbuf ) { + free( _dbuf ); + } +} + +const char* system_error::what() const throw() +{ + size_t sz = strlen( runtime_error::what() ); + size_t sz_add = sz + ecode_.message().length() + (sz > 0 ? 3 : 1); // + ": ", not \0 + + if ( sz_add < _bufsize ) { + if ( sz > 0 ) { + memcpy( _buf, runtime_error::what(), sz ); + _buf[sz++] = ':'; + _buf[sz++] = ' '; + } + memcpy( _buf + sz, ecode_.message().data(), ecode_.message().length() ); + _buf[sz_add - 1] = 0; + } else { + _dbuf = static_cast<char *>(malloc( sz_add )); + if ( _dbuf != 0 ) { + if ( sz > 0 ) { + memcpy( _dbuf, runtime_error::what(), sz ); + _dbuf[sz++] = ':'; + _dbuf[sz++] = ' '; + } + memcpy( _dbuf + sz, ecode_.message().data(), ecode_.message().length() ); + _dbuf[sz_add - 1] = 0; + return _dbuf; + } + if ( sz > 0 ) { + strncpy( _buf, runtime_error::what(), _bufsize - 1 ); + } + if ( sz < (_bufsize - 1) ) { + if ( sz > 0 ) { + _buf[sz++] = ':'; + } + if ( sz < (_bufsize - 1) ) { + if ( sz > 0 ) { + _buf[sz++] = ' '; + } + if ( sz < (_bufsize - 1) ) { + strncpy( _buf + sz, ecode_.message().data(), _bufsize - sz - 1 ); + } + } + } + _buf[_bufsize - 1] = 0; + } + + return _buf; +} + } // namespace std - Modified: trunk/complement/explore/lib/mt/ut/Makefile.inc =================================================================== --- trunk/complement/explore/lib/mt/ut/Makefile.inc 2008-07-25 06:34:37 UTC (rev 1950) +++ trunk/complement/explore/lib/mt/ut/Makefile.inc 2008-07-25 06:35:15 UTC (rev 1951) @@ -1,7 +1,7 @@ -# -*- makefile -*- Time-stamp: <08/07/02 09:03:03 ptr> +# -*- makefile -*- Time-stamp: <08/07/25 09:39:59 ptr> PRGNAME = mt_ut -SRC_CC = timespec.cc \ +SRC_CC = sys_err_test.cc timespec.cc \ signal-1.cc signal-3.cc \ mt_test.cc shm_test.cc mt_test_suite.cc \ mt_test_wg21.cc Modified: trunk/complement/explore/lib/mt/ut/mt_test_suite.cc =================================================================== --- trunk/complement/explore/lib/mt/ut/mt_test_suite.cc 2008-07-25 06:34:37 UTC (rev 1950) +++ trunk/complement/explore/lib/mt/ut/mt_test_suite.cc 2008-07-25 06:35:15 UTC (rev 1951) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/07/07 13:15:01 yeti> +// -*- C++ -*- Time-stamp: <08/07/25 09:43:40 ptr> /* * Copyright (c) 2006-2008 @@ -12,6 +12,7 @@ #include "mt_test.h" #include "shm_test.h" #include "mt_test_wg21.h" +#include "sys_err_test.h" #include <config/feature.h> @@ -30,6 +31,7 @@ int main( int argc, const char** argv ) { exam::test_suite t( "libxmt test" ); + sys_err_test sys_err; mt_test test; #if 0 @@ -44,6 +46,7 @@ exam::test_suite::test_case_type tc[3]; + t.add( &sys_err_test::file, sys_err, "system error, no such file" ); // t.add( &mt_test::callstack, test, "callstack" ); tc[0] = t.add( &mt_test::barrier, test, "mt_test::barrier" ); tc[1] = t.add( &mt_test::join_test, test, "mt_test::join_test" ); Added: trunk/complement/explore/lib/mt/ut/sys_err_test.cc =================================================================== --- trunk/complement/explore/lib/mt/ut/sys_err_test.cc (rev 0) +++ trunk/complement/explore/lib/mt/ut/sys_err_test.cc 2008-07-25 06:35:15 UTC (rev 1951) @@ -0,0 +1,41 @@ +// -*- C++ -*- Time-stamp: <08/07/25 10:08:26 ptr> + +/* + * Copyright (c) 2008 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +#include "sys_err_test.h" + +#include <mt/system_error> +#include <cerrno> +#include <string> + +// #include <iostream> + +#include <stdio.h> + +using namespace std; + +int EXAM_IMPL(sys_err_test::file) +{ + FILE* f = fopen( "/tmp/no-such-file", "r" ); + + if ( f == 0 ) { + system_error se1( errno, std::get_posix_category(), string( "Test" ) ); + + EXAM_CHECK( strcmp( se1.what(), "Test: No such file or directory" ) == 0 ); + + system_error se2( errno, std::get_posix_category() ); + + EXAM_CHECK( strcmp( se2.what(), "No such file or directory" ) == 0 ); + } else { + EXAM_ERROR( "file exist, but shouldn't" ); + fclose( f ); + } + + return EXAM_RESULT; +} Added: trunk/complement/explore/lib/mt/ut/sys_err_test.h =================================================================== --- trunk/complement/explore/lib/mt/ut/sys_err_test.h (rev 0) +++ trunk/complement/explore/lib/mt/ut/sys_err_test.h 2008-07-25 06:35:15 UTC (rev 1951) @@ -0,0 +1,24 @@ +// -*- C++ -*- Time-stamp: <08/07/25 09:34:11 ptr> + +/* + * Copyright (c) 2008 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +#ifndef __SYS_ERR_TEST_H +#define __SYS_ERR_TEST_H + +#define FIT_EXAM + +#include <exam/suite.h> + +class sys_err_test +{ + public: + int EXAM_DECL(file); +}; + +#endif // __SYS_ERR_TEST_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |