Ticket #408: pserror-stream.patch

File pserror-stream.patch, 4.3 KB (added by Markus, 11 years ago)
  • trunk/source/ps/Errors.cpp

    diff -Nur a/trunk/source/ps/Errors.cpp b/trunk/source/ps/Errors.cpp
    a b  
    448448PSRETURN PSERROR_Xeromyces_XMLParseError::getCode() const { return 0x0d000002; }
    449449
    450450
    451 PSERROR::PSERROR(const char* msg) : m_msg(msg) { }
     451PSERROR::PSERROR(const char* msg)
     452{
     453    if (msg)
     454        m_msg = msg;
     455    m_os << m_msg;
     456}
    452457
    453458const char* PSERROR::what() const throw ()
    454459{
    455     return m_msg ? m_msg : GetErrorString(getCode());
     460    if (m_msg.empty())
     461        return GetErrorString(getCode());
     462    return m_msg.c_str();
     463}
     464
     465PSERROR::PSERROR(const PSERROR &a) : m_msg(a.m_msg)
     466{
     467    m_os << m_msg;
    456468}
    457469
    458470const char* GetErrorString(PSRETURN code)
  • trunk/source/ps/Errors.h

    diff -Nur a/trunk/source/ps/Errors.h b/trunk/source/ps/Errors.h
    a b  
    5656
    5757    void bar() { throw PSERROR_ModuleName_FrobnificationFailed("More informative message"); }
    5858
     59    void foobar() { throw PSERROR_ModuleName_FrobnificationFailed("More informative message") << something << " more text"; }
     60
    5961    try {
    6062        foo();
    6163    } catch (PSERROR_ModuleName_FrobnificationFailed& e) {
     
    7173*/
    7274
    7375#include <exception>
     76#include <sstream>
     77
     78#include <boost/utility/enable_if.hpp>
     79#include <boost/type_traits/is_base_of.hpp>
     80
     81#include "lib/utf8.h"
    7482
    7583typedef u32 PSRETURN;
    7684
     
    8088    PSERROR(const char* msg);
    8189    virtual const char* what() const throw ();
    8290    virtual PSRETURN getCode() const = 0; // for functions that catch exceptions then return error codes
     91
     92    PSERROR(const PSERROR &a);
     93    ~PSERROR() throw () {}
    8394private:
    84     const char* m_msg;
     95    std::string m_msg;
     96    std::ostringstream m_os;
     97   
     98    template <typename T, typename U>
     99    friend
     100    typename boost::enable_if<boost::is_base_of<PSERROR, T>, T>::type
     101    operator<<(T err, const U& a)
     102    {
     103        err.m_os << a;
     104        err.m_msg = err.m_os.str();
     105        return err;
     106    }
     107    template <typename T>
     108    friend
     109    typename boost::enable_if<boost::is_base_of<PSERROR, T>, T>::type
     110    operator<<(T err, const std::wstring& a)
     111    {
     112        err.m_os << utf8_from_wstring(a, NULL);
     113        err.m_msg = err.m_os.str();
     114        return err;
     115    }
    85116};
    86117
    87118#define ERROR_GROUP(a) class PSERROR_##a : public PSERROR { protected: PSERROR_##a(const char* msg); }; \
  • trunk/source/ps/tests/test_Errors.h

    diff -Nur a/trunk/source/ps/tests/test_Errors.h b/trunk/source/ps/tests/test_Errors.h
    a b  
     1/* Copyright (C) 2013 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#include "lib/self_test.h"
     19
     20#include "ps/Errors.h"
     21#include "ps/Errors.cpp"
     22
     23class TestPSERROR : public CxxTest::TestSuite
     24{
     25public:
     26    void test_throwcatch()
     27    {
     28        int cnt = 0;
     29       
     30        try
     31        {
     32            cnt--;
     33            throw PSERROR_File_OpenFailed();
     34        }
     35        catch (PSERROR_File_OpenFailed &e)
     36        {
     37            TS_ASSERT_STR_EQUALS(e.what(), "File_OpenFailed");
     38            cnt++;
     39        }
     40
     41        try
     42        {
     43            cnt--;
     44            throw PSERROR_File_OpenFailed("test") << 123 << "abc";
     45        }
     46        catch (PSERROR_File_OpenFailed &e) // exact match
     47        {
     48            TS_ASSERT_STR_EQUALS(e.what(), "test123abc");
     49            cnt++;
     50        }
     51
     52        try
     53        {
     54            cnt--;
     55            throw PSERROR_File_OpenFailed("test") << 123 << "abc";
     56        }
     57        catch (PSERROR &e) // parent
     58        {
     59            TS_ASSERT_STR_EQUALS(e.what(), "test123abc");
     60            cnt++;
     61        }
     62
     63        try
     64        {
     65            cnt--;
     66            std::wstring wstr(L"äöü");
     67            throw PSERROR_File_OpenFailed("test") << 123 << wstr;
     68        }
     69        catch (PSERROR_File_OpenFailed &e)
     70        {
     71            TS_ASSERT_STR_EQUALS(e.what(), "test123äöü");
     72            cnt++;
     73        }
     74       
     75        TS_ASSERT_EQUALS(cnt, 0);
     76    }
     77};