Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.3 KiB

  1. // locale -- class locale member functions
  2. #include <cstdlib>
  3. #include <istream>
  4. #include <locale>
  5. #include <xdebug>
  6. #include <dbgint.h>
  7. _C_STD_BEGIN
  8. _EXTERN_C
  9. std::locale::_Locimp *__cdecl _Getgloballocale();
  10. void __cdecl _Setgloballocale(void *);
  11. _END_EXTERN_C
  12. _C_STD_END
  13. _STD_BEGIN
  14. typedef char_traits<char> _Traits;
  15. typedef istreambuf_iterator<char, _Traits> _Initer;
  16. typedef ostreambuf_iterator<char, _Traits> _Outiter;
  17. locale::locale(const locale& loc, const locale& other, category cat)
  18. : _Ptr(_NEW_CRT _Locimp(*loc._Ptr))
  19. { // construct a locale by copying named facets
  20. _TRY_BEGIN
  21. _Locinfo _Lobj(loc._Ptr->_Catmask, loc._Ptr->_Name.c_str());
  22. _Locimp::_Makeloc(_Lobj._Addcats(cat & other._Ptr->_Catmask,
  23. other._Ptr->_Name.c_str()), cat, _Ptr, &other);
  24. _CATCH_ALL
  25. _DELETE_CRT(_Ptr->_Decref());
  26. _RERAISE;
  27. _CATCH_END
  28. }
  29. locale::locale(const char *locname, category cat)
  30. : _Ptr(_NEW_CRT _Locimp)
  31. { // construct a locale with named facets
  32. _TRY_BEGIN
  33. _Init();
  34. _Locinfo _Lobj(cat, locname);
  35. if (_Lobj._Getname().compare("*") == 0)
  36. _THROW(runtime_error, "bad locale name");
  37. _Locimp::_Makeloc(_Lobj, cat, _Ptr, 0);
  38. _CATCH_ALL
  39. _DELETE_CRT(_Ptr->_Decref());
  40. _RERAISE;
  41. _CATCH_END
  42. }
  43. locale::locale(const locale& loc, const char *locname, category cat)
  44. : _Ptr(_NEW_CRT _Locimp(*loc._Ptr))
  45. { // construct a locale by copying, replacing named facets
  46. _TRY_BEGIN
  47. _Locinfo _Lobj(loc._Ptr->_Catmask, loc._Ptr->_Name.c_str());
  48. bool _Hadname = _Lobj._Getname().compare("*") != 0;
  49. _Lobj._Addcats(cat, locname);
  50. if (_Hadname && _Lobj._Getname().compare("*") == 0)
  51. _THROW(runtime_error, "bad locale name");
  52. _Locimp::_Makeloc(_Lobj, cat, _Ptr, 0);
  53. _CATCH_ALL
  54. _DELETE_CRT(_Ptr->_Decref());
  55. _RERAISE;
  56. _CATCH_END
  57. }
  58. _DEPRECATED locale& locale::_Addfac(facet *fac, size_t id, size_t catmask)
  59. { // add a facet, copying on write
  60. if (1 < _Ptr->_Refs)
  61. { // shared, make private copy before altering
  62. _Ptr->_Decref();
  63. _Ptr = _NEW_CRT _Locimp(*_Ptr);
  64. }
  65. _Ptr->_Addfac(fac, id);
  66. if (catmask != 0)
  67. _Ptr->_Name = "*";
  68. return (*this);
  69. }
  70. locale __cdecl locale::global(const locale& loc)
  71. { // change global locale
  72. locale _Oldglobal;
  73. _Lockit lock(_LOCK_LOCALE);
  74. locale::_Locimp *_Ptr = ::_Getgloballocale();
  75. if (_Ptr != loc._Ptr)
  76. { // set new global locale
  77. _DELETE_CRT(_Ptr->_Decref());
  78. ::_Setgloballocale(_Ptr = loc._Ptr);
  79. _Ptr->_Incref();
  80. category _Cmask = _Ptr->_Catmask & all;
  81. if (_Cmask == all)
  82. setlocale(LC_ALL, _Ptr->_Name.c_str());
  83. else
  84. for (int catindex = 0; catindex <= _X_MAX; ++catindex)
  85. if ((_CATMASK(catindex) & _Cmask) != 0)
  86. setlocale(catindex, _Ptr->_Name.c_str());
  87. }
  88. return (_Oldglobal);
  89. }
  90. // facets associated with C categories
  91. #define ADDFAC(Facet, cat, ptrimp, ptrloc) \
  92. if ((_CATMASK(Facet::_Getcat()) & cat) == 0) \
  93. ; \
  94. else if (ptrloc == 0) \
  95. ptrimp->_Addfac(_NEW_CRT Facet(lobj), Facet::id); \
  96. else \
  97. ptrimp->_Addfac((locale::facet *)&_USE(*ptrloc, Facet), Facet::id);
  98. typedef ctype<char> _T1;
  99. typedef num_get<char, _Initer> _T2;
  100. typedef num_put<char, _Outiter> _T3;
  101. typedef numpunct<char> _T4;
  102. // others moved to wlocale and xlocale to ease subsetting
  103. typedef codecvt<char, char, mbstate_t> _Tc1;
  104. locale::_Locimp *__cdecl locale::_Locimp::_Makeloc(const _Locinfo& lobj,
  105. locale::category cat, _Locimp *ptrimp, const locale *ptrloc)
  106. { // setup a new locale
  107. ADDFAC(_T1, cat, ptrimp, ptrloc);
  108. ADDFAC(_T2, cat, ptrimp, ptrloc);
  109. ADDFAC(_T3, cat, ptrimp, ptrloc);
  110. ADDFAC(_T4, cat, ptrimp, ptrloc);
  111. //...
  112. ADDFAC(_Tc1, cat, ptrimp, ptrloc);
  113. _Locimp::_Makexloc(lobj, cat, ptrimp, ptrloc);
  114. _Locimp::_Makewloc(lobj, cat, ptrimp, ptrloc);
  115. #ifdef _NATIVE_WCHAR_T_DEFINED
  116. _Locimp::_Makeushloc(lobj, cat, ptrimp, ptrloc);
  117. #endif
  118. ptrimp->_Catmask |= cat;
  119. ptrimp->_Name = lobj._Getname();
  120. return (ptrimp);
  121. }
  122. locale::_Locimp::_Locimp(const locale::_Locimp& imp)
  123. : locale::facet(1), _Facetvec(0), _Facetcount(imp._Facetcount),
  124. _Catmask(imp._Catmask), _Xparent(imp._Xparent), _Name(imp._Name)
  125. { // construct a _Locimp from a copy
  126. if (&imp == _Clocptr)
  127. _Makeloc(_Locinfo(), locale::all, this, 0);
  128. else
  129. { // lock to keep facets from disappearing
  130. _Lockit lock(_LOCK_LOCALE);
  131. if (0 < _Facetcount)
  132. { // copy over nonempty facet vector
  133. if ((_Facetvec = (locale::facet **)_malloc_crt(
  134. _Facetcount * sizeof (locale::facet *))) == 0)
  135. _Nomemory();
  136. for (size_t count = _Facetcount; 0 < count; )
  137. { // copy over facet pointers
  138. locale::facet *ptrfac = imp._Facetvec[--count];
  139. if ((_Facetvec[count] = ptrfac) != 0)
  140. ptrfac->_Incref();
  141. }
  142. }
  143. }
  144. }
  145. void locale::_Locimp::_Addfac(locale::facet *ptrfac, size_t id)
  146. { // add a facet to a locale
  147. _Lockit lock(_LOCK_LOCALE);
  148. const size_t MINCAT = 40; // minimum number of facets in a locale
  149. if (_Facetcount <= id)
  150. { // make facet vector larger
  151. size_t count = id + 1;
  152. if (count < MINCAT)
  153. count = MINCAT;
  154. locale::facet **ptrnewvec = (locale::facet **)_realloc_crt(_Facetvec,
  155. count * sizeof (locale::facet **));
  156. if (ptrnewvec == 0)
  157. _Nomemory();
  158. _Facetvec = ptrnewvec;
  159. for (; _Facetcount < count; ++_Facetcount)
  160. _Facetvec[_Facetcount] = 0;
  161. }
  162. ptrfac->_Incref();
  163. if (_Facetvec[id] != 0)
  164. _DELETE_CRT(_Facetvec[id]->_Decref());
  165. _Facetvec[id] = ptrfac;
  166. }
  167. _CRTIMP2 _Locinfo::_Locinfo(int cat, const char *locname)
  168. : _Lock(_LOCK_LOCALE)
  169. { // capture a named locale
  170. _Oldlocname = setlocale(LC_ALL, 0);
  171. _Addcats(cat, locname);
  172. }
  173. _CRTIMP2 _Locinfo& _Locinfo::_Addcats(int cat, const char *locname)
  174. { // merge in another named locale
  175. const char *oldlocname = 0;
  176. if (locname[0] == '*' && locname[1] == '\0')
  177. ;
  178. else if (cat == 0)
  179. oldlocname = setlocale(LC_ALL, 0);
  180. else if (cat == _M_ALL)
  181. oldlocname = setlocale(LC_ALL, locname);
  182. else
  183. { // alter selected categories
  184. for (int catindex = 0; catindex <= _X_MAX; ++catindex)
  185. if ((_CATMASK(catindex) & cat) != 0)
  186. setlocale(catindex, locname);
  187. oldlocname = setlocale(LC_ALL, locname);
  188. }
  189. if (oldlocname == 0)
  190. _Newlocname = "*";
  191. else if (_Newlocname.compare("*") != 0)
  192. _Newlocname = oldlocname;
  193. return (*this);
  194. }
  195. _STD_END
  196. /*
  197. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  198. * Consult your license regarding permissions and restrictions.
  199. V3.10:0009 */