123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- //
- // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
- //
- // 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_LOCALE_TEST_H
- #define BOOST_LOCALE_TEST_H
- #include <stdexcept>
- #include <sstream>
- #include <iostream>
- #include <iomanip>
- #include <cstdlib>
- #include <string>
- int error_counter=0;
- int test_counter=0;
- #ifndef BOOST_LOCALE_ERROR_LIMIT
- #define BOOST_LOCALE_ERROR_LIMIT 20
- #endif
- #define THROW_IF_TOO_BIG(X) \
- do { \
- if((X) > BOOST_LOCALE_ERROR_LIMIT) \
- throw std::runtime_error("Error limits reached, stopping unit test"); \
- }while(0)
- #define TEST(X) \
- do { \
- test_counter++; \
- if(X) break; \
- std::cerr << "Error in line:"<<__LINE__ << " "#X << std::endl; \
- THROW_IF_TOO_BIG(error_counter++); \
- }while(0)
- #endif
- #define TEST_THROWS(X,E) \
- do { \
- test_counter++; \
- try { X; } catch(E const &/*e*/ ) {break;} catch(...){} \
- std::cerr << "Error in line:"<<__LINE__ << " "#X << std::endl; \
- THROW_IF_TOO_BIG(error_counter++); \
- }while(0)
- #define FINALIZE() \
- do { \
- int passed=test_counter - error_counter; \
- std::cout << std::endl; \
- std::cout << "Passed "<<passed<<" tests" << std::endl; \
- if(error_counter >0 ) { \
- std::cout << "Failed "<<error_counter<<" tests"<<std::endl; \
- } \
- std::cout <<" "<< std::fixed << std::setprecision(1) \
- << std::setw(5) << 100.0 * passed / test_counter << \
- "% of tests completed sucsessefully" << std::endl; \
- return error_counter == 0 ? EXIT_SUCCESS : EXIT_FAILURE ; \
- }while(0)
- inline unsigned utf8_next(std::string const &s,unsigned &pos)
- {
- unsigned c=(unsigned char)s[pos++];
- if( (unsigned char)(c - 0xc0) >= 0x35)
- return c;
- unsigned l;
- if(c < 192)
- l = 0;
- else if(c < 224)
- l = 1;
- else if(c < 240)
- l = 2;
- else
- l = 3;
-
- c&=(1<<(6-l))-1;
-
- switch(l) {
- case 3:
- c = (c << 6) | (((unsigned char)s[pos++]) & 0x3F);
- case 2:
- c = (c << 6) | (((unsigned char)s[pos++]) & 0x3F);
- case 1:
- c = (c << 6) | (((unsigned char)s[pos++]) & 0x3F);
- }
- return c;
- }
- template<typename Char>
- std::basic_string<Char> to(std::string const &utf8)
- {
- std::basic_string<Char> out;
- unsigned i=0;
- while(i<utf8.size()) {
- unsigned point;
- unsigned prev=i;
- point = utf8_next(utf8,i);
- if(sizeof(Char)==1 && point > 255) {
- std::ostringstream ss;
- ss << "Can't convert codepoint U" << std::hex << point <<"(" <<std::string(utf8.begin()+prev,utf8.begin()+i)<<") to Latin1";
- throw std::runtime_error(ss.str());
- }
- else if(sizeof(Char)==2 && point >0xFFFF) { // Deal with surragates
- point-=0x10000;
- out+=static_cast<Char>(0xD800 | (point>>10));
- out+=static_cast<Char>(0xDC00 | (point & 0x3FF));
- continue;
- }
- out+=static_cast<Char>(point);
- }
- return out;
- }
- // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|