test_winapi_formatting.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. //
  2. // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. #ifdef BOOST_LOCALE_NO_WINAPI_BACKEND
  9. #include <iostream>
  10. int main()
  11. {
  12. std::cout << "WinAPI Backend is not build... Skipping" << std::endl;
  13. }
  14. #else
  15. #include <boost/locale/formatting.hpp>
  16. #include <boost/locale/localization_backend.hpp>
  17. #include <boost/locale/generator.hpp>
  18. #include <boost/locale/encoding.hpp>
  19. #include <boost/locale/info.hpp>
  20. #include <iomanip>
  21. #include "test_locale.hpp"
  22. #include "test_locale_tools.hpp"
  23. #include "../src/win32/lcid.hpp"
  24. #include <iostream>
  25. #include <time.h>
  26. #include <assert.h>
  27. #ifndef NOMINMAX
  28. #define NOMINMAX
  29. #endif
  30. #include <windows.h>
  31. #define DEBUG_FMT
  32. bool equal(std::string const &s1,std::wstring const &s2)
  33. {
  34. bool res = s1 == boost::locale::conv::from_utf(s2,"UTF-8");
  35. #ifdef DEBUG_FMT
  36. if(!res)
  37. std::cout << "[" << s1 << "]!=["<<boost::locale::conv::from_utf(s2,"UTF-8")<<"]"<<std::endl;
  38. #endif
  39. return res;
  40. }
  41. bool equal(std::wstring const &s1,std::wstring const &s2)
  42. {
  43. bool res = s1 == s2;
  44. #ifdef DEBUG_FMT
  45. if(!res)
  46. std::cout << "[" << boost::locale::conv::from_utf(s1,"UTF-8") << "]!=["<<boost::locale::conv::from_utf(s2,"UTF-8")<<"]"<<std::endl;
  47. #endif
  48. return res;
  49. }
  50. bool equal(std::string const &s1,std::string const &s2)
  51. {
  52. bool res = s1 == s2;
  53. #ifdef DEBUG_FMT
  54. if(!res)
  55. std::cout << "[" << s1 << "]!=["<<s2<<"]"<<std::endl;
  56. #endif
  57. return res;
  58. }
  59. bool equal(std::wstring const &s1,std::string const &s2)
  60. {
  61. bool res = s1 == boost::locale::conv::to_utf<wchar_t>(s2,"UTF-8");
  62. #ifdef DEBUG_FMT
  63. if(!res)
  64. std::cout << "[" << boost::locale::conv::from_utf(s1,"UTF-8") << "]!=["<<s2<<"]"<<std::endl;
  65. #endif
  66. return res;
  67. }
  68. template<typename CharType>
  69. std::basic_string<CharType> conv_to_char(char const *p)
  70. {
  71. std::basic_string<CharType> r;
  72. while(*p)
  73. r+=CharType(*p++);
  74. return r;
  75. }
  76. template<typename CharType>
  77. void test_by_char(std::locale const &l,std::string name,int lcid)
  78. {
  79. typedef std::basic_stringstream<CharType> ss_type;
  80. typedef std::basic_string<CharType> string_type;
  81. using namespace boost::locale;
  82. {
  83. std::cout << "--- Testing as::posix" << std::endl;
  84. ss_type ss;
  85. ss.imbue(l);
  86. ss << 1045.45;
  87. TEST(ss);
  88. double n;
  89. ss >> n;
  90. TEST(ss);
  91. TEST(n == 1045.45);
  92. TEST(equal(ss.str(),"1045.45"));
  93. }
  94. {
  95. std::cout << "--- Testing as::number" << std::endl;
  96. ss_type ss;
  97. ss.imbue(l);
  98. ss << as::number;
  99. ss << 1045.45;
  100. TEST(ss);
  101. double n;
  102. ss >> n;
  103. TEST(ss);
  104. TEST(n == 1045.45);
  105. if(name == "ru_RU.UTF-8") {
  106. if(sizeof(CharType)==1)
  107. TEST(equal(ss.str(),"1 045,45")); // SP
  108. else
  109. TEST(equal(ss.str(),"1\xC2\xA0" "045,45")); // NBSP
  110. }
  111. else
  112. TEST(equal(ss.str(),"1,045.45"));
  113. }
  114. {
  115. std::cout << "--- Testing as::currency " << std::endl;
  116. ss_type ss;
  117. ss.imbue(l);
  118. ss << as::currency;
  119. ss << 1043.34;
  120. TEST(ss);
  121. wchar_t buf[256];
  122. GetCurrencyFormatW(lcid,0,L"1043.34",0,buf,256);
  123. TEST(equal(ss.str(),buf));
  124. }
  125. {
  126. std::cout << "--- Testing as::date/time" << std::endl;
  127. ss_type ss;
  128. ss.imbue(l);
  129. time_t a_date = 3600*24*(31+4); // Feb 5th
  130. time_t a_time = 3600*15+60*33; // 15:33:13
  131. time_t a_timesec = 13;
  132. time_t a_datetime = a_date + a_time + a_timesec;
  133. ss << as::time_zone("GMT");
  134. ss << as::date << a_datetime << CharType('\n');
  135. ss << as::time << a_datetime << CharType('\n');
  136. ss << as::datetime << a_datetime << CharType('\n');
  137. ss << as::time_zone("GMT+01:00");
  138. ss << as::ftime(conv_to_char<CharType>("%H")) << a_datetime << CharType('\n');
  139. ss << as::time_zone("GMT+00:15");
  140. ss << as::ftime(conv_to_char<CharType>("%M")) << a_datetime << CharType('\n');
  141. wchar_t time_buf[256];
  142. wchar_t date_buf[256];
  143. SYSTEMTIME st= { 1970, 2,5, 5,15,33,13,0 };
  144. GetTimeFormatW(lcid,0,&st,0,time_buf,256);
  145. GetDateFormatW(lcid,0,&st,0,date_buf,256);
  146. TEST(equal(ss.str(),std::wstring(date_buf)+L"\n" + time_buf +L"\n" + date_buf + L" " + time_buf + L"\n16\n48\n"));
  147. }
  148. }
  149. void test_date_time(std::locale l)
  150. {
  151. std::ostringstream ss;
  152. ss.imbue(l);
  153. ss << boost::locale::as::time_zone("GMT");
  154. time_t a_date = 3600*24*(31+4); // Feb 5th
  155. time_t a_time = 3600*15+60*33; // 15:33:13
  156. time_t a_timesec = 13;
  157. time_t a_datetime = a_date + a_time + a_timesec;
  158. std::string pat[] = {
  159. "a", "Thu",
  160. "A", "Thursday",
  161. "b", "Feb",
  162. "B", "February",
  163. "d", "05",
  164. "D", "02/05/70",
  165. "e", "5",
  166. "h", "Feb",
  167. "H", "15",
  168. "I", "03",
  169. "m", "02",
  170. "M", "33",
  171. "n", "\n",
  172. "p", "PM",
  173. "r", "03:33:13 PM",
  174. "R", "15:33",
  175. "S", "13",
  176. "t", "\t",
  177. "y", "70",
  178. "Y", "1970",
  179. "%", "%"
  180. };
  181. for(unsigned i=0;i<sizeof(pat)/sizeof(pat[0]);i+=2) {
  182. ss.str("");
  183. ss << boost::locale::as::ftime("%" + pat[i]) << a_datetime;
  184. TEST(equal(ss.str(),pat[i+1]));
  185. }
  186. }
  187. int main()
  188. {
  189. try {
  190. boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
  191. mgr.select("winapi");
  192. boost::locale::localization_backend_manager::global(mgr);
  193. boost::locale::generator gen;
  194. std::string name;
  195. std::string names[] = { "en_US.UTF-8", "he_IL.UTF-8", "ru_RU.UTF-8" };
  196. int lcids[] = { 0x0409, 0x040D ,0x0419 };
  197. for(unsigned i=0;i<sizeof(names)/sizeof(names[9]);i++) {
  198. name = names[i];
  199. std::cout << "- " << name << " locale" << std::endl;
  200. if(boost::locale::impl_win::locale_to_lcid(name) == 0) {
  201. std::cout << "-- not supported, skipping" << std::endl;
  202. continue;
  203. }
  204. std::locale l1=gen(name);
  205. std::cout << "-- UTF-8" << std::endl;
  206. test_by_char<char>(l1,name,lcids[i]);
  207. std::cout << "-- UTF-16" << std::endl;
  208. test_by_char<wchar_t>(l1,name,lcids[i]);
  209. }
  210. std::cout << "- Testing strftime" <<std::endl;
  211. test_date_time(gen("en_US.UTF-8"));
  212. }
  213. catch(std::exception const &e) {
  214. std::cerr << "Failed " << e.what() << std::endl;
  215. return EXIT_FAILURE;
  216. }
  217. FINALIZE();
  218. }
  219. #endif // no winapi
  220. // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
  221. // boostinspect:noascii