locale_impl.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /*
  2. * Copyright (c) 1999
  3. * Silicon Graphics Computer Systems, Inc.
  4. *
  5. * Copyright (c) 1999
  6. * Boris Fomitchev
  7. *
  8. * This material is provided "as is", with absolutely no warranty expressed
  9. * or implied. Any use is at your own risk.
  10. *
  11. * Permission to use or copy this software for any purpose is hereby granted
  12. * without fee, provided the above notices are retained on all copies.
  13. * Permission to modify the code and to distribute modified code is granted,
  14. * provided the above notices are retained, and a notice that the code was
  15. * modified is included with the above copyright notice.
  16. *
  17. */
  18. #include "stlport_prefix.h"
  19. #include <locale>
  20. #include <algorithm>
  21. #include <typeinfo>
  22. #include "c_locale.h"
  23. #include "aligned_buffer.h"
  24. #include "acquire_release.h"
  25. #include "locale_impl.h"
  26. _STLP_BEGIN_NAMESPACE
  27. static const string _Nameless("*");
  28. static inline bool is_C_locale_name (const char* name)
  29. { return ((name[0] == 'C') && (name[1] == 0)); }
  30. locale::facet * _STLP_CALL _get_facet(locale::facet *f)
  31. {
  32. if (f != 0)
  33. f->_M_incr();
  34. return f;
  35. }
  36. void _STLP_CALL _release_facet(locale::facet *&f)
  37. {
  38. if ((f != 0) && (f->_M_decr() == 0)) {
  39. delete f;
  40. f = 0;
  41. }
  42. }
  43. size_t locale::id::_S_max = 27;
  44. static void _Stl_loc_assign_ids();
  45. static _Stl_aligned_buffer<_Locale_impl::Init> __Loc_init_buf;
  46. _Locale_impl::Init::Init() {
  47. if (_M_count()._M_incr() == 1) {
  48. _Locale_impl::_S_initialize();
  49. }
  50. }
  51. _Locale_impl::Init::~Init() {
  52. if (_M_count()._M_decr() == 0) {
  53. _Locale_impl::_S_uninitialize();
  54. }
  55. }
  56. _Refcount_Base& _Locale_impl::Init::_M_count() const {
  57. static _Refcount_Base _S_count(0);
  58. return _S_count;
  59. }
  60. _Locale_impl::_Locale_impl(const char* s)
  61. : _Refcount_Base(0), name(s), facets_vec() {
  62. facets_vec.reserve( locale::id::_S_max );
  63. new (&__Loc_init_buf) Init();
  64. }
  65. _Locale_impl::_Locale_impl( _Locale_impl const& locimpl )
  66. : _Refcount_Base(0), name(locimpl.name), facets_vec() {
  67. for_each( locimpl.facets_vec.begin(), locimpl.facets_vec.end(), _get_facet);
  68. facets_vec = locimpl.facets_vec;
  69. new (&__Loc_init_buf) Init();
  70. }
  71. _Locale_impl::_Locale_impl( size_t n, const char* s)
  72. : _Refcount_Base(0), name(s), facets_vec(n, 0) {
  73. new (&__Loc_init_buf) Init();
  74. }
  75. _Locale_impl::~_Locale_impl() {
  76. (&__Loc_init_buf)->~Init();
  77. for_each( facets_vec.begin(), facets_vec.end(), _release_facet);
  78. }
  79. // Initialization of the locale system. This must be called before
  80. // any locales are constructed. (Meaning that it must be called when
  81. // the I/O library itself is initialized.)
  82. void _STLP_CALL _Locale_impl::_S_initialize() {
  83. _Stl_loc_assign_ids();
  84. make_classic_locale();
  85. }
  86. // Release of the classic locale ressources. Has to be called after the last
  87. // locale destruction and not only after the classic locale destruction as
  88. // the facets can be shared between different facets.
  89. void _STLP_CALL _Locale_impl::_S_uninitialize() {
  90. //Not necessary anymore as classic facets are now 'normal' dynamically allocated
  91. //facets with a reference counter telling to _release_facet when the facet can be
  92. //deleted.
  93. //free_classic_locale();
  94. }
  95. // _Locale_impl non-inline member functions.
  96. void _STLP_CALL _Locale_impl::_M_throw_bad_cast() {
  97. _STLP_THROW(bad_cast());
  98. }
  99. void _Locale_impl::insert(_Locale_impl *from, const locale::id& n) {
  100. if (n._M_index > 0 && n._M_index < from->size()) {
  101. this->insert(from->facets_vec[n._M_index], n);
  102. }
  103. }
  104. locale::facet* _Locale_impl::insert(locale::facet *f, const locale::id& n) {
  105. if (f == 0 || n._M_index == 0)
  106. return 0;
  107. if (n._M_index >= facets_vec.size()) {
  108. facets_vec.resize(n._M_index + 1);
  109. }
  110. if (f != facets_vec[n._M_index])
  111. {
  112. _release_facet(facets_vec[n._M_index]);
  113. facets_vec[n._M_index] = _get_facet(f);
  114. }
  115. return f;
  116. }
  117. //
  118. // <locale> content which is dependent on the name
  119. //
  120. /* Six functions, one for each category. Each of them takes a
  121. * a name, constructs that appropriate category facets by name,
  122. * and inserts them into the locale. */
  123. _Locale_name_hint* _Locale_impl::insert_ctype_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
  124. if (name[0] == 0)
  125. name = _Locale_ctype_default(buf);
  126. if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
  127. _Locale_impl* i2 = locale::classic()._M_impl;
  128. this->insert(i2, ctype<char>::id);
  129. this->insert(i2, codecvt<char, char, mbstate_t>::id);
  130. #ifndef _STLP_NO_WCHAR_T
  131. this->insert(i2, ctype<wchar_t>::id);
  132. this->insert(i2, codecvt<wchar_t, char, mbstate_t>::id);
  133. #endif
  134. } else {
  135. locale::facet* ct = 0;
  136. locale::facet* cvt = 0;
  137. #ifndef _STLP_NO_WCHAR_T
  138. locale::facet* wct = 0;
  139. locale::facet* wcvt = 0;
  140. #endif
  141. int __err_code;
  142. _Locale_ctype *__lct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code);
  143. if (!__lct) {
  144. locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
  145. return hint;
  146. }
  147. if (hint == 0) hint = _Locale_get_ctype_hint(__lct);
  148. _STLP_TRY {
  149. ct = new ctype_byname<char>(__lct);
  150. }
  151. _STLP_UNWIND(_STLP_PRIV __release_ctype(__lct));
  152. _STLP_TRY {
  153. cvt = new codecvt_byname<char, char, mbstate_t>(name);
  154. }
  155. _STLP_UNWIND(delete ct);
  156. #ifndef _STLP_NO_WCHAR_T
  157. _STLP_TRY {
  158. _Locale_ctype *__lwct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code);
  159. if (!__lwct) {
  160. locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
  161. return hint;
  162. }
  163. _STLP_TRY {
  164. wct = new ctype_byname<wchar_t>(__lwct);
  165. }
  166. _STLP_UNWIND(_STLP_PRIV __release_ctype(__lwct));
  167. _Locale_codecvt *__lwcvt = _STLP_PRIV __acquire_codecvt(name, buf, hint, &__err_code);
  168. if (__lwcvt) {
  169. _STLP_TRY {
  170. wcvt = new codecvt_byname<wchar_t, char, mbstate_t>(__lwcvt);
  171. }
  172. _STLP_UNWIND(_STLP_PRIV __release_codecvt(__lwcvt); delete wct);
  173. }
  174. }
  175. _STLP_UNWIND(delete cvt; delete ct);
  176. #endif
  177. this->insert(ct, ctype<char>::id);
  178. this->insert(cvt, codecvt<char, char, mbstate_t>::id);
  179. #ifndef _STLP_NO_WCHAR_T
  180. this->insert(wct, ctype<wchar_t>::id);
  181. if (wcvt) this->insert(wcvt, codecvt<wchar_t, char, mbstate_t>::id);
  182. #endif
  183. }
  184. return hint;
  185. }
  186. _Locale_name_hint* _Locale_impl::insert_numeric_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
  187. if (name[0] == 0)
  188. name = _Locale_numeric_default(buf);
  189. _Locale_impl* i2 = locale::classic()._M_impl;
  190. // We first insert name independant facets taken from the classic locale instance:
  191. this->insert(i2,
  192. num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
  193. this->insert(i2,
  194. num_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
  195. #ifndef _STLP_NO_WCHAR_T
  196. this->insert(i2,
  197. num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  198. this->insert(i2,
  199. num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  200. #endif
  201. if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
  202. this->insert(i2, numpunct<char>::id);
  203. #ifndef _STLP_NO_WCHAR_T
  204. this->insert(i2, numpunct<wchar_t>::id);
  205. #endif
  206. }
  207. else {
  208. locale::facet* punct = 0;
  209. #ifndef _STLP_NO_WCHAR_T
  210. locale::facet* wpunct = 0;
  211. #endif
  212. int __err_code;
  213. _Locale_numeric *__lpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code);
  214. if (!__lpunct) {
  215. locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
  216. return hint;
  217. }
  218. if (hint == 0) hint = _Locale_get_numeric_hint(__lpunct);
  219. _STLP_TRY {
  220. punct = new numpunct_byname<char>(__lpunct);
  221. }
  222. _STLP_UNWIND(_STLP_PRIV __release_numeric(__lpunct));
  223. #ifndef _STLP_NO_WCHAR_T
  224. _Locale_numeric *__lwpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code);
  225. if (!__lwpunct) {
  226. delete punct;
  227. locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
  228. return hint;
  229. }
  230. if (__lwpunct) {
  231. _STLP_TRY {
  232. wpunct = new numpunct_byname<wchar_t>(__lwpunct);
  233. }
  234. _STLP_UNWIND(_STLP_PRIV __release_numeric(__lwpunct); delete punct);
  235. }
  236. #endif
  237. this->insert(punct, numpunct<char>::id);
  238. #ifndef _STLP_NO_WCHAR_T
  239. this->insert(wpunct, numpunct<wchar_t>::id);
  240. #endif
  241. }
  242. return hint;
  243. }
  244. _Locale_name_hint* _Locale_impl::insert_time_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
  245. if (name[0] == 0)
  246. name = _Locale_time_default(buf);
  247. if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
  248. _Locale_impl* i2 = locale::classic()._M_impl;
  249. this->insert(i2,
  250. time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
  251. this->insert(i2,
  252. time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
  253. #ifndef _STLP_NO_WCHAR_T
  254. this->insert(i2,
  255. time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  256. this->insert(i2,
  257. time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  258. #endif
  259. } else {
  260. locale::facet *get = 0;
  261. locale::facet *put = 0;
  262. #ifndef _STLP_NO_WCHAR_T
  263. locale::facet *wget = 0;
  264. locale::facet *wput = 0;
  265. #endif
  266. int __err_code;
  267. _Locale_time *__time = _STLP_PRIV __acquire_time(name, buf, hint, &__err_code);
  268. if (!__time) {
  269. // time facets category is not mandatory for correct stream behavior so if platform
  270. // do not support it we do not generate a runtime_error exception.
  271. if (__err_code == _STLP_LOC_NO_MEMORY) {
  272. _STLP_THROW_BAD_ALLOC;
  273. }
  274. return hint;
  275. }
  276. if (!hint) hint = _Locale_get_time_hint(__time);
  277. _STLP_TRY {
  278. get = new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(__time);
  279. put = new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(__time);
  280. #ifndef _STLP_NO_WCHAR_T
  281. wget = new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(__time);
  282. wput = new time_put_byname<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(__time);
  283. #endif
  284. }
  285. #ifndef _STLP_NO_WCHAR_T
  286. _STLP_UNWIND(delete wget; delete put; delete get; _STLP_PRIV __release_time(__time));
  287. #else
  288. _STLP_UNWIND(delete get; _STLP_PRIV __release_time(__time));
  289. #endif
  290. _STLP_PRIV __release_time(__time);
  291. this->insert(get, time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
  292. this->insert(put, time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
  293. #ifndef _STLP_NO_WCHAR_T
  294. this->insert(wget, time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  295. this->insert(wput, time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  296. #endif
  297. }
  298. return hint;
  299. }
  300. _Locale_name_hint* _Locale_impl::insert_collate_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
  301. if (name[0] == 0)
  302. name = _Locale_collate_default(buf);
  303. if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
  304. _Locale_impl* i2 = locale::classic()._M_impl;
  305. this->insert(i2, collate<char>::id);
  306. #ifndef _STLP_NO_WCHAR_T
  307. this->insert(i2, collate<wchar_t>::id);
  308. #endif
  309. }
  310. else {
  311. locale::facet *col = 0;
  312. #ifndef _STLP_NO_WCHAR_T
  313. locale::facet *wcol = 0;
  314. #endif
  315. int __err_code;
  316. _Locale_collate *__coll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code);
  317. if (!__coll) {
  318. if (__err_code == _STLP_LOC_NO_MEMORY) {
  319. _STLP_THROW_BAD_ALLOC;
  320. }
  321. return hint;
  322. }
  323. if (hint == 0) hint = _Locale_get_collate_hint(__coll);
  324. _STLP_TRY {
  325. col = new collate_byname<char>(__coll);
  326. }
  327. _STLP_UNWIND(_STLP_PRIV __release_collate(__coll));
  328. #ifndef _STLP_NO_WCHAR_T
  329. _Locale_collate *__wcoll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code);
  330. if (!__wcoll) {
  331. if (__err_code == _STLP_LOC_NO_MEMORY) {
  332. delete col;
  333. _STLP_THROW_BAD_ALLOC;
  334. }
  335. }
  336. if (__wcoll) {
  337. _STLP_TRY {
  338. wcol = new collate_byname<wchar_t>(__wcoll);
  339. }
  340. _STLP_UNWIND(_STLP_PRIV __release_collate(__wcoll); delete col);
  341. }
  342. #endif
  343. this->insert(col, collate<char>::id);
  344. #ifndef _STLP_NO_WCHAR_T
  345. if (wcol) this->insert(wcol, collate<wchar_t>::id);
  346. #endif
  347. }
  348. return hint;
  349. }
  350. _Locale_name_hint* _Locale_impl::insert_monetary_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
  351. if (name[0] == 0)
  352. name = _Locale_monetary_default(buf);
  353. _Locale_impl* i2 = locale::classic()._M_impl;
  354. // We first insert name independant facets taken from the classic locale instance:
  355. this->insert(i2, money_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
  356. this->insert(i2, money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
  357. #ifndef _STLP_NO_WCHAR_T
  358. this->insert(i2, money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  359. this->insert(i2, money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
  360. #endif
  361. if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
  362. this->insert(i2, moneypunct<char, false>::id);
  363. this->insert(i2, moneypunct<char, true>::id);
  364. #ifndef _STLP_NO_WCHAR_T
  365. this->insert(i2, moneypunct<wchar_t, false>::id);
  366. this->insert(i2, moneypunct<wchar_t, true>::id);
  367. #endif
  368. }
  369. else {
  370. locale::facet *punct = 0;
  371. locale::facet *ipunct = 0;
  372. #ifndef _STLP_NO_WCHAR_T
  373. locale::facet* wpunct = 0;
  374. locale::facet* wipunct = 0;
  375. #endif
  376. int __err_code;
  377. _Locale_monetary *__mon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
  378. if (!__mon) {
  379. if (__err_code == _STLP_LOC_NO_MEMORY) {
  380. _STLP_THROW_BAD_ALLOC;
  381. }
  382. return hint;
  383. }
  384. if (hint == 0) hint = _Locale_get_monetary_hint(__mon);
  385. _STLP_TRY {
  386. punct = new moneypunct_byname<char, false>(__mon);
  387. }
  388. _STLP_UNWIND(_STLP_PRIV __release_monetary(__mon));
  389. _Locale_monetary *__imon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
  390. if (!__imon) {
  391. delete punct;
  392. if (__err_code == _STLP_LOC_NO_MEMORY) {
  393. _STLP_THROW_BAD_ALLOC;
  394. }
  395. return hint;
  396. }
  397. _STLP_TRY {
  398. ipunct = new moneypunct_byname<char, true>(__imon);
  399. }
  400. _STLP_UNWIND(_STLP_PRIV __release_monetary(__imon); delete punct);
  401. #ifndef _STLP_NO_WCHAR_T
  402. _STLP_TRY {
  403. _Locale_monetary *__wmon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
  404. if (!__wmon) {
  405. if (__err_code == _STLP_LOC_NO_MEMORY) {
  406. _STLP_THROW_BAD_ALLOC;
  407. }
  408. }
  409. if (__wmon) {
  410. _STLP_TRY {
  411. wpunct = new moneypunct_byname<wchar_t, false>(__wmon);
  412. }
  413. _STLP_UNWIND(_STLP_PRIV __release_monetary(__wmon));
  414. _Locale_monetary *__wimon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
  415. if (!__wimon) {
  416. delete wpunct;
  417. if (__err_code == _STLP_LOC_NO_MEMORY) {
  418. _STLP_THROW_BAD_ALLOC;
  419. }
  420. wpunct = 0;
  421. }
  422. else {
  423. _STLP_TRY {
  424. wipunct = new moneypunct_byname<wchar_t, true>(__wimon);
  425. }
  426. _STLP_UNWIND(_STLP_PRIV __release_monetary(__wimon); delete wpunct);
  427. }
  428. }
  429. }
  430. _STLP_UNWIND(delete ipunct; delete punct);
  431. #endif
  432. this->insert(punct, moneypunct<char, false>::id);
  433. this->insert(ipunct, moneypunct<char, true>::id);
  434. #ifndef _STLP_NO_WCHAR_T
  435. if (wpunct) this->insert(wpunct, moneypunct<wchar_t, false>::id);
  436. if (wipunct) this->insert(wipunct, moneypunct<wchar_t, true>::id);
  437. #endif
  438. }
  439. return hint;
  440. }
  441. _Locale_name_hint* _Locale_impl::insert_messages_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
  442. if (name[0] == 0)
  443. name = _Locale_messages_default(buf);
  444. if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
  445. _Locale_impl* i2 = locale::classic()._M_impl;
  446. this->insert(i2, messages<char>::id);
  447. #ifndef _STLP_NO_WCHAR_T
  448. this->insert(i2, messages<wchar_t>::id);
  449. #endif
  450. }
  451. else {
  452. locale::facet *msg = 0;
  453. #ifndef _STLP_NO_WCHAR_T
  454. locale::facet *wmsg = 0;
  455. #endif
  456. int __err_code;
  457. _Locale_messages *__msg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code);
  458. if (!__msg) {
  459. if (__err_code == _STLP_LOC_NO_MEMORY) {
  460. _STLP_THROW_BAD_ALLOC;
  461. }
  462. return hint;
  463. }
  464. _STLP_TRY {
  465. msg = new messages_byname<char>(__msg);
  466. }
  467. _STLP_UNWIND(_STLP_PRIV __release_messages(__msg));
  468. #ifndef _STLP_NO_WCHAR_T
  469. _STLP_TRY {
  470. _Locale_messages *__wmsg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code);
  471. if (!__wmsg) {
  472. if (__err_code == _STLP_LOC_NO_MEMORY) {
  473. _STLP_THROW_BAD_ALLOC;
  474. }
  475. }
  476. if (__wmsg) {
  477. _STLP_TRY {
  478. wmsg = new messages_byname<wchar_t>(__wmsg);
  479. }
  480. _STLP_UNWIND(_STLP_PRIV __release_messages(__wmsg));
  481. }
  482. }
  483. _STLP_UNWIND(delete msg);
  484. #endif
  485. this->insert(msg, messages<char>::id);
  486. #ifndef _STLP_NO_WCHAR_T
  487. if (wmsg) this->insert(wmsg, messages<wchar_t>::id);
  488. #endif
  489. }
  490. return hint;
  491. }
  492. static void _Stl_loc_assign_ids() {
  493. // This assigns ids to every facet that is a member of a category,
  494. // and also to money_get/put, num_get/put, and time_get/put
  495. // instantiated using ordinary pointers as the input/output
  496. // iterators. (The default is [io]streambuf_iterator.)
  497. money_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index = 8;
  498. money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index = 9;
  499. num_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index = 10;
  500. num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index = 11;
  501. time_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index = 12;
  502. time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index = 13;
  503. #ifndef _STLP_NO_WCHAR_T
  504. money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 21;
  505. money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 22;
  506. num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 23;
  507. num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::id._M_index = 24;
  508. time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 25;
  509. time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 26;
  510. #endif
  511. // locale::id::_S_max = 27;
  512. }
  513. // To access those static instance use the getter below, they guaranty
  514. // a correct initialization.
  515. static locale *_Stl_classic_locale = 0;
  516. static locale *_Stl_global_locale = 0;
  517. locale* _Stl_get_classic_locale() {
  518. static _Locale_impl::Init init;
  519. return _Stl_classic_locale;
  520. }
  521. locale* _Stl_get_global_locale() {
  522. static _Locale_impl::Init init;
  523. return _Stl_global_locale;
  524. }
  525. #if defined (_STLP_MSVC) || defined (__ICL) || defined (__ISCPP__) || defined (__DMC__)
  526. /*
  527. * The following static variable needs to be initialized before STLport
  528. * users static variable in order for him to be able to use Standard
  529. * streams in its variable initialization.
  530. * This variable is here because MSVC do not allow to change the initialization
  531. * segment in a given translation unit, iostream.cpp already contains an
  532. * initialization segment specification.
  533. */
  534. # pragma warning (disable : 4073)
  535. # pragma init_seg(lib)
  536. #endif
  537. static ios_base::Init _IosInit;
  538. void _Locale_impl::make_classic_locale() {
  539. // This funcion will be called once: during build classic _Locale_impl
  540. // The classic locale contains every facet that belongs to a category.
  541. static _Stl_aligned_buffer<_Locale_impl> _Locale_classic_impl_buf;
  542. _Locale_impl *classic = new(&_Locale_classic_impl_buf) _Locale_impl("C");
  543. locale::facet* classic_facets[] = {
  544. 0,
  545. new collate<char>(1),
  546. new ctype<char>(0, false, 1),
  547. new codecvt<char, char, mbstate_t>(1),
  548. new moneypunct<char, true>(1),
  549. new moneypunct<char, false>(1),
  550. new numpunct<char>(1),
  551. new messages<char>(1),
  552. new money_get<char, istreambuf_iterator<char, char_traits<char> > >(1),
  553. new money_put<char, ostreambuf_iterator<char, char_traits<char> > >(1),
  554. new num_get<char, istreambuf_iterator<char, char_traits<char> > >(1),
  555. new num_put<char, ostreambuf_iterator<char, char_traits<char> > >(1),
  556. new time_get<char, istreambuf_iterator<char, char_traits<char> > >(1),
  557. new time_put<char, ostreambuf_iterator<char, char_traits<char> > >(1),
  558. #ifndef _STLP_NO_WCHAR_T
  559. new collate<wchar_t>(1),
  560. new ctype<wchar_t>(1),
  561. new codecvt<wchar_t, char, mbstate_t>(1),
  562. new moneypunct<wchar_t, true>(1),
  563. new moneypunct<wchar_t, false>(1),
  564. new numpunct<wchar_t>(1),
  565. new messages<wchar_t>(1),
  566. new money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
  567. new money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
  568. new num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
  569. new num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
  570. new time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
  571. new time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
  572. #endif
  573. 0
  574. };
  575. const size_t nb_classic_facets = sizeof(classic_facets) / sizeof(locale::facet *);
  576. classic->facets_vec.reserve(nb_classic_facets);
  577. classic->facets_vec.assign(&classic_facets[0], &classic_facets[0] + nb_classic_facets);
  578. static locale _Locale_classic(classic);
  579. _Stl_classic_locale = &_Locale_classic;
  580. static locale _Locale_global(classic);
  581. _Stl_global_locale = &_Locale_global;
  582. }
  583. // Declarations of (non-template) facets' static data members
  584. // size_t locale::id::_S_max = 27; // made before
  585. locale::id collate<char>::id = { 1 };
  586. locale::id ctype<char>::id = { 2 };
  587. locale::id codecvt<char, char, mbstate_t>::id = { 3 };
  588. locale::id moneypunct<char, true>::id = { 4 };
  589. locale::id moneypunct<char, false>::id = { 5 };
  590. locale::id numpunct<char>::id = { 6 } ;
  591. locale::id messages<char>::id = { 7 };
  592. #ifndef _STLP_NO_WCHAR_T
  593. locale::id collate<wchar_t>::id = { 14 };
  594. locale::id ctype<wchar_t>::id = { 15 };
  595. locale::id codecvt<wchar_t, char, mbstate_t>::id = { 16 };
  596. locale::id moneypunct<wchar_t, true>::id = { 17 } ;
  597. locale::id moneypunct<wchar_t, false>::id = { 18 } ;
  598. locale::id numpunct<wchar_t>::id = { 19 };
  599. locale::id messages<wchar_t>::id = { 20 };
  600. #endif
  601. _STLP_DECLSPEC _Locale_impl* _STLP_CALL _get_Locale_impl(_Locale_impl *loc)
  602. {
  603. _STLP_ASSERT( loc != 0 );
  604. loc->_M_incr();
  605. return loc;
  606. }
  607. void _STLP_CALL _release_Locale_impl(_Locale_impl *& loc)
  608. {
  609. _STLP_ASSERT( loc != 0 );
  610. if (loc->_M_decr() == 0) {
  611. if (*loc != *_Stl_classic_locale)
  612. delete loc;
  613. else
  614. loc->~_Locale_impl();
  615. loc = 0;
  616. }
  617. }
  618. _STLP_DECLSPEC _Locale_impl* _STLP_CALL _copy_Nameless_Locale_impl(_Locale_impl *loc)
  619. {
  620. _STLP_ASSERT( loc != 0 );
  621. _Locale_impl *loc_new = new _Locale_impl(*loc);
  622. loc_new->name = _Nameless;
  623. return loc_new;
  624. }
  625. /* _GetFacetId implementation have to be here in order to be in the same translation unit
  626. * as where id are initialize (in _Stl_loc_assign_ids) */
  627. _STLP_MOVE_TO_PRIV_NAMESPACE
  628. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<char, istreambuf_iterator<char, char_traits<char> > >*)
  629. { return money_get<char, istreambuf_iterator<char, char_traits<char> > >::id; }
  630. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<char, ostreambuf_iterator<char, char_traits<char> > >*)
  631. { return money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; }
  632. #ifndef _STLP_NO_WCHAR_T
  633. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
  634. { return money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
  635. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
  636. { return money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
  637. #endif
  638. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<char, istreambuf_iterator<char, char_traits<char> > >*)
  639. { return num_get<char, istreambuf_iterator<char, char_traits<char> > >::id; }
  640. #ifndef _STLP_NO_WCHAR_T
  641. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
  642. { return num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
  643. #endif
  644. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<char, ostreambuf_iterator<char, char_traits<char> > >*)
  645. { return num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; }
  646. #ifndef _STLP_NO_WCHAR_T
  647. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
  648. { return num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
  649. #endif
  650. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<char, istreambuf_iterator<char, char_traits<char> > >*)
  651. { return time_get<char, istreambuf_iterator<char, char_traits<char> > >::id; }
  652. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<char, ostreambuf_iterator<char, char_traits<char> > >*)
  653. { return time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; }
  654. #ifndef _STLP_NO_WCHAR_T
  655. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
  656. { return time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
  657. _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
  658. { return time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
  659. #endif
  660. _STLP_MOVE_TO_STD_NAMESPACE
  661. _STLP_END_NAMESPACE