usp10: Move the application of pair values to a helper function.
[wine] / dlls / msvcp90 / locale.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #include "msvcp90.h"
24 #include "locale.h"
25 #include "errno.h"
26 #include "limits.h"
27 #include "math.h"
28 #include "stdio.h"
29 #include "wctype.h"
30
31 #include "wine/list.h"
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winnls.h"
36 #include "wine/unicode.h"
37 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
39
40 char* __cdecl _Getdays(void);
41 char* __cdecl _Getmonths(void);
42 void* __cdecl _Gettnames(void);
43 unsigned int __cdecl ___lc_codepage_func(void);
44 LCID* __cdecl ___lc_handle_func(void);
45 const locale_facet* __thiscall locale__Getfacet(const locale*, MSVCP_size_t);
46
47 typedef int category;
48
49 typedef struct {
50     MSVCP_size_t id;
51 } locale_id;
52
53 typedef struct _locale__Locimp {
54     locale_facet facet;
55     locale_facet **facetvec;
56     MSVCP_size_t facet_cnt;
57     category catmask;
58     MSVCP_bool transparent;
59     basic_string_char name;
60 } locale__Locimp;
61
62 typedef struct {
63     void *timeptr;
64 } _Timevec;
65
66 typedef struct {
67     _Lockit lock;
68     basic_string_char days;
69     basic_string_char months;
70     basic_string_char oldlocname;
71     basic_string_char newlocname;
72 } _Locinfo;
73
74 typedef struct {
75     LCID handle;
76     unsigned page;
77 } _Collvec;
78
79 typedef struct {
80     locale_facet facet;
81     _Collvec coll;
82 } collate;
83
84 typedef struct {
85     locale_facet facet;
86     const char *grouping;
87     char dp;
88     char sep;
89     const char *false_name;
90     const char *true_name;
91 } numpunct_char;
92
93 typedef struct {
94     locale_facet facet;
95     const char *grouping;
96     wchar_t dp;
97     wchar_t sep;
98     const wchar_t *false_name;
99     const wchar_t *true_name;
100 } numpunct_wchar;
101
102 /* ?_Id_cnt@id@locale@std@@0HA */
103 int locale_id__Id_cnt = 0;
104
105 static locale__Locimp *global_locale;
106 static locale classic_locale;
107
108 /* ?_Clocptr@_Locimp@locale@std@@0PAV123@A */
109 /* ?_Clocptr@_Locimp@locale@std@@0PEAV123@EA */
110 locale__Locimp *locale__Locimp__Clocptr = NULL;
111
112 static char istreambuf_iterator_char_val(istreambuf_iterator_char *this)
113 {
114     if(this->strbuf && !this->got) {
115         int c = basic_streambuf_char_sgetc(this->strbuf);
116         if(c == EOF)
117             this->strbuf = NULL;
118         else
119             this->val = c;
120     }
121
122     this->got = TRUE;
123     return this->val;
124 }
125
126 static wchar_t istreambuf_iterator_wchar_val(istreambuf_iterator_wchar *this)
127 {
128     if(this->strbuf && !this->got) {
129         unsigned short c = basic_streambuf_wchar_sgetc(this->strbuf);
130         if(c == WEOF)
131             this->strbuf = NULL;
132         else
133             this->val = c;
134     }
135
136     this->got = TRUE;
137     return this->val;
138 }
139
140 static void istreambuf_iterator_char_inc(istreambuf_iterator_char *this)
141 {
142     if(!this->strbuf || basic_streambuf_char_sbumpc(this->strbuf)==EOF) {
143         this->strbuf = NULL;
144         this->got = TRUE;
145     }else {
146         this->got = FALSE;
147         istreambuf_iterator_char_val(this);
148     }
149 }
150
151 static void istreambuf_iterator_wchar_inc(istreambuf_iterator_wchar *this)
152 {
153     if(!this->strbuf || basic_streambuf_wchar_sbumpc(this->strbuf)==WEOF) {
154         this->strbuf = NULL;
155         this->got = TRUE;
156     }else {
157         this->got = FALSE;
158         istreambuf_iterator_wchar_val(this);
159     }
160 }
161
162 static void ostreambuf_iterator_char_put(ostreambuf_iterator_char *this, char ch)
163 {
164     if(this->failed || basic_streambuf_char_sputc(this->strbuf, ch)==EOF)
165         this->failed = TRUE;
166 }
167
168 static void ostreambuf_iterator_wchar_put(ostreambuf_iterator_wchar *this, wchar_t ch)
169 {
170     if(this->failed || basic_streambuf_wchar_sputc(this->strbuf, ch)==WEOF)
171         this->failed = TRUE;
172 }
173
174 /* ??1facet@locale@std@@UAE@XZ */
175 /* ??1facet@locale@std@@UEAA@XZ */
176 DEFINE_THISCALL_WRAPPER(locale_facet_dtor, 4)
177 void __thiscall locale_facet_dtor(locale_facet *this)
178 {
179     TRACE("(%p)\n", this);
180 }
181
182 DEFINE_THISCALL_WRAPPER(locale_facet_vector_dtor, 8)
183 #define call_locale_facet_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0, \
184         locale_facet*, (locale_facet*, unsigned int), (this, flags))
185 locale_facet* __thiscall locale_facet_vector_dtor(locale_facet *this, unsigned int flags)
186 {
187     TRACE("(%p %x)\n", this, flags);
188     if(flags & 2) {
189         /* we have an array, with the number of elements stored before the first object */
190         INT_PTR i, *ptr = (INT_PTR *)this-1;
191
192         for(i=*ptr-1; i>=0; i--)
193             locale_facet_dtor(this+i);
194         MSVCRT_operator_delete(ptr);
195     } else {
196         locale_facet_dtor(this);
197         if(flags & 1)
198             MSVCRT_operator_delete(this);
199     }
200
201     return this;
202 }
203
204 typedef struct
205 {
206     locale_facet *fac;
207     struct list entry;
208 } facets_elem;
209 static struct list lazy_facets = LIST_INIT(lazy_facets);
210
211 /* Not exported from msvcp90 */
212 /* ?facet_Register@facet@locale@std@@CAXPAV123@@Z */
213 /* ?facet_Register@facet@locale@std@@CAXPEAV123@@Z */
214 void __cdecl locale_facet_register(locale_facet *add)
215 {
216     facets_elem *head = MSVCRT_operator_new(sizeof(*head));
217     if(!head) {
218         ERR("Out of memory\n");
219         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
220     }
221
222     head->fac = add;
223     list_add_head(&lazy_facets, &head->entry);
224 }
225
226 /* Not exported from msvcp90 */
227 /* ?_Register@facet@locale@std@@QAEXXZ */
228 /* ?_Register@facet@locale@std@@QEAAXXZ */
229 DEFINE_THISCALL_WRAPPER(locale_facet__Register, 4)
230 void __thiscall locale_facet__Register(locale_facet *this)
231 {
232     TRACE("(%p)\n", this);
233     locale_facet_register(this);
234 }
235
236 /* Not exported from msvcp90 */
237 /* ??_7facet@locale@std@@6B@ */
238 extern const vtable_ptr MSVCP_locale_facet_vtable;
239
240 /* ??0id@locale@std@@QAE@I@Z */
241 /* ??0id@locale@std@@QEAA@_K@Z */
242 DEFINE_THISCALL_WRAPPER(locale_id_ctor_id, 8)
243 locale_id* __thiscall locale_id_ctor_id(locale_id *this, MSVCP_size_t id)
244 {
245     TRACE("(%p %lu)\n", this, id);
246
247     this->id = id;
248     return this;
249 }
250
251 /* ??_Fid@locale@std@@QAEXXZ */
252 /* ??_Fid@locale@std@@QEAAXXZ */
253 DEFINE_THISCALL_WRAPPER(locale_id_ctor, 4)
254 locale_id* __thiscall locale_id_ctor(locale_id *this)
255 {
256     TRACE("(%p)\n", this);
257
258     this->id = 0;
259     return this;
260 }
261
262 /* ??Bid@locale@std@@QAEIXZ */
263 /* ??Bid@locale@std@@QEAA_KXZ */
264 DEFINE_THISCALL_WRAPPER(locale_id_operator_size_t, 4)
265 MSVCP_size_t __thiscall locale_id_operator_size_t(locale_id *this)
266 {
267     _Lockit lock;
268
269     TRACE("(%p)\n", this);
270
271     if(!this->id) {
272         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
273         this->id = ++locale_id__Id_cnt;
274         _Lockit_dtor(&lock);
275     }
276
277     return this->id;
278 }
279
280 /* ?_Id_cnt_func@id@locale@std@@CAAAHXZ */
281 /* ?_Id_cnt_func@id@locale@std@@CAAEAHXZ */
282 int* __cdecl locale_id__Id_cnt_func(void)
283 {
284     TRACE("\n");
285     return &locale_id__Id_cnt;
286 }
287
288 /* ??_Ffacet@locale@std@@QAEXXZ */
289 /* ??_Ffacet@locale@std@@QEAAXXZ */
290 DEFINE_THISCALL_WRAPPER(locale_facet_ctor, 4)
291 locale_facet* __thiscall locale_facet_ctor(locale_facet *this)
292 {
293     TRACE("(%p)\n", this);
294     this->vtable = &MSVCP_locale_facet_vtable;
295     this->refs = 0;
296     return this;
297 }
298
299 /* ??0facet@locale@std@@IAE@I@Z */
300 /* ??0facet@locale@std@@IEAA@_K@Z */
301 DEFINE_THISCALL_WRAPPER(locale_facet_ctor_refs, 8)
302 locale_facet* __thiscall locale_facet_ctor_refs(locale_facet *this, MSVCP_size_t refs)
303 {
304     TRACE("(%p %lu)\n", this, refs);
305     this->vtable = &MSVCP_locale_facet_vtable;
306     this->refs = refs;
307     return this;
308 }
309
310 /* ?_Incref@facet@locale@std@@QAEXXZ */
311 /* ?_Incref@facet@locale@std@@QEAAXXZ */
312 DEFINE_THISCALL_WRAPPER(locale_facet__Incref, 4)
313 void __thiscall locale_facet__Incref(locale_facet *this)
314 {
315     _Lockit lock;
316
317     TRACE("(%p)\n", this);
318
319     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
320     this->refs++;
321     _Lockit_dtor(&lock);
322 }
323
324 /* ?_Decref@facet@locale@std@@QAEPAV123@XZ */
325 /* ?_Decref@facet@locale@std@@QEAAPEAV123@XZ */
326 DEFINE_THISCALL_WRAPPER(locale_facet__Decref, 4)
327 locale_facet* __thiscall locale_facet__Decref(locale_facet *this)
328 {
329     _Lockit lock;
330     locale_facet *ret;
331
332     TRACE("(%p)\n", this);
333
334     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
335     if(this->refs)
336         this->refs--;
337
338     ret = this->refs ? NULL : this;
339     _Lockit_dtor(&lock);
340
341     return ret;
342 }
343
344 /* ?_Getcat@facet@locale@std@@SAIPAPBV123@PBV23@@Z */
345 /* ?_Getcat@facet@locale@std@@SA_KPEAPEBV123@PEBV23@@Z */
346 MSVCP_size_t __cdecl locale_facet__Getcat(const locale_facet **facet, const locale *loc)
347 {
348     TRACE("(%p %p)\n", facet, loc);
349     return -1;
350 }
351
352 /* ??0_Timevec@std@@QAE@ABV01@@Z */
353 /* ??0_Timevec@std@@QEAA@AEBV01@@Z */
354 /* This copy constructor modifies copied object */
355 DEFINE_THISCALL_WRAPPER(_Timevec_copy_ctor, 8)
356 _Timevec* __thiscall _Timevec_copy_ctor(_Timevec *this, _Timevec *copy)
357 {
358     TRACE("(%p %p)\n", this, copy);
359     this->timeptr = copy->timeptr;
360     copy->timeptr = NULL;
361     return this;
362 }
363
364 /* ??0_Timevec@std@@QAE@PAX@Z */
365 /* ??0_Timevec@std@@QEAA@PEAX@Z */
366 DEFINE_THISCALL_WRAPPER(_Timevec_ctor_timeptr, 8)
367 _Timevec* __thiscall _Timevec_ctor_timeptr(_Timevec *this, void *timeptr)
368 {
369     TRACE("(%p %p)\n", this, timeptr);
370     this->timeptr = timeptr;
371     return this;
372 }
373
374 /* ??_F_Timevec@std@@QAEXXZ */
375 /* ??_F_Timevec@std@@QEAAXXZ */
376 DEFINE_THISCALL_WRAPPER(_Timevec_ctor, 4)
377 _Timevec* __thiscall _Timevec_ctor(_Timevec *this)
378 {
379     TRACE("(%p)\n", this);
380     this->timeptr = NULL;
381     return this;
382 }
383
384 /* ??1_Timevec@std@@QAE@XZ */
385 /* ??1_Timevec@std@@QEAA@XZ */
386 DEFINE_THISCALL_WRAPPER(_Timevec_dtor, 4)
387 void __thiscall _Timevec_dtor(_Timevec *this)
388 {
389     TRACE("(%p)\n", this);
390     free(this->timeptr);
391 }
392
393 /* ??4_Timevec@std@@QAEAAV01@ABV01@@Z */
394 /* ??4_Timevec@std@@QEAAAEAV01@AEBV01@@Z */
395 DEFINE_THISCALL_WRAPPER(_Timevec_op_assign, 8)
396 _Timevec* __thiscall _Timevec_op_assign(_Timevec *this, _Timevec *right)
397 {
398     TRACE("(%p %p)\n", this, right);
399     this->timeptr = right->timeptr;
400     right->timeptr = NULL;
401     return this;
402 }
403
404 /* ?_Getptr@_Timevec@std@@QBEPAXXZ */
405 /* ?_Getptr@_Timevec@std@@QEBAPEAXXZ */
406 DEFINE_THISCALL_WRAPPER(_Timevec__Getptr, 4)
407 void* __thiscall _Timevec__Getptr(_Timevec *this)
408 {
409     TRACE("(%p)\n", this);
410     return this->timeptr;
411 }
412
413 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@HPBD@Z */
414 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@HPEBD@Z */
415 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cat_cstr(_Locinfo *locinfo, int category, const char *locstr)
416 {
417     const char *locale = NULL;
418
419     /* This function is probably modifying more global objects */
420     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
421
422     if(!locstr)
423         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
424
425     _Lockit_ctor_locktype(&locinfo->lock, _LOCK_LOCALE);
426     MSVCP_basic_string_char_ctor_cstr(&locinfo->days, "");
427     MSVCP_basic_string_char_ctor_cstr(&locinfo->months, "");
428     MSVCP_basic_string_char_ctor_cstr(&locinfo->oldlocname, setlocale(LC_ALL, NULL));
429
430     if(category)
431         locale = setlocale(LC_ALL, locstr);
432     else
433         locale = setlocale(LC_ALL, NULL);
434
435     if(locale)
436         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
437     else
438         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
439
440     return locinfo;
441 }
442
443 /* ??0_Locinfo@std@@QAE@HPBD@Z */
444 /* ??0_Locinfo@std@@QEAA@HPEBD@Z */
445 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cat_cstr, 12)
446 _Locinfo* __thiscall _Locinfo_ctor_cat_cstr(_Locinfo *this, int category, const char *locstr)
447 {
448     return _Locinfo__Locinfo_ctor_cat_cstr(this, category, locstr);
449 }
450
451 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
452 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
453 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_bstr(_Locinfo *locinfo, const basic_string_char *locstr)
454 {
455     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
456 }
457
458 /* ??0_Locinfo@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
459 /* ??0_Locinfo@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
460 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_bstr, 8)
461 _Locinfo* __thiscall _Locinfo_ctor_bstr(_Locinfo *this, const basic_string_char *locstr)
462 {
463     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
464 }
465
466 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@PBD@Z */
467 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@PEBD@Z */
468 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cstr(_Locinfo *locinfo, const char *locstr)
469 {
470     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, locstr);
471 }
472
473 /* ??0_Locinfo@std@@QAE@PBD@Z */
474 /* ??0_Locinfo@std@@QEAA@PEBD@Z */
475 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cstr, 8)
476 _Locinfo* __thiscall _Locinfo_ctor_cstr(_Locinfo *this, const char *locstr)
477 {
478     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, locstr);
479 }
480
481 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z */
482 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPEAV12@@Z */
483 void __cdecl _Locinfo__Locinfo_dtor(_Locinfo *locinfo)
484 {
485     TRACE("(%p)\n", locinfo);
486
487     setlocale(LC_ALL, MSVCP_basic_string_char_c_str(&locinfo->oldlocname));
488     MSVCP_basic_string_char_dtor(&locinfo->days);
489     MSVCP_basic_string_char_dtor(&locinfo->months);
490     MSVCP_basic_string_char_dtor(&locinfo->oldlocname);
491     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
492     _Lockit_dtor(&locinfo->lock);
493 }
494
495 /* ??_F_Locinfo@std@@QAEXXZ */
496 /* ??_F_Locinfo@std@@QEAAXXZ */
497 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor, 4)
498 _Locinfo* __thiscall _Locinfo_ctor(_Locinfo *this)
499 {
500     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, "C");
501 }
502
503 /* ??1_Locinfo@std@@QAE@XZ */
504 /* ??1_Locinfo@std@@QEAA@XZ */
505 DEFINE_THISCALL_WRAPPER(_Locinfo_dtor, 4)
506 void __thiscall _Locinfo_dtor(_Locinfo *this)
507 {
508     _Locinfo__Locinfo_dtor(this);
509 }
510
511 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAAV12@PAV12@HPBD@Z */
512 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAEAV12@PEAV12@HPEBD@Z */
513 _Locinfo* __cdecl _Locinfo__Locinfo_Addcats(_Locinfo *locinfo, int category, const char *locstr)
514 {
515     const char *locale = NULL;
516
517     /* This function is probably modifying more global objects */
518     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
519     if(!locstr)
520         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
521
522     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
523
524     if(category)
525         locale = setlocale(LC_ALL, locstr);
526     else
527         locale = setlocale(LC_ALL, NULL);
528
529     if(locale)
530         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
531     else
532         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
533
534     return locinfo;
535 }
536
537 /* ?_Addcats@_Locinfo@std@@QAEAAV12@HPBD@Z */
538 /* ?_Addcats@_Locinfo@std@@QEAAAEAV12@HPEBD@Z */
539 DEFINE_THISCALL_WRAPPER(_Locinfo__Addcats, 12)
540 _Locinfo* __thiscall _Locinfo__Addcats(_Locinfo *this, int category, const char *locstr)
541 {
542     return _Locinfo__Locinfo_Addcats(this, category, locstr);
543 }
544
545 /* _Getcoll */
546 ULONGLONG __cdecl _Getcoll(void)
547 {
548     union {
549         _Collvec collvec;
550         ULONGLONG ull;
551     } ret;
552     _locale_t locale = _get_current_locale();
553
554     TRACE("\n");
555
556     ret.collvec.page = locale->locinfo->lc_collate_cp;
557     ret.collvec.handle = locale->locinfo->lc_handle[LC_COLLATE];
558     _free_locale(locale);
559     return ret.ull;
560 }
561
562 /* ?_Getcoll@_Locinfo@std@@QBE?AU_Collvec@@XZ */
563 /* ?_Getcoll@_Locinfo@std@@QEBA?AU_Collvec@@XZ */
564 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcoll, 8)
565 _Collvec* __thiscall _Locinfo__Getcoll(const _Locinfo *this, _Collvec *ret)
566 {
567     ULONGLONG ull = _Getcoll();
568     memcpy(ret, &ull, sizeof(ull));
569     return ret;
570 }
571
572 /* _Getctype */
573 _Ctypevec* __cdecl _Getctype(_Ctypevec *ret)
574 {
575     _locale_t locale = _get_current_locale();
576     short *table;
577
578     TRACE("\n");
579
580     ret->page = locale->locinfo->lc_codepage;
581     ret->handle = locale->locinfo->lc_handle[LC_COLLATE];
582     ret->delfl = TRUE;
583     table = malloc(sizeof(short[256]));
584     if(!table) {
585         _free_locale(locale);
586         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
587     }
588     memcpy(table, locale->locinfo->pctype, sizeof(short[256]));
589     ret->table = table;
590     _free_locale(locale);
591     return ret;
592 }
593
594 /* ?_Getctype@_Locinfo@std@@QBE?AU_Ctypevec@@XZ */
595 /* ?_Getctype@_Locinfo@std@@QEBA?AU_Ctypevec@@XZ */
596 DEFINE_THISCALL_WRAPPER(_Locinfo__Getctype, 8)
597 _Ctypevec* __thiscall _Locinfo__Getctype(const _Locinfo *this, _Ctypevec *ret)
598 {
599     return _Getctype(ret);
600 }
601
602 /* _Getcvt */
603 ULONGLONG __cdecl _Getcvt(void)
604 {
605     _locale_t locale = _get_current_locale();
606     union {
607         _Cvtvec cvtvec;
608         ULONGLONG ull;
609     } ret;
610
611     TRACE("\n");
612
613     ret.cvtvec.page = locale->locinfo->lc_codepage;
614     ret.cvtvec.handle = locale->locinfo->lc_handle[LC_CTYPE];
615     _free_locale(locale);
616     return ret.ull;
617 }
618
619 /* ?_Getcvt@_Locinfo@std@@QBE?AU_Cvtvec@@XZ */
620 /* ?_Getcvt@_Locinfo@std@@QEBA?AU_Cvtvec@@XZ */
621 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcvt, 8)
622 _Cvtvec* __thiscall _Locinfo__Getcvt(const _Locinfo *this, _Cvtvec *ret)
623 {
624     ULONGLONG ull = _Getcvt();
625     memcpy(ret, &ull, sizeof(ull));
626     return ret;
627 }
628
629 /* ?_Getdateorder@_Locinfo@std@@QBEHXZ */
630 /* ?_Getdateorder@_Locinfo@std@@QEBAHXZ */
631 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdateorder, 4)
632 int __thiscall _Locinfo__Getdateorder(const _Locinfo *this)
633 {
634     FIXME("(%p) stub\n", this);
635     return 0;
636 }
637
638 /* ?_Getdays@_Locinfo@std@@QBEPBDXZ */
639 /* ?_Getdays@_Locinfo@std@@QEBAPEBDXZ */
640 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdays, 4)
641 const char* __thiscall _Locinfo__Getdays(_Locinfo *this)
642 {
643     char *days = _Getdays();
644
645     TRACE("(%p)\n", this);
646
647     if(days) {
648         MSVCP_basic_string_char_dtor(&this->days);
649         MSVCP_basic_string_char_ctor_cstr(&this->days, days);
650         free(days);
651     }
652
653     return this->days.size ? MSVCP_basic_string_char_c_str(&this->days) :
654         ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
655 }
656
657 /* ?_Getmonths@_Locinfo@std@@QBEPBDXZ */
658 /* ?_Getmonths@_Locinfo@std@@QEBAPEBDXZ */
659 DEFINE_THISCALL_WRAPPER(_Locinfo__Getmonths, 4)
660 const char* __thiscall _Locinfo__Getmonths(_Locinfo *this)
661 {
662     char *months = _Getmonths();
663
664     TRACE("(%p)\n", this);
665
666     if(months) {
667         MSVCP_basic_string_char_dtor(&this->months);
668         MSVCP_basic_string_char_ctor_cstr(&this->months, months);
669         free(months);
670     }
671
672     return this->months.size ? MSVCP_basic_string_char_c_str(&this->months) :
673         ":Jan:January:Feb:February:Mar:March:Apr:April:May:May:Jun:June:Jul:July"
674         ":Aug:August:Sep:September:Oct:October:Nov:November:Dec:December";
675 }
676
677 /* ?_Getfalse@_Locinfo@std@@QBEPBDXZ */
678 /* ?_Getfalse@_Locinfo@std@@QEBAPEBDXZ */
679 DEFINE_THISCALL_WRAPPER(_Locinfo__Getfalse, 4)
680 const char* __thiscall _Locinfo__Getfalse(const _Locinfo *this)
681 {
682     TRACE("(%p)\n", this);
683     return "false";
684 }
685
686 /* ?_Gettrue@_Locinfo@std@@QBEPBDXZ */
687 /* ?_Gettrue@_Locinfo@std@@QEBAPEBDXZ */
688 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettrue, 4)
689 const char* __thiscall _Locinfo__Gettrue(const _Locinfo *this)
690 {
691     TRACE("(%p)\n", this);
692     return "true";
693 }
694
695 /* ?_Getlconv@_Locinfo@std@@QBEPBUlconv@@XZ */
696 /* ?_Getlconv@_Locinfo@std@@QEBAPEBUlconv@@XZ */
697 DEFINE_THISCALL_WRAPPER(_Locinfo__Getlconv, 4)
698 const struct lconv* __thiscall _Locinfo__Getlconv(const _Locinfo *this)
699 {
700     TRACE("(%p)\n", this);
701     return localeconv();
702 }
703
704 /* ?_Getname@_Locinfo@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
705 /* ?_Getname@_Locinfo@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
706 DEFINE_THISCALL_WRAPPER(_Locinfo__Getname, 8)
707 basic_string_char* __thiscall _Locinfo__Getname(const _Locinfo *this, basic_string_char *ret)
708 {
709     TRACE("(%p)\n", this);
710
711     MSVCP_basic_string_char_copy_ctor(ret, &this->newlocname);
712     return ret;
713 }
714
715 /* ?_Gettnames@_Locinfo@std@@QBE?AV_Timevec@2@XZ */
716 /* ?_Gettnames@_Locinfo@std@@QEBA?AV_Timevec@2@XZ */
717 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettnames, 8)
718 _Timevec*__thiscall _Locinfo__Gettnames(const _Locinfo *this, _Timevec *ret)
719 {
720     TRACE("(%p)\n", this);
721
722     _Timevec_ctor_timeptr(ret, _Gettnames());
723     return ret;
724 }
725
726 /* ?id@?$collate@D@std@@2V0locale@2@A */
727 locale_id collate_char_id = {0};
728
729 /* ??_7?$collate@D@std@@6B@ */
730 extern const vtable_ptr MSVCP_collate_char_vtable;
731
732 /* ?_Init@?$collate@D@std@@IAEXABV_Locinfo@2@@Z */
733 /* ?_Init@?$collate@D@std@@IEAAXAEBV_Locinfo@2@@Z */
734 DEFINE_THISCALL_WRAPPER(collate_char__Init, 8)
735 void __thiscall collate_char__Init(collate *this, const _Locinfo *locinfo)
736 {
737     TRACE("(%p %p)\n", this, locinfo);
738     _Locinfo__Getcoll(locinfo, &this->coll);
739 }
740
741 /* ??0?$collate@D@std@@IAE@PBDI@Z */
742 /* ??0?$collate@D@std@@IEAA@PEBD_K@Z */
743 DEFINE_THISCALL_WRAPPER(collate_char_ctor_name, 12)
744 collate* __thiscall collate_char_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
745 {
746     _Locinfo locinfo;
747
748     TRACE("(%p %s %lu)\n", this, name, refs);
749
750     locale_facet_ctor_refs(&this->facet, refs);
751     this->facet.vtable = &MSVCP_collate_char_vtable;
752
753     _Locinfo_ctor_cstr(&locinfo, name);
754     collate_char__Init(this, &locinfo);
755     _Locinfo_dtor(&locinfo);
756     return this;
757 }
758
759 /* ??0?$collate@D@std@@QAE@ABV_Locinfo@1@I@Z */
760 /* ??0?$collate@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
761 DEFINE_THISCALL_WRAPPER(collate_char_ctor_locinfo, 12)
762 collate* __thiscall collate_char_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
763 {
764     TRACE("(%p %p %lu)\n", this, locinfo, refs);
765
766     locale_facet_ctor_refs(&this->facet, refs);
767     this->facet.vtable = &MSVCP_collate_char_vtable;
768     collate_char__Init(this, locinfo);
769     return this;
770 }
771
772 /* ??0?$collate@D@std@@QAE@I@Z */
773 /* ??0?$collate@D@std@@QEAA@_K@Z */
774 DEFINE_THISCALL_WRAPPER(collate_char_ctor_refs, 8)
775 collate* __thiscall collate_char_ctor_refs(collate *this, MSVCP_size_t refs)
776 {
777     return collate_char_ctor_name(this, "C", refs);
778 }
779
780 /* ??1?$collate@D@std@@MAE@XZ */
781 /* ??1?$collate@D@std@@MEAA@XZ */
782 DEFINE_THISCALL_WRAPPER(collate_char_dtor, 4)
783 void __thiscall collate_char_dtor(collate *this)
784 {
785     TRACE("(%p)\n", this);
786 }
787
788 DEFINE_THISCALL_WRAPPER(collate_char_vector_dtor, 8)
789 collate* __thiscall collate_char_vector_dtor(collate *this, unsigned int flags)
790 {
791     TRACE("(%p %x)\n", this, flags);
792     if(flags & 2) {
793         /* we have an array, with the number of elements stored before the first object */
794         INT_PTR i, *ptr = (INT_PTR *)this-1;
795
796         for(i=*ptr-1; i>=0; i--)
797             collate_char_dtor(this+i);
798         MSVCRT_operator_delete(ptr);
799     } else {
800         collate_char_dtor(this);
801         if(flags & 1)
802             MSVCRT_operator_delete(this);
803     }
804
805     return this;
806 }
807
808 /* ??_F?$collate@D@std@@QAEXXZ */
809 /* ??_F?$collate@D@std@@QEAAXXZ */
810 DEFINE_THISCALL_WRAPPER(collate_char_ctor, 4)
811 collate* __thiscall collate_char_ctor(collate *this)
812 {
813     return collate_char_ctor_name(this, "C", 0);
814 }
815
816 /* ?_Getcat@?$collate@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
817 /* ?_Getcat@?$collate@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
818 MSVCP_size_t __cdecl collate_char__Getcat(const locale_facet **facet, const locale *loc)
819 {
820     TRACE("(%p %p)\n", facet, loc);
821
822     if(facet && !*facet) {
823         *facet = MSVCRT_operator_new(sizeof(collate));
824         if(!*facet) {
825             ERR("Out of memory\n");
826             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
827             return 0;
828         }
829         collate_char_ctor_name((collate*)*facet,
830                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
831     }
832
833     return LC_COLLATE;
834 }
835
836 /* _Strcoll */
837 int __cdecl _Strcoll(const char *first1, const char *last1, const char *first2,
838         const char *last2, const _Collvec *coll)
839 {
840     LCID lcid;
841
842     TRACE("(%s %s)\n", debugstr_an(first1, last1-first1), debugstr_an(first2, last2-first2));
843
844     if(coll)
845         lcid = coll->handle;
846     else
847         lcid = ___lc_handle_func()[LC_COLLATE];
848     return CompareStringA(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
849 }
850
851 /* ?do_compare@?$collate@D@std@@MBEHPBD000@Z */
852 /* ?do_compare@?$collate@D@std@@MEBAHPEBD000@Z */
853 DEFINE_THISCALL_WRAPPER(collate_char_do_compare, 20)
854 #define call_collate_char_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
855         (const collate*, const char*, const char*, const char*, const char*), \
856         (this, first1, last1, first2, last2))
857 int __thiscall collate_char_do_compare(const collate *this, const char *first1,
858         const char *last1, const char *first2, const char *last2)
859 {
860     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
861     return _Strcoll(first1, last1, first2, last2, &this->coll);
862 }
863
864 /* ?compare@?$collate@D@std@@QBEHPBD000@Z */
865 /* ?compare@?$collate@D@std@@QEBAHPEBD000@Z */
866 DEFINE_THISCALL_WRAPPER(collate_char_compare, 20)
867 int __thiscall collate_char_compare(const collate *this, const char *first1,
868         const char *last1, const char *first2, const char *last2)
869 {
870     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
871     return call_collate_char_do_compare(this, first1, last1, first2, last2);
872 }
873
874 /* ?do_hash@?$collate@D@std@@MBEJPBD0@Z */
875 /* ?do_hash@?$collate@D@std@@MEBAJPEBD0@Z */
876 DEFINE_THISCALL_WRAPPER(collate_char_do_hash, 12)
877 #define call_collate_char_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
878         (const collate*, const char*, const char*), (this, first, last))
879 LONG __thiscall collate_char_do_hash(const collate *this,
880         const char *first, const char *last)
881 {
882     ULONG ret = 0;
883
884     TRACE("(%p %p %p)\n", this, first, last);
885
886     for(; first<last; first++)
887         ret = (ret<<8 | ret>>24) + *first;
888     return ret;
889 }
890
891 /* ?hash@?$collate@D@std@@QBEJPBD0@Z */
892 /* ?hash@?$collate@D@std@@QEBAJPEBD0@Z */
893 DEFINE_THISCALL_WRAPPER(collate_char_hash, 12)
894 LONG __thiscall collate_char_hash(const collate *this,
895         const char *first, const char *last)
896 {
897     TRACE("(%p %p %p)\n", this, first, last);
898     return call_collate_char_do_hash(this, first, last);
899 }
900
901 /* ?do_transform@?$collate@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
902 /* ?do_transform@?$collate@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
903 DEFINE_THISCALL_WRAPPER(collate_char_do_transform, 16)
904 basic_string_char* __thiscall collate_char_do_transform(const collate *this,
905         basic_string_char *ret, const char *first, const char *last)
906 {
907     FIXME("(%p %p %p) stub\n", this, first, last);
908     return ret;
909 }
910
911 /* ?transform@?$collate@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
912 /* ?transform@?$collate@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
913 DEFINE_THISCALL_WRAPPER(collate_char_transform, 16)
914 basic_string_char* __thiscall collate_char_transform(const collate *this,
915         basic_string_char *ret, const char *first, const char *last)
916 {
917     FIXME("(%p %p %p) stub\n", this, first, last);
918     return ret;
919 }
920
921 /* ?id@?$collate@_W@std@@2V0locale@2@A */
922 locale_id collate_wchar_id = {0};
923 /* ?id@?$collate@G@std@@2V0locale@2@A */
924 locale_id collate_short_id = {0};
925
926 /* ??_7?$collate@_W@std@@6B@ */
927 extern const vtable_ptr MSVCP_collate_wchar_vtable;
928 /* ??_7?$collate@G@std@@6B@ */
929 extern const vtable_ptr MSVCP_collate_short_vtable;
930
931 /* ?_Init@?$collate@_W@std@@IAEXABV_Locinfo@2@@Z */
932 /* ?_Init@?$collate@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
933 /* ?_Init@?$collate@G@std@@IAEXABV_Locinfo@2@@Z */
934 /* ?_Init@?$collate@G@std@@IEAAXAEBV_Locinfo@2@@Z */
935 DEFINE_THISCALL_WRAPPER(collate_wchar__Init, 8)
936 void __thiscall collate_wchar__Init(collate *this, const _Locinfo *locinfo)
937 {
938     TRACE("(%p %p)\n", this, locinfo);
939     _Locinfo__Getcoll(locinfo, &this->coll);
940 }
941
942 /* ??0?$collate@_W@std@@IAE@PBDI@Z */
943 /* ??0?$collate@_W@std@@IEAA@PEBD_K@Z */
944 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_name, 12)
945 collate* __thiscall collate_wchar_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
946 {
947     _Locinfo locinfo;
948
949     TRACE("(%p %s %lu)\n", this, name, refs);
950
951     locale_facet_ctor_refs(&this->facet, refs);
952     this->facet.vtable = &MSVCP_collate_wchar_vtable;
953
954     _Locinfo_ctor_cstr(&locinfo, name);
955     collate_wchar__Init(this, &locinfo);
956     _Locinfo_dtor(&locinfo);
957     return this;
958 }
959
960 /* ??0?$collate@G@std@@IAE@PBDI@Z */
961 /* ??0?$collate@G@std@@IEAA@PEBD_K@Z */
962 DEFINE_THISCALL_WRAPPER(collate_short_ctor_name, 12)
963 collate* __thiscall collate_short_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
964 {
965     collate *ret = collate_wchar_ctor_name(this, name, refs);
966     ret->facet.vtable = &MSVCP_collate_short_vtable;
967     return ret;
968 }
969
970 /* ??0?$collate@_W@std@@QAE@ABV_Locinfo@1@I@Z */
971 /* ??0?$collate@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
972 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_locinfo, 12)
973 collate* __thiscall collate_wchar_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
974 {
975     TRACE("(%p %p %lu)\n", this, locinfo, refs);
976
977     locale_facet_ctor_refs(&this->facet, refs);
978     this->facet.vtable = &MSVCP_collate_wchar_vtable;
979     collate_wchar__Init(this, locinfo);
980     return this;
981 }
982
983 /* ??0?$collate@G@std@@QAE@ABV_Locinfo@1@I@Z */
984 /* ??0?$collate@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
985 DEFINE_THISCALL_WRAPPER(collate_short_ctor_locinfo, 12)
986 collate* __thiscall collate_short_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
987 {
988     collate *ret = collate_wchar_ctor_locinfo(this, locinfo, refs);
989     ret->facet.vtable = &MSVCP_collate_short_vtable;
990     return ret;
991 }
992
993 /* ??0?$collate@_W@std@@QAE@I@Z */
994 /* ??0?$collate@_W@std@@QEAA@_K@Z */
995 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_refs, 8)
996 collate* __thiscall collate_wchar_ctor_refs(collate *this, MSVCP_size_t refs)
997 {
998     return collate_wchar_ctor_name(this, "C", refs);
999 }
1000
1001 /* ??0?$collate@G@std@@QAE@I@Z */
1002 /* ??0?$collate@G@std@@QEAA@_K@Z */
1003 DEFINE_THISCALL_WRAPPER(collate_short_ctor_refs, 8)
1004 collate* __thiscall collate_short_ctor_refs(collate *this, MSVCP_size_t refs)
1005 {
1006     collate *ret = collate_wchar_ctor_refs(this, refs);
1007     ret->facet.vtable = &MSVCP_collate_short_vtable;
1008     return ret;
1009 }
1010
1011 /* ??1?$collate@_W@std@@MAE@XZ */
1012 /* ??1?$collate@_W@std@@MEAA@XZ */
1013 /* ??1?$collate@G@std@@MAE@XZ */
1014 /* ??1?$collate@G@std@@MEAA@XZ */
1015 DEFINE_THISCALL_WRAPPER(collate_wchar_dtor, 4)
1016 void __thiscall collate_wchar_dtor(collate *this)
1017 {
1018     TRACE("(%p)\n", this);
1019 }
1020
1021 DEFINE_THISCALL_WRAPPER(collate_wchar_vector_dtor, 8)
1022 collate* __thiscall collate_wchar_vector_dtor(collate *this, unsigned int flags)
1023 {
1024     TRACE("(%p %x)\n", this, flags);
1025     if(flags & 2) {
1026         /* we have an array, with the number of elements stored before the first object */
1027         INT_PTR i, *ptr = (INT_PTR *)this-1;
1028
1029         for(i=*ptr-1; i>=0; i--)
1030             collate_wchar_dtor(this+i);
1031         MSVCRT_operator_delete(ptr);
1032     } else {
1033         collate_wchar_dtor(this);
1034         if(flags & 1)
1035             MSVCRT_operator_delete(this);
1036     }
1037
1038     return this;
1039 }
1040
1041 /* ??_F?$collate@_W@std@@QAEXXZ */
1042 /* ??_F?$collate@_W@std@@QEAAXXZ */
1043 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor, 4)
1044 collate* __thiscall collate_wchar_ctor(collate *this)
1045 {
1046     return collate_wchar_ctor_name(this, "C", 0);
1047 }
1048
1049 /* ??_F?$collate@G@std@@QAEXXZ */
1050 /* ??_F?$collate@G@std@@QEAAXXZ */
1051 DEFINE_THISCALL_WRAPPER(collate_short_ctor, 4)
1052 collate* __thiscall collate_short_ctor(collate *this)
1053 {
1054     collate *ret = collate_wchar_ctor(this);
1055     ret->facet.vtable = &MSVCP_collate_short_vtable;
1056     return ret;
1057 }
1058
1059 /* ?_Getcat@?$collate@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1060 /* ?_Getcat@?$collate@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1061 MSVCP_size_t __cdecl collate_wchar__Getcat(const locale_facet **facet, const locale *loc)
1062 {
1063     TRACE("(%p %p)\n", facet, loc);
1064
1065     if(facet && !*facet) {
1066         *facet = MSVCRT_operator_new(sizeof(collate));
1067         if(!*facet) {
1068             ERR("Out of memory\n");
1069             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1070             return 0;
1071         }
1072         collate_wchar_ctor_name((collate*)*facet,
1073                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
1074     }
1075
1076     return LC_COLLATE;
1077 }
1078
1079 /* ?_Getcat@?$collate@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1080 /* ?_Getcat@?$collate@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1081 MSVCP_size_t __cdecl collate_short__Getcat(const locale_facet **facet, const locale *loc)
1082 {
1083     if(facet && !*facet) {
1084         collate_wchar__Getcat(facet, loc);
1085         (*(locale_facet**)facet)->vtable = &MSVCP_collate_short_vtable;
1086     }
1087
1088     return LC_COLLATE;
1089 }
1090
1091 /* _Wcscoll */
1092 int __cdecl _Wcscoll(const wchar_t *first1, const wchar_t *last1, const wchar_t *first2,
1093         const wchar_t *last2, const _Collvec *coll)
1094 {
1095     LCID lcid;
1096
1097     TRACE("(%s %s)\n", debugstr_wn(first1, last1-first1), debugstr_wn(first2, last2-first2));
1098
1099     if(coll)
1100         lcid = coll->handle;
1101     else
1102         lcid = ___lc_handle_func()[LC_COLLATE];
1103     return CompareStringW(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
1104 }
1105
1106 /* ?do_compare@?$collate@_W@std@@MBEHPB_W000@Z */
1107 /* ?do_compare@?$collate@_W@std@@MEBAHPEB_W000@Z */
1108 /* ?do_compare@?$collate@G@std@@MBEHPBG000@Z */
1109 /* ?do_compare@?$collate@G@std@@MEBAHPEBG000@Z */
1110 DEFINE_THISCALL_WRAPPER(collate_wchar_do_compare, 20)
1111 #define call_collate_wchar_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
1112         (const collate*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*), \
1113         (this, first1, last1, first2, last2))
1114 int __thiscall collate_wchar_do_compare(const collate *this, const wchar_t *first1,
1115         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1116 {
1117     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1118     return _Wcscoll(first1, last1, first2, last2, &this->coll);
1119 }
1120
1121 /* ?compare@?$collate@_W@std@@QBEHPB_W000@Z */
1122 /* ?compare@?$collate@_W@std@@QEBAHPEB_W000@Z */
1123 /* ?compare@?$collate@G@std@@QBEHPBG000@Z */
1124 /* ?compare@?$collate@G@std@@QEBAHPEBG000@Z */
1125 DEFINE_THISCALL_WRAPPER(collate_wchar_compare, 20)
1126 int __thiscall collate_wchar_compare(const collate *this, const wchar_t *first1,
1127         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1128 {
1129     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1130     return call_collate_wchar_do_compare(this, first1, last1, first2, last2);
1131 }
1132
1133 /* ?do_hash@?$collate@_W@std@@MBEJPB_W0@Z */
1134 /* ?do_hash@?$collate@_W@std@@MEBAJPEB_W0@Z */
1135 /* ?do_hash@?$collate@G@std@@MBEJPBG0@Z */
1136 /* ?do_hash@?$collate@G@std@@MEBAJPEBG0@Z */
1137 DEFINE_THISCALL_WRAPPER(collate_wchar_do_hash, 12)
1138 #define call_collate_wchar_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
1139         (const collate*, const wchar_t*, const wchar_t*), (this, first, last))
1140 LONG __thiscall collate_wchar_do_hash(const collate *this,
1141         const wchar_t *first, const wchar_t *last)
1142 {
1143     ULONG ret = 0;
1144
1145     TRACE("(%p %p %p)\n", this, first, last);
1146
1147     for(; first<last; first++)
1148         ret = (ret<<8 | ret>>24) + *first;
1149     return ret;
1150 }
1151
1152 /* ?hash@?$collate@_W@std@@QBEJPB_W0@Z */
1153 /* ?hash@?$collate@_W@std@@QEBAJPEB_W0@Z */
1154 /* ?hash@?$collate@G@std@@QBEJPBG0@Z */
1155 /* ?hash@?$collate@G@std@@QEBAJPEBG0@Z */
1156 DEFINE_THISCALL_WRAPPER(collate_wchar_hash, 12)
1157 LONG __thiscall collate_wchar_hash(const collate *this,
1158         const wchar_t *first, const wchar_t *last)
1159 {
1160     TRACE("(%p %p %p)\n", this, first, last);
1161     return call_collate_wchar_do_hash(this, first, last);
1162 }
1163
1164 /* ?do_transform@?$collate@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1165 /* ?do_transform@?$collate@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1166 /* ?do_transform@?$collate@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1167 /* ?do_transform@?$collate@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1168 DEFINE_THISCALL_WRAPPER(collate_wchar_do_transform, 16)
1169 basic_string_wchar* __thiscall collate_wchar_do_transform(const collate *this,
1170         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1171 {
1172     FIXME("(%p %p %p) stub\n", this, first, last);
1173     return ret;
1174 }
1175
1176 /* ?transform@?$collate@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1177 /* ?transform@?$collate@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1178 /* ?transform@?$collate@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1179 /* ?transform@?$collate@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1180 DEFINE_THISCALL_WRAPPER(collate_wchar_transform, 16)
1181 basic_string_wchar* __thiscall collate_wchar_transform(const collate *this,
1182         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1183 {
1184     FIXME("(%p %p %p) stub\n", this, first, last);
1185     return ret;
1186 }
1187
1188 /* ??_7ctype_base@std@@6B@ */
1189 extern const vtable_ptr MSVCP_ctype_base_vtable;
1190
1191 /* ??0ctype_base@std@@QAE@I@Z */
1192 /* ??0ctype_base@std@@QEAA@_K@Z */
1193 DEFINE_THISCALL_WRAPPER(ctype_base_ctor_refs, 8)
1194 ctype_base* __thiscall ctype_base_ctor_refs(ctype_base *this, MSVCP_size_t refs)
1195 {
1196     TRACE("(%p %lu)\n", this, refs);
1197     locale_facet_ctor_refs(&this->facet, refs);
1198     this->facet.vtable = &MSVCP_ctype_base_vtable;
1199     return this;
1200 }
1201
1202 /* ??_Fctype_base@std@@QAEXXZ */
1203 /* ??_Fctype_base@std@@QEAAXXZ */
1204 DEFINE_THISCALL_WRAPPER(ctype_base_ctor, 4)
1205 ctype_base* __thiscall ctype_base_ctor(ctype_base *this)
1206 {
1207     TRACE("(%p)\n", this);
1208     locale_facet_ctor_refs(&this->facet, 0);
1209     this->facet.vtable = &MSVCP_ctype_base_vtable;
1210     return this;
1211 }
1212
1213 /* ??1ctype_base@std@@UAE@XZ */
1214 /* ??1ctype_base@std@@UEAA@XZ */
1215 DEFINE_THISCALL_WRAPPER(ctype_base_dtor, 4)
1216 void __thiscall ctype_base_dtor(ctype_base *this)
1217 {
1218     TRACE("(%p)\n", this);
1219 }
1220
1221 DEFINE_THISCALL_WRAPPER(ctype_base_vector_dtor, 8)
1222 ctype_base* __thiscall ctype_base_vector_dtor(ctype_base *this, unsigned int flags)
1223 {
1224     TRACE("(%p %x)\n", this, flags);
1225     if(flags & 2) {
1226         /* we have an array, with the number of elements stored before the first object */
1227         INT_PTR i, *ptr = (INT_PTR *)this-1;
1228
1229         for(i=*ptr-1; i>=0; i--)
1230             ctype_base_dtor(this+i);
1231         MSVCRT_operator_delete(ptr);
1232     } else {
1233         ctype_base_dtor(this);
1234         if(flags & 1)
1235             MSVCRT_operator_delete(this);
1236     }
1237
1238     return this;
1239 }
1240
1241 /* ?_Xran@ctype_base@std@@KAXXZ */
1242 void __cdecl ctype_base__Xran(void)
1243 {
1244     throw_exception(EXCEPTION_OUT_OF_RANGE, "out of range in ctype<T>");
1245 }
1246
1247 /* ?id@?$ctype@D@std@@2V0locale@2@A */
1248 locale_id ctype_char_id = {0};
1249 /* ?table_size@?$ctype@D@std@@2IB */
1250 /* ?table_size@?$ctype@D@std@@2_KB */
1251 MSVCP_size_t ctype_char_table_size = 256;
1252
1253 /* ??_7?$ctype@D@std@@6B@ */
1254 extern const vtable_ptr MSVCP_ctype_char_vtable;
1255
1256 /* ?_Id_func@?$ctype@D@std@@SAAAVid@locale@2@XZ */
1257 /* ?_Id_func@?$ctype@D@std@@SAAEAVid@locale@2@XZ */
1258 locale_id* __cdecl ctype_char__Id_func(void)
1259 {
1260     TRACE("()\n");
1261     return &ctype_char_id;
1262 }
1263
1264 /* ?_Init@?$ctype@D@std@@IAEXABV_Locinfo@2@@Z */
1265 /* ?_Init@?$ctype@D@std@@IEAAXAEBV_Locinfo@2@@Z */
1266 DEFINE_THISCALL_WRAPPER(ctype_char__Init, 8)
1267 void __thiscall ctype_char__Init(ctype_char *this, const _Locinfo *locinfo)
1268 {
1269     TRACE("(%p %p)\n", this, locinfo);
1270     _Locinfo__Getctype(locinfo, &this->ctype);
1271 }
1272
1273 /* ?_Tidy@?$ctype@D@std@@IAEXXZ */
1274 /* ?_Tidy@?$ctype@D@std@@IEAAXXZ */
1275 DEFINE_THISCALL_WRAPPER(ctype_char__Tidy, 4)
1276 void __thiscall ctype_char__Tidy(ctype_char *this)
1277 {
1278     TRACE("(%p)\n", this);
1279
1280     if(this->ctype.delfl)
1281         free((short*)this->ctype.table);
1282 }
1283
1284 /* ?classic_table@?$ctype@D@std@@KAPBFXZ */
1285 /* ?classic_table@?$ctype@D@std@@KAPEBFXZ */
1286 const short* __cdecl ctype_char_classic_table(void)
1287 {
1288     TRACE("()\n");
1289     return &((short*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_ctype"))[1];
1290 }
1291
1292 /* ??0?$ctype@D@std@@QAE@ABV_Locinfo@1@I@Z */
1293 /* ??0?$ctype@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1294 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_locinfo, 12)
1295 ctype_char* __thiscall ctype_char_ctor_locinfo(ctype_char *this,
1296         const _Locinfo *locinfo, MSVCP_size_t refs)
1297 {
1298     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1299     ctype_base_ctor_refs(&this->base, refs);
1300     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1301     ctype_char__Init(this, locinfo);
1302     return this;
1303 }
1304
1305 /* ??0?$ctype@D@std@@QAE@PBF_NI@Z */
1306 /* ??0?$ctype@D@std@@QEAA@PEBF_N_K@Z */
1307 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_table, 16)
1308 ctype_char* __thiscall ctype_char_ctor_table(ctype_char *this,
1309         const short *table, MSVCP_bool delete, MSVCP_size_t refs)
1310 {
1311     _Locinfo locinfo;
1312
1313     TRACE("(%p %p %d %lu)\n", this, table, delete, refs);
1314
1315     ctype_base_ctor_refs(&this->base, refs);
1316     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1317
1318     _Locinfo_ctor(&locinfo);
1319     ctype_char__Init(this, &locinfo);
1320     _Locinfo_dtor(&locinfo);
1321
1322     if(table) {
1323         ctype_char__Tidy(this);
1324         this->ctype.table = table;
1325         this->ctype.delfl = delete;
1326     }
1327     return this;
1328 }
1329
1330 /* ??_F?$ctype@D@std@@QAEXXZ */
1331 /* ??_F?$ctype@D@std@@QEAAXXZ */
1332 DEFINE_THISCALL_WRAPPER(ctype_char_ctor, 4)
1333 ctype_char* __thiscall ctype_char_ctor(ctype_char *this)
1334 {
1335     return ctype_char_ctor_table(this, NULL, FALSE, 0);
1336 }
1337
1338 /* ??1?$ctype@D@std@@MAE@XZ */
1339 /* ??1?$ctype@D@std@@MEAA@XZ */
1340 DEFINE_THISCALL_WRAPPER(ctype_char_dtor, 4)
1341 void __thiscall ctype_char_dtor(ctype_char *this)
1342 {
1343     TRACE("(%p)\n", this);
1344     ctype_char__Tidy(this);
1345 }
1346
1347 DEFINE_THISCALL_WRAPPER(ctype_char_vector_dtor, 8)
1348 ctype_char* __thiscall ctype_char_vector_dtor(ctype_char *this, unsigned int flags)
1349 {
1350     TRACE("(%p %x)\n", this, flags);
1351     if(flags & 2) {
1352         /* we have an array, with the number of elements stored before the first object */
1353         INT_PTR i, *ptr = (INT_PTR *)this-1;
1354
1355         for(i=*ptr-1; i>=0; i--)
1356             ctype_char_dtor(this+i);
1357         MSVCRT_operator_delete(ptr);
1358     } else {
1359         ctype_char_dtor(this);
1360         if(flags & 1)
1361             MSVCRT_operator_delete(this);
1362     }
1363
1364     return this;
1365 }
1366
1367 /* ?do_narrow@?$ctype@D@std@@MBEDDD@Z */
1368 /* ?do_narrow@?$ctype@D@std@@MEBADDD@Z */
1369 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow_ch, 12)
1370 #define call_ctype_char_do_narrow_ch(this, ch, unused) CALL_VTBL_FUNC(this, 36, \
1371         char, (const ctype_char*, char, char), (this, ch, unused))
1372 char __thiscall ctype_char_do_narrow_ch(const ctype_char *this, char ch, char unused)
1373 {
1374     TRACE("(%p %c %c)\n", this, ch, unused);
1375     return ch;
1376 }
1377
1378 /* ?do_narrow@?$ctype@D@std@@MBEPBDPBD0DPAD@Z */
1379 /* ?do_narrow@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD@Z */
1380 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow, 20)
1381 #define call_ctype_char_do_narrow(this, first, last, unused, dest) CALL_VTBL_FUNC(this, 32, \
1382         const char*, (const ctype_char*, const char*, const char*, char, char*), \
1383         (this, first, last, unused, dest))
1384 const char* __thiscall ctype_char_do_narrow(const ctype_char *this,
1385         const char *first, const char *last, char unused, char *dest)
1386 {
1387     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1388     memcpy(dest, first, last-first);
1389     return last;
1390 }
1391
1392 /* ?_Do_narrow_s@?$ctype@D@std@@MBEPBDPBD0DPADI@Z */
1393 /* ?_Do_narrow_s@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD_K@Z */
1394 DEFINE_THISCALL_WRAPPER(ctype_char__Do_narrow_s, 24)
1395 #define call_ctype_char__Do_narrow_s(this, first, last, unused, dest, size) CALL_VTBL_FUNC(this, 40, \
1396         const char*, (const ctype_char*, const char*, const char*, char, char*, MSVCP_size_t), \
1397         (this, first, last, unused, dest, size))
1398 const char* __thiscall ctype_char__Do_narrow_s(const ctype_char *this, const char *first,
1399         const char *last, char unused, char *dest, MSVCP_size_t size)
1400 {
1401     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1402     memcpy_s(dest, size, first, last-first);
1403     return last;
1404 }
1405
1406 /* ?narrow@?$ctype@D@std@@QBEDDD@Z */
1407 /* ?narrow@?$ctype@D@std@@QEBADDD@Z */
1408 DEFINE_THISCALL_WRAPPER(ctype_char_narrow_ch, 12)
1409 char __thiscall ctype_char_narrow_ch(const ctype_char *this, char ch, char dflt)
1410 {
1411     TRACE("(%p %c %c)\n", this, ch, dflt);
1412     return call_ctype_char_do_narrow_ch(this, ch, dflt);
1413 }
1414
1415 /* ?narrow@?$ctype@D@std@@QBEPBDPBD0DPAD@Z */
1416 /* ?narrow@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD@Z */
1417 DEFINE_THISCALL_WRAPPER(ctype_char_narrow, 20)
1418 const char* __thiscall ctype_char_narrow(const ctype_char *this,
1419         const char *first, const char *last, char dflt, char *dest)
1420 {
1421     TRACE("(%p %p %p %c %p)\n", this, first, last, dflt, dest);
1422     return call_ctype_char_do_narrow(this, first, last, dflt, dest);
1423 }
1424
1425 /* ?_Narrow_s@?$ctype@D@std@@QBEPBDPBD0DPADI@Z */
1426 /* ?_Narrow_s@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD_K@Z */
1427 DEFINE_THISCALL_WRAPPER(ctype_char__Narrow_s, 24)
1428 const char* __thiscall ctype_char__Narrow_s(const ctype_char *this, const char *first,
1429         const char *last, char dflt, char *dest, MSVCP_size_t size)
1430 {
1431     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1432     return call_ctype_char__Do_narrow_s(this, first, last, dflt, dest, size);
1433 }
1434
1435 /* ?do_widen@?$ctype@D@std@@MBEDD@Z */
1436 /* ?do_widen@?$ctype@D@std@@MEBADD@Z */
1437 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen_ch, 8)
1438 #define call_ctype_char_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
1439         char, (const ctype_char*, char), (this, ch))
1440 char __thiscall ctype_char_do_widen_ch(const ctype_char *this, char ch)
1441 {
1442     TRACE("(%p %c)\n", this, ch);
1443     return ch;
1444 }
1445
1446 /* ?do_widen@?$ctype@D@std@@MBEPBDPBD0PAD@Z */
1447 /* ?do_widen@?$ctype@D@std@@MEBAPEBDPEBD0PEAD@Z */
1448 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen, 16)
1449 #define call_ctype_char_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 20, \
1450         const char*, (const ctype_char*, const char*, const char*, char*), \
1451         (this, first, last, dest))
1452 const char* __thiscall ctype_char_do_widen(const ctype_char *this,
1453         const char *first, const char *last, char *dest)
1454 {
1455     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1456     memcpy(dest, first, last-first);
1457     return last;
1458 }
1459
1460 /* ?_Do_widen_s@?$ctype@D@std@@MBEPBDPBD0PADI@Z */
1461 /* ?_Do_widen_s@?$ctype@D@std@@MEBAPEBDPEBD0PEAD_K@Z */
1462 DEFINE_THISCALL_WRAPPER(ctype_char__Do_widen_s, 20)
1463 #define call_ctype_char__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 28, \
1464         const char*, (const ctype_char*, const char*, const char*, char*, MSVCP_size_t), \
1465         (this, first, last, dest, size))
1466 const char* __thiscall ctype_char__Do_widen_s(const ctype_char *this,
1467         const char *first, const char *last, char *dest, MSVCP_size_t size)
1468 {
1469     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1470     memcpy_s(dest, size, first, last-first);
1471     return last;
1472 }
1473
1474 /* ?widen@?$ctype@D@std@@QBEDD@Z */
1475 /* ?widen@?$ctype@D@std@@QEBADD@Z */
1476 DEFINE_THISCALL_WRAPPER(ctype_char_widen_ch, 8)
1477 char __thiscall ctype_char_widen_ch(const ctype_char *this, char ch)
1478 {
1479     TRACE("(%p %c)\n", this, ch);
1480     return call_ctype_char_do_widen_ch(this, ch);
1481 }
1482
1483 /* ?widen@?$ctype@D@std@@QBEPBDPBD0PAD@Z */
1484 /* ?widen@?$ctype@D@std@@QEBAPEBDPEBD0PEAD@Z */
1485 DEFINE_THISCALL_WRAPPER(ctype_char_widen, 16)
1486 const char* __thiscall ctype_char_widen(const ctype_char *this,
1487         const char *first, const char *last, char *dest)
1488 {
1489     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1490     return call_ctype_char_do_widen(this, first, last, dest);
1491 }
1492
1493 /* ?_Widen_s@?$ctype@D@std@@QBEPBDPBD0PADI@Z */
1494 /* ?_Widen_s@?$ctype@D@std@@QEBAPEBDPEBD0PEAD_K@Z */
1495 DEFINE_THISCALL_WRAPPER(ctype_char__Widen_s, 20)
1496 const char* __thiscall ctype_char__Widen_s(const ctype_char *this,
1497         const char *first, const char *last, char *dest, MSVCP_size_t size)
1498 {
1499     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1500     return call_ctype_char__Do_widen_s(this, first, last, dest, size);
1501 }
1502
1503 /* ?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1504 /* ?_Getcat@?$ctype@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1505 MSVCP_size_t __cdecl ctype_char__Getcat(const locale_facet **facet, const locale *loc)
1506 {
1507     TRACE("(%p %p)\n", facet, loc);
1508
1509     if(facet && !*facet) {
1510         _Locinfo locinfo;
1511
1512         *facet = MSVCRT_operator_new(sizeof(ctype_char));
1513         if(!*facet) {
1514             ERR("Out of memory\n");
1515             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1516             return 0;
1517         }
1518
1519         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
1520         ctype_char_ctor_locinfo((ctype_char*)*facet, &locinfo, 0);
1521         _Locinfo_dtor(&locinfo);
1522     }
1523
1524     return LC_CTYPE;
1525 }
1526
1527 ctype_char* ctype_char_use_facet(const locale *loc)
1528 {
1529     static ctype_char *obj = NULL;
1530
1531     _Lockit lock;
1532     const locale_facet *fac;
1533
1534     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
1535     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_char_id));
1536     if(fac) {
1537         _Lockit_dtor(&lock);
1538         return (ctype_char*)fac;
1539     }
1540
1541     if(obj) {
1542         _Lockit_dtor(&lock);
1543         return obj;
1544     }
1545
1546     ctype_char__Getcat(&fac, loc);
1547     obj = (ctype_char*)fac;
1548     locale_facet__Incref(&obj->base.facet);
1549     locale_facet_register(&obj->base.facet);
1550     _Lockit_dtor(&lock);
1551
1552     return obj;
1553 }
1554
1555 /* _Tolower */
1556 int __cdecl _Tolower(int ch, const _Ctypevec *ctype)
1557 {
1558     unsigned int cp;
1559
1560     TRACE("%d %p\n", ch, ctype);
1561
1562     if(ctype)
1563         cp = ctype->page;
1564     else
1565         cp = ___lc_codepage_func();
1566
1567     /* Don't convert to unicode in case of C locale */
1568     if(!cp) {
1569         if(ch>='A' && ch<='Z')
1570             ch = ch-'A'+'a';
1571         return ch;
1572     } else {
1573         WCHAR wide, lower;
1574         char str[2];
1575         int size;
1576
1577         if(ch > 255) {
1578             str[0] = (ch>>8) & 255;
1579             str[1] = ch & 255;
1580             size = 2;
1581         } else {
1582             str[0] = ch & 255;
1583             size = 1;
1584         }
1585
1586         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1587             return ch;
1588
1589         lower = tolowerW(wide);
1590         if(lower == wide)
1591             return ch;
1592
1593         WideCharToMultiByte(cp, 0, &lower, 1, str, 2, NULL, NULL);
1594
1595         return str[0] + (str[1]<<8);
1596     }
1597 }
1598
1599 /* ?do_tolower@?$ctype@D@std@@MBEDD@Z */
1600 /* ?do_tolower@?$ctype@D@std@@MEBADD@Z */
1601 #define call_ctype_char_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 8, \
1602         char, (const ctype_char*, char), (this, ch))
1603 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower_ch, 8)
1604 char __thiscall ctype_char_do_tolower_ch(const ctype_char *this, char ch)
1605 {
1606     TRACE("(%p %c)\n", this, ch);
1607     return _Tolower(ch, &this->ctype);
1608 }
1609
1610 /* ?do_tolower@?$ctype@D@std@@MBEPBDPADPBD@Z */
1611 /* ?do_tolower@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1612 #define call_ctype_char_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 4, \
1613         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1614 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower, 12)
1615 const char* __thiscall ctype_char_do_tolower(const ctype_char *this, char *first, const char *last)
1616 {
1617     TRACE("(%p %p %p)\n", this, first, last);
1618     for(; first<last; first++)
1619         *first = _Tolower(*first, &this->ctype);
1620     return last;
1621 }
1622
1623 /* ?tolower@?$ctype@D@std@@QBEDD@Z */
1624 /* ?tolower@?$ctype@D@std@@QEBADD@Z */
1625 DEFINE_THISCALL_WRAPPER(ctype_char_tolower_ch, 8)
1626 char __thiscall ctype_char_tolower_ch(const ctype_char *this, char ch)
1627 {
1628     TRACE("(%p %c)\n", this, ch);
1629     return call_ctype_char_do_tolower_ch(this, ch);
1630 }
1631
1632 /* ?tolower@?$ctype@D@std@@QBEPBDPADPBD@Z */
1633 /* ?tolower@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1634 DEFINE_THISCALL_WRAPPER(ctype_char_tolower, 12)
1635 const char* __thiscall ctype_char_tolower(const ctype_char *this, char *first, const char *last)
1636 {
1637     TRACE("(%p %p %p)\n", this, first, last);
1638     return call_ctype_char_do_tolower(this, first, last);
1639 }
1640
1641 /* _Toupper */
1642 int __cdecl _Toupper(int ch, const _Ctypevec *ctype)
1643 {
1644     unsigned int cp;
1645
1646     TRACE("%d %p\n", ch, ctype);
1647
1648     if(ctype)
1649         cp = ctype->page;
1650     else
1651         cp = ___lc_codepage_func();
1652
1653     /* Don't convert to unicode in case of C locale */
1654     if(!cp) {
1655         if(ch>='a' && ch<='z')
1656             ch = ch-'a'+'A';
1657         return ch;
1658     } else {
1659         WCHAR wide, upper;
1660         char str[2];
1661         int size;
1662
1663         if(ch > 255) {
1664             str[0] = (ch>>8) & 255;
1665             str[1] = ch & 255;
1666             size = 2;
1667         } else {
1668             str[0] = ch & 255;
1669             size = 1;
1670         }
1671
1672         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1673             return ch;
1674
1675         upper = toupperW(wide);
1676         if(upper == wide)
1677             return ch;
1678
1679         WideCharToMultiByte(cp, 0, &upper, 1, str, 2, NULL, NULL);
1680
1681         return str[0] + (str[1]<<8);
1682     }
1683 }
1684
1685 /* ?do_toupper@?$ctype@D@std@@MBEDD@Z */
1686 /* ?do_toupper@?$ctype@D@std@@MEBADD@Z */
1687 #define call_ctype_char_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 16, \
1688         char, (const ctype_char*, char), (this, ch))
1689 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper_ch, 8)
1690 char __thiscall ctype_char_do_toupper_ch(const ctype_char *this, char ch)
1691 {
1692     TRACE("(%p %c)\n", this, ch);
1693     return _Toupper(ch, &this->ctype);
1694 }
1695
1696 /* ?do_toupper@?$ctype@D@std@@MBEPBDPADPBD@Z */
1697 /* ?do_toupper@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1698 #define call_ctype_char_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 12, \
1699         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1700 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper, 12)
1701 const char* __thiscall ctype_char_do_toupper(const ctype_char *this,
1702         char *first, const char *last)
1703 {
1704     TRACE("(%p %p %p)\n", this, first, last);
1705     for(; first<last; first++)
1706         *first = _Toupper(*first, &this->ctype);
1707     return last;
1708 }
1709
1710 /* ?toupper@?$ctype@D@std@@QBEDD@Z */
1711 /* ?toupper@?$ctype@D@std@@QEBADD@Z */
1712 DEFINE_THISCALL_WRAPPER(ctype_char_toupper_ch, 8)
1713 char __thiscall ctype_char_toupper_ch(const ctype_char *this, char ch)
1714 {
1715     TRACE("(%p %c)\n", this, ch);
1716     return call_ctype_char_do_toupper_ch(this, ch);
1717 }
1718
1719 /* ?toupper@?$ctype@D@std@@QBEPBDPADPBD@Z */
1720 /* ?toupper@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1721 DEFINE_THISCALL_WRAPPER(ctype_char_toupper, 12)
1722 const char* __thiscall ctype_char_toupper(const ctype_char *this, char *first, const char *last)
1723 {
1724     TRACE("(%p %p %p)\n", this, first, last);
1725     return call_ctype_char_do_toupper(this, first, last);
1726 }
1727
1728 /* ?is@?$ctype@D@std@@QBE_NFD@Z */
1729 /* ?is@?$ctype@D@std@@QEBA_NFD@Z */
1730 DEFINE_THISCALL_WRAPPER(ctype_char_is_ch, 12)
1731 MSVCP_bool __thiscall ctype_char_is_ch(const ctype_char *this, short mask, char ch)
1732 {
1733     TRACE("(%p %x %c)\n", this, mask, ch);
1734     return (this->ctype.table[(unsigned char)ch] & mask) != 0;
1735 }
1736
1737 /* ?is@?$ctype@D@std@@QBEPBDPBD0PAF@Z */
1738 /* ?is@?$ctype@D@std@@QEBAPEBDPEBD0PEAF@Z */
1739 DEFINE_THISCALL_WRAPPER(ctype_char_is, 16)
1740 const char* __thiscall ctype_char_is(const ctype_char *this, const char *first, const char *last, short *dest)
1741 {
1742     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1743     for(; first<last; first++)
1744         *dest++ = this->ctype.table[(unsigned char)*first];
1745     return last;
1746 }
1747
1748 /* ?scan_is@?$ctype@D@std@@QBEPBDFPBD0@Z */
1749 /* ?scan_is@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1750 DEFINE_THISCALL_WRAPPER(ctype_char_scan_is, 16)
1751 const char* __thiscall ctype_char_scan_is(const ctype_char *this, short mask, const char *first, const char *last)
1752 {
1753     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1754     for(; first<last; first++)
1755         if(!ctype_char_is_ch(this, mask, *first))
1756             break;
1757     return first;
1758 }
1759
1760 /* ?scan_not@?$ctype@D@std@@QBEPBDFPBD0@Z */
1761 /* ?scan_not@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1762 DEFINE_THISCALL_WRAPPER(ctype_char_scan_not, 16)
1763 const char* __thiscall ctype_char_scan_not(const ctype_char *this, short mask, const char *first, const char *last)
1764 {
1765     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1766     for(; first<last; first++)
1767         if(ctype_char_is_ch(this, mask, *first))
1768             break;
1769     return first;
1770 }
1771
1772 /* ?table@?$ctype@D@std@@IBEPBFXZ */
1773 /* ?table@?$ctype@D@std@@IEBAPEBFXZ */
1774 DEFINE_THISCALL_WRAPPER(ctype_char_table, 4)
1775 const short* __thiscall ctype_char_table(const ctype_char *this)
1776 {
1777     TRACE("(%p)\n", this);
1778     return this->ctype.table;
1779 }
1780
1781 /* ?id@?$ctype@_W@std@@2V0locale@2@A */
1782 locale_id ctype_wchar_id = {0};
1783 /* ?id@?$ctype@G@std@@2V0locale@2@A */
1784 locale_id ctype_short_id = {0};
1785
1786 /* ??_7?$ctype@_W@std@@6B@ */
1787 extern const vtable_ptr MSVCP_ctype_wchar_vtable;
1788 /* ??_7?$ctype@G@std@@6B@ */
1789 extern const vtable_ptr MSVCP_ctype_short_vtable;
1790
1791 /* ?_Id_func@?$ctype@_W@std@@SAAAVid@locale@2@XZ */
1792 /* ?_Id_func@?$ctype@_W@std@@SAAEAVid@locale@2@XZ */
1793 locale_id* __cdecl ctype_wchar__Id_func(void)
1794 {
1795     TRACE("()\n");
1796     return &ctype_wchar_id;
1797 }
1798
1799 /* ?_Id_func@?$ctype@G@std@@SAAAVid@locale@2@XZ */
1800 /* ?_Id_func@?$ctype@G@std@@SAAEAVid@locale@2@XZ */
1801 locale_id* __cdecl ctype_short__Id_func(void)
1802 {
1803     TRACE("()\n");
1804     return &ctype_short_id;
1805 }
1806
1807 /* ?_Init@?$ctype@_W@std@@IAEXABV_Locinfo@2@@Z */
1808 /* ?_Init@?$ctype@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
1809 /* ?_Init@?$ctype@G@std@@IAEXABV_Locinfo@2@@Z */
1810 /* ?_Init@?$ctype@G@std@@IEAAXAEBV_Locinfo@2@@Z */
1811 DEFINE_THISCALL_WRAPPER(ctype_wchar__Init, 8)
1812 void __thiscall ctype_wchar__Init(ctype_wchar *this, const _Locinfo *locinfo)
1813 {
1814     TRACE("(%p %p)\n", this, locinfo);
1815     _Locinfo__Getctype(locinfo, &this->ctype);
1816     _Locinfo__Getcvt(locinfo, &this->cvt);
1817 }
1818
1819 /* ??0?$ctype@_W@std@@QAE@ABV_Locinfo@1@I@Z */
1820 /* ??0?$ctype@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1821 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_locinfo, 12)
1822 ctype_wchar* __thiscall ctype_wchar_ctor_locinfo(ctype_wchar *this,
1823         const _Locinfo *locinfo, MSVCP_size_t refs)
1824 {
1825     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1826     ctype_base_ctor_refs(&this->base, refs);
1827     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1828     ctype_wchar__Init(this, locinfo);
1829     return this;
1830 }
1831
1832 /* ??0?$ctype@G@std@@QAE@ABV_Locinfo@1@I@Z */
1833 /* ??0?$ctype@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1834 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_locinfo, 12)
1835 ctype_wchar* __thiscall ctype_short_ctor_locinfo(ctype_wchar *this,
1836         const _Locinfo *locinfo, MSVCP_size_t refs)
1837 {
1838     ctype_wchar *ret = ctype_wchar_ctor_locinfo(this, locinfo, refs);
1839     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1840     return ret;
1841 }
1842
1843 /* ??0?$ctype@_W@std@@QAE@I@Z */
1844 /* ??0?$ctype@_W@std@@QEAA@_K@Z */
1845 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_refs, 8)
1846 ctype_wchar* __thiscall ctype_wchar_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1847 {
1848     _Locinfo locinfo;
1849
1850     TRACE("(%p %lu)\n", this, refs);
1851
1852     ctype_base_ctor_refs(&this->base, refs);
1853     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1854
1855     _Locinfo_ctor(&locinfo);
1856     ctype_wchar__Init(this, &locinfo);
1857     _Locinfo_dtor(&locinfo);
1858     return this;
1859 }
1860
1861 /* ??0?$ctype@G@std@@QAE@I@Z */
1862 /* ??0?$ctype@G@std@@QEAA@_K@Z */
1863 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_refs, 8)
1864 ctype_wchar* __thiscall ctype_short_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1865 {
1866     ctype_wchar *ret = ctype_wchar_ctor_refs(this, refs);
1867     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1868     return ret;
1869 }
1870
1871 /* ??0?$ctype@G@std@@IAE@PBDI@Z */
1872 /* ??0?$ctype@G@std@@IEAA@PEBD_K@Z */
1873 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_name, 12)
1874 ctype_wchar* __thiscall ctype_short_ctor_name(ctype_wchar *this,
1875     const char *name, MSVCP_size_t refs)
1876 {
1877     _Locinfo locinfo;
1878
1879     TRACE("(%p %s %lu)\n", this, debugstr_a(name), refs);
1880
1881     ctype_base_ctor_refs(&this->base, refs);
1882     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1883
1884     _Locinfo_ctor_cstr(&locinfo, name);
1885     ctype_wchar__Init(this, &locinfo);
1886     _Locinfo_dtor(&locinfo);
1887     return this;
1888 }
1889
1890 /* ??_F?$ctype@_W@std@@QAEXXZ */
1891 /* ??_F?$ctype@_W@std@@QEAAXXZ */
1892 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor, 4)
1893 ctype_wchar* __thiscall ctype_wchar_ctor(ctype_wchar *this)
1894 {
1895     TRACE("(%p)\n", this);
1896     return ctype_short_ctor_refs(this, 0);
1897 }
1898
1899 /* ??_F?$ctype@G@std@@QAEXXZ */
1900 /* ??_F?$ctype@G@std@@QEAAXXZ */
1901 DEFINE_THISCALL_WRAPPER(ctype_short_ctor, 4)
1902 ctype_wchar* __thiscall ctype_short_ctor(ctype_wchar *this)
1903 {
1904     ctype_wchar *ret = ctype_wchar_ctor(this);
1905     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1906     return ret;
1907 }
1908
1909 /* ??1?$ctype@_W@std@@MAE@XZ */
1910 /* ??1?$ctype@_W@std@@MEAA@XZ */
1911 /* ??1?$ctype@G@std@@MAE@XZ */
1912 /* ??1?$ctype@G@std@@MEAA@XZ */
1913 DEFINE_THISCALL_WRAPPER(ctype_wchar_dtor, 4)
1914 void __thiscall ctype_wchar_dtor(ctype_wchar *this)
1915 {
1916     TRACE("(%p)\n", this);
1917     if(this->ctype.delfl)
1918         free((void*)this->ctype.table);
1919 }
1920
1921 DEFINE_THISCALL_WRAPPER(ctype_wchar_vector_dtor, 8)
1922 ctype_wchar* __thiscall ctype_wchar_vector_dtor(ctype_wchar *this, unsigned int flags)
1923 {
1924     TRACE("(%p %x)\n", this, flags);
1925     if(flags & 2) {
1926         /* we have an array, with the number of elements stored before the first object */
1927         INT_PTR i, *ptr = (INT_PTR *)this-1;
1928
1929         for(i=*ptr-1; i>=0; i--)
1930             ctype_wchar_dtor(this+i);
1931         MSVCRT_operator_delete(ptr);
1932     } else {
1933         ctype_wchar_dtor(this);
1934         if(flags & 1)
1935             MSVCRT_operator_delete(this);
1936     }
1937
1938     return this;
1939 }
1940
1941 /* _Wcrtomb */
1942 int __cdecl _Wcrtomb(char *s, wchar_t wch, int *state, const _Cvtvec *cvt)
1943 {
1944     int cp, size;
1945     BOOL def;
1946
1947     TRACE("%p %d %p %p\n", s, wch, state, cvt);
1948
1949     if(cvt)
1950         cp = cvt->page;
1951     else
1952         cp = ___lc_codepage_func();
1953
1954     if(!cp) {
1955         if(wch > 255) {
1956            *_errno() = EILSEQ;
1957            return -1;
1958         }
1959
1960         *s = wch & 255;
1961         return 1;
1962     }
1963
1964     size = WideCharToMultiByte(cp, 0, &wch, 1, s, MB_LEN_MAX, NULL, &def);
1965     if(!size || def) {
1966         *_errno() = EILSEQ;
1967         return -1;
1968     }
1969
1970     return size;
1971 }
1972
1973 /* ?_Donarrow@?$ctype@_W@std@@IBED_WD@Z */
1974 /* ?_Donarrow@?$ctype@_W@std@@IEBAD_WD@Z */
1975 /* ?_Donarrow@?$ctype@G@std@@IBEDGD@Z */
1976 /* ?_Donarrow@?$ctype@G@std@@IEBADGD@Z */
1977 DEFINE_THISCALL_WRAPPER(ctype_wchar__Donarrow, 12)
1978 char __thiscall ctype_wchar__Donarrow(const ctype_wchar *this, wchar_t ch, char dflt)
1979 {
1980     char buf[MB_LEN_MAX];
1981
1982     TRACE("(%p %d %d)\n", this, ch, dflt);
1983
1984     return _Wcrtomb(buf, ch, NULL, &this->cvt)==1 ? buf[0] : dflt;
1985 }
1986
1987 /* ?do_narrow@?$ctype@_W@std@@MBED_WD@Z */
1988 /* ?do_narrow@?$ctype@_W@std@@MEBAD_WD@Z */
1989 /* ?do_narrow@?$ctype@G@std@@MBEDGD@Z */
1990 /* ?do_narrow@?$ctype@G@std@@MEBADGD@Z */
1991 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow_ch, 12)
1992 #define call_ctype_wchar_do_narrow_ch(this, ch, dflt) CALL_VTBL_FUNC(this, 52, \
1993         char, (const ctype_wchar*, wchar_t, char), (this, ch, dflt))
1994 char __thiscall ctype_wchar_do_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
1995 {
1996     return ctype_wchar__Donarrow(this, ch, dflt);
1997 }
1998
1999 /* ?do_narrow@?$ctype@_W@std@@MBEPB_WPB_W0DPAD@Z */
2000 /* ?do_narrow@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD@Z */
2001 /* ?do_narrow@?$ctype@G@std@@MBEPBGPBG0DPAD@Z */
2002 /* ?do_narrow@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD@Z */
2003 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow, 20)
2004 #define call_ctype_wchar_do_narrow(this, first, last, dflt, dest) CALL_VTBL_FUNC(this, 48, \
2005         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*), \
2006         (this, first, last, dflt, dest))
2007 const wchar_t* __thiscall ctype_wchar_do_narrow(const ctype_wchar *this,
2008         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
2009 {
2010     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
2011     for(; first<last; first++)
2012         *dest++ = ctype_wchar__Donarrow(this, *first, dflt);
2013     return last;
2014 }
2015
2016 /* ?_Do_narrow_s@?$ctype@_W@std@@MBEPB_WPB_W0DPADI@Z */
2017 /* ?_Do_narrow_s@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD_K@Z */
2018 /* ?_Do_narrow_s@?$ctype@G@std@@MBEPBGPBG0DPADI@Z */
2019 /* ?_Do_narrow_s@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD_K@Z */
2020 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_narrow_s, 24)
2021 #define call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size) CALL_VTBL_FUNC(this, 56, \
2022         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*, MSVCP_size_t), \
2023         (this, first, last, dflt, dest, size))
2024 const wchar_t* __thiscall ctype_wchar__Do_narrow_s(const ctype_wchar *this,
2025         const wchar_t *first, const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
2026 {
2027     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
2028     /* This function converts all multi-byte characters to dflt,
2029      * thanks to it result size is known before converting */
2030     if(last-first > size)
2031         ctype_base__Xran();
2032     return ctype_wchar_do_narrow(this, first, last, dflt, dest);
2033 }
2034
2035 /* ?narrow@?$ctype@_W@std@@QBED_WD@Z */
2036 /* ?narrow@?$ctype@_W@std@@QEBAD_WD@Z */
2037 /* ?narrow@?$ctype@G@std@@QBEDGD@Z */
2038 /* ?narrow@?$ctype@G@std@@QEBADGD@Z */
2039 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow_ch, 12)
2040 char __thiscall ctype_wchar_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
2041 {
2042     TRACE("(%p %d %d)\n", this, ch, dflt);
2043     return call_ctype_wchar_do_narrow_ch(this, ch, dflt);
2044 }
2045
2046 /* ?narrow@?$ctype@_W@std@@QBEPB_WPB_W0DPAD@Z */
2047 /* ?narrow@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD@Z */
2048 /* ?narrow@?$ctype@G@std@@QBEPBGPBG0DPAD@Z */
2049 /* ?narrow@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD@Z */
2050 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow, 20)
2051 const wchar_t* __thiscall ctype_wchar_narrow(const ctype_wchar *this,
2052         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
2053 {
2054     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
2055     return call_ctype_wchar_do_narrow(this, first, last, dflt, dest);
2056 }
2057
2058 /* ?_Narrow_s@?$ctype@_W@std@@QBEPB_WPB_W0DPADI@Z */
2059 /* ?_Narrow_s@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD_K@Z */
2060 /* ?_Narrow_s@?$ctype@G@std@@QBEPBGPBG0DPADI@Z */
2061 /* ?_Narrow_s@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD_K@Z */
2062 DEFINE_THISCALL_WRAPPER(ctype_wchar__Narrow_s, 24)
2063 const wchar_t* __thiscall ctype_wchar__Narrow_s(const ctype_wchar *this, const wchar_t *first,
2064         const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
2065 {
2066     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
2067     return call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size);
2068 }
2069
2070 /* _Mbrtowc */
2071 int __cdecl _Mbrtowc(wchar_t *out, const char *in, MSVCP_size_t len, int *state, const _Cvtvec *cvt)
2072 {
2073     int i, cp;
2074     CPINFO cp_info;
2075     BOOL is_lead;
2076
2077     TRACE("(%p %p %lu %p %p)\n", out, in, len, state, cvt);
2078
2079     if(!len)
2080         return 0;
2081
2082     if(cvt)
2083         cp = cvt->page;
2084     else
2085         cp = ___lc_codepage_func();
2086
2087     if(!cp) {
2088         if(out)
2089             *out = (unsigned char)*in;
2090
2091         *state = 0;
2092         return *in ? 1 : 0;
2093     }
2094
2095     if(*state) {
2096         ((char*)state)[1] = *in;
2097
2098         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, (char*)state, 2, out, out ? 1 : 0)) {
2099             *state = 0;
2100             *_errno() = EILSEQ;
2101             return -1;
2102         }
2103
2104         *state = 0;
2105         return 2;
2106     }
2107
2108     GetCPInfo(cp, &cp_info);
2109     is_lead = FALSE;
2110     for(i=0; i<MAX_LEADBYTES; i+=2) {
2111         if(!cp_info.LeadByte[i+1])
2112             break;
2113         if((unsigned char)*in>=cp_info.LeadByte[i] && (unsigned char)*in<=cp_info.LeadByte[i+1]) {
2114             is_lead = TRUE;
2115             break;
2116         }
2117     }
2118
2119     if(is_lead) {
2120         if(len == 1) {
2121             *state = (unsigned char)*in;
2122             return -2;
2123         }
2124
2125         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 2, out, out ? 1 : 0)) {
2126             *_errno() = EILSEQ;
2127             return -1;
2128         }
2129         return 2;
2130     }
2131
2132     if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 1, out, out ? 1 : 0)) {
2133         *_errno() = EILSEQ;
2134         return -1;
2135     }
2136     return 1;
2137 }
2138
2139 /* ?_Dowiden@?$ctype@_W@std@@IBE_WD@Z */
2140 /* ?_Dowiden@?$ctype@_W@std@@IEBA_WD@Z */
2141 /* ?_Dowiden@?$ctype@G@std@@IBEGD@Z */
2142 /* ?_Dowiden@?$ctype@G@std@@IEBAGD@Z */
2143 DEFINE_THISCALL_WRAPPER(ctype_wchar__Dowiden, 8)
2144 wchar_t __thiscall ctype_wchar__Dowiden(const ctype_wchar *this, char ch)
2145 {
2146     wchar_t ret;
2147     int state = 0;
2148     TRACE("(%p %d)\n", this, ch);
2149     return _Mbrtowc(&ret, &ch, 1, &state, &this->cvt)<0 ? WEOF : ret;
2150 }
2151
2152 /* ?do_widen@?$ctype@_W@std@@MBE_WD@Z */
2153 /* ?do_widen@?$ctype@_W@std@@MEBA_WD@Z */
2154 /* ?do_widen@?$ctype@G@std@@MBEGD@Z */
2155 /* ?do_widen@?$ctype@G@std@@MEBAGD@Z */
2156 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen_ch, 8)
2157 #define call_ctype_wchar_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 40, \
2158         wchar_t, (const ctype_wchar*, char), (this, ch))
2159 wchar_t __thiscall ctype_wchar_do_widen_ch(const ctype_wchar *this, char ch)
2160 {
2161     return ctype_wchar__Dowiden(this, ch);
2162 }
2163
2164 /* ?do_widen@?$ctype@_W@std@@MBEPBDPBD0PA_W@Z */
2165 /* ?do_widen@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W@Z */
2166 /* ?do_widen@?$ctype@G@std@@MBEPBDPBD0PAG@Z */
2167 /* ?do_widen@?$ctype@G@std@@MEBAPEBDPEBD0PEAG@Z */
2168 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen, 16)
2169 #define call_ctype_wchar_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 36, \
2170         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*), \
2171         (this, first, last, dest))
2172 const char* __thiscall ctype_wchar_do_widen(const ctype_wchar *this,
2173         const char *first, const char *last, wchar_t *dest)
2174 {
2175     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2176     for(; first<last; first++)
2177         *dest++ = ctype_wchar__Dowiden(this, *first);
2178     return last;
2179 }
2180
2181 /* ?_Do_widen_s@?$ctype@_W@std@@MBEPBDPBD0PA_WI@Z */
2182 /* ?_Do_widen_s@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W_K@Z */
2183 /* ?_Do_widen_s@?$ctype@G@std@@MBEPBDPBD0PAGI@Z */
2184 /* ?_Do_widen_s@?$ctype@G@std@@MEBAPEBDPEBD0PEAG_K@Z */
2185 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_widen_s, 20)
2186 #define call_ctype_wchar__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 44, \
2187         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*, MSVCP_size_t), \
2188         (this, first, last, dest, size))
2189 const char* __thiscall ctype_wchar__Do_widen_s(const ctype_wchar *this,
2190         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2191 {
2192     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2193     /* This function converts all multi-byte characters to WEOF,
2194      * thanks to it result size is known before converting */
2195     if(size < last-first)
2196         ctype_base__Xran();
2197     return ctype_wchar_do_widen(this, first, last, dest);
2198 }
2199
2200 /* ?widen@?$ctype@_W@std@@QBE_WD@Z */
2201 /* ?widen@?$ctype@_W@std@@QEBA_WD@Z */
2202 /* ?widen@?$ctype@G@std@@QBEGD@Z */
2203 /* ?widen@?$ctype@G@std@@QEBAGD@Z */
2204 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen_ch, 8)
2205 wchar_t __thiscall ctype_wchar_widen_ch(const ctype_wchar *this, char ch)
2206 {
2207     TRACE("(%p %d)\n", this, ch);
2208     return call_ctype_wchar_do_widen_ch(this, ch);
2209 }
2210
2211 /* ?widen@?$ctype@_W@std@@QBEPBDPBD0PA_W@Z */
2212 /* ?widen@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W@Z */
2213 /* ?widen@?$ctype@G@std@@QBEPBDPBD0PAG@Z */
2214 /* ?widen@?$ctype@G@std@@QEBAPEBDPEBD0PEAG@Z */
2215 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen, 16)
2216 const char* __thiscall ctype_wchar_widen(const ctype_wchar *this,
2217         const char *first, const char *last, wchar_t *dest)
2218 {
2219     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2220     return call_ctype_wchar_do_widen(this, first, last, dest);
2221 }
2222
2223 /* ?_Widen_s@?$ctype@_W@std@@QBEPBDPBD0PA_WI@Z */
2224 /* ?_Widen_s@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W_K@Z */
2225 /* ?_Widen_s@?$ctype@G@std@@QBEPBDPBD0PAGI@Z */
2226 /* ?_Widen_s@?$ctype@G@std@@QEBAPEBDPEBD0PEAG_K@Z */
2227 DEFINE_THISCALL_WRAPPER(ctype_wchar__Widen_s, 20)
2228 const char* __thiscall ctype_wchar__Widen_s(const ctype_wchar *this,
2229         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2230 {
2231     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2232     return call_ctype_wchar__Do_widen_s(this, first, last, dest, size);
2233 }
2234
2235 /* ?_Getcat@?$ctype@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2236 /* ?_Getcat@?$ctype@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2237 MSVCP_size_t __cdecl ctype_wchar__Getcat(const locale_facet **facet, const locale *loc)
2238 {
2239     TRACE("(%p %p)\n", facet, loc);
2240
2241     if(facet && !*facet) {
2242         _Locinfo locinfo;
2243
2244         *facet = MSVCRT_operator_new(sizeof(ctype_wchar));
2245         if(!*facet) {
2246             ERR("Out of memory\n");
2247             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2248             return 0;
2249         }
2250
2251         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
2252         ctype_wchar_ctor_locinfo((ctype_wchar*)*facet, &locinfo, 0);
2253         _Locinfo_dtor(&locinfo);
2254     }
2255
2256     return LC_CTYPE;
2257 }
2258
2259 /* ?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2260 /* ?_Getcat@?$ctype@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2261 MSVCP_size_t __cdecl ctype_short__Getcat(const locale_facet **facet, const locale *loc)
2262 {
2263     if(facet && !*facet) {
2264         ctype_wchar__Getcat(facet, loc);
2265         (*(locale_facet**)facet)->vtable = &MSVCP_ctype_short_vtable;
2266     }
2267
2268     return LC_CTYPE;
2269 }
2270
2271 /* _Towlower */
2272 wchar_t __cdecl _Towlower(wchar_t ch, const _Ctypevec *ctype)
2273 {
2274     TRACE("(%d %p)\n", ch, ctype);
2275     return tolowerW(ch);
2276 }
2277
2278 ctype_wchar* ctype_wchar_use_facet(const locale *loc)
2279 {
2280     static ctype_wchar *obj = NULL;
2281
2282     _Lockit lock;
2283     const locale_facet *fac;
2284
2285     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2286     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_wchar_id));
2287     if(fac) {
2288         _Lockit_dtor(&lock);
2289         return (ctype_wchar*)fac;
2290     }
2291
2292     if(obj) {
2293         _Lockit_dtor(&lock);
2294         return obj;
2295     }
2296
2297     ctype_wchar__Getcat(&fac, loc);
2298     obj = (ctype_wchar*)fac;
2299     locale_facet__Incref(&obj->base.facet);
2300     locale_facet_register(&obj->base.facet);
2301     _Lockit_dtor(&lock);
2302
2303     return obj;
2304 }
2305
2306 ctype_wchar* ctype_short_use_facet(const locale *loc)
2307 {
2308     static ctype_wchar *obj = NULL;
2309
2310     _Lockit lock;
2311     const locale_facet *fac;
2312
2313     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2314     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_short_id));
2315     if(fac) {
2316         _Lockit_dtor(&lock);
2317         return (ctype_wchar*)fac;
2318     }
2319
2320     if(obj) {
2321         _Lockit_dtor(&lock);
2322         return obj;
2323     }
2324
2325     ctype_short__Getcat(&fac, loc);
2326     obj = (ctype_wchar*)fac;
2327     locale_facet__Incref(&obj->base.facet);
2328     locale_facet_register(&obj->base.facet);
2329     _Lockit_dtor(&lock);
2330
2331     return obj;
2332 }
2333
2334 /* ?do_tolower@?$ctype@_W@std@@MBE_W_W@Z */
2335 /* ?do_tolower@?$ctype@_W@std@@MEBA_W_W@Z */
2336 /* ?do_tolower@?$ctype@G@std@@MBEGG@Z */
2337 /* ?do_tolower@?$ctype@G@std@@MEBAGG@Z */
2338 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower_ch, 8)
2339 #define call_ctype_wchar_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
2340         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2341 wchar_t __thiscall ctype_wchar_do_tolower_ch(const ctype_wchar *this, wchar_t ch)
2342 {
2343     return _Towlower(ch, &this->ctype);
2344 }
2345
2346 /* ?do_tolower@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2347 /* ?do_tolower@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2348 /* ?do_tolower@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2349 /* ?do_tolower@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2350 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower, 12)
2351 #define call_ctype_wchar_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 20, \
2352         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2353         (this, first, last))
2354 const wchar_t* __thiscall ctype_wchar_do_tolower(const ctype_wchar *this,
2355         wchar_t *first, const wchar_t *last)
2356 {
2357     TRACE("(%p %p %p)\n", this, first, last);
2358     for(; first<last; first++)
2359         *first = _Towlower(*first, &this->ctype);
2360     return last;
2361 }
2362
2363 /* ?tolower@?$ctype@_W@std@@QBE_W_W@Z */
2364 /* ?tolower@?$ctype@_W@std@@QEBA_W_W@Z */
2365 /* ?tolower@?$ctype@G@std@@QBEGG@Z */
2366 /* ?tolower@?$ctype@G@std@@QEBAGG@Z */
2367 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower_ch, 8)
2368 wchar_t __thiscall ctype_wchar_tolower_ch(const ctype_wchar *this, wchar_t ch)
2369 {
2370     TRACE("(%p %d)\n", this, ch);
2371     return call_ctype_wchar_do_tolower_ch(this, ch);
2372 }
2373
2374 /* ?tolower@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2375 /* ?tolower@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2376 /* ?tolower@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2377 /* ?tolower@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2378 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower, 12)
2379 const wchar_t* __thiscall ctype_wchar_tolower(const ctype_wchar *this,
2380         wchar_t *first, const wchar_t *last)
2381 {
2382     TRACE("(%p %p %p)\n", this, first, last);
2383     return call_ctype_wchar_do_tolower(this, first, last);
2384 }
2385
2386 /* _Towupper */
2387 wchar_t __cdecl _Towupper(wchar_t ch, const _Ctypevec *ctype)
2388 {
2389     TRACE("(%d %p)\n", ch, ctype);
2390     return toupperW(ch);
2391 }
2392
2393 /* ?do_toupper@?$ctype@_W@std@@MBE_W_W@Z */
2394 /* ?do_toupper@?$ctype@_W@std@@MEBA_W_W@Z */
2395 /* ?do_toupper@?$ctype@G@std@@MBEGG@Z */
2396 /* ?do_toupper@?$ctype@G@std@@MEBAGG@Z */
2397 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper_ch, 8)
2398 #define call_ctype_wchar_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 32, \
2399         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2400 wchar_t __thiscall ctype_wchar_do_toupper_ch(const ctype_wchar *this, wchar_t ch)
2401 {
2402     return _Towupper(ch, &this->ctype);
2403 }
2404
2405 /* ?do_toupper@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2406 /* ?do_toupper@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2407 /* ?do_toupper@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2408 /* ?do_toupper@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2409 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper, 12)
2410 #define call_ctype_wchar_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 28, \
2411         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2412         (this, first, last))
2413 const wchar_t* __thiscall ctype_wchar_do_toupper(const ctype_wchar *this,
2414         wchar_t *first, const wchar_t *last)
2415 {
2416     TRACE("(%p %p %p)\n", this, first, last);
2417     for(; first<last; first++)
2418         *first = _Towupper(*first, &this->ctype);
2419     return last;
2420 }
2421
2422 /* ?toupper@?$ctype@_W@std@@QBE_W_W@Z */
2423 /* ?toupper@?$ctype@_W@std@@QEBA_W_W@Z */
2424 /* ?toupper@?$ctype@G@std@@QBEGG@Z */
2425 /* ?toupper@?$ctype@G@std@@QEBAGG@Z */
2426 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper_ch, 8)
2427 wchar_t __thiscall ctype_wchar_toupper_ch(const ctype_wchar *this, wchar_t ch)
2428 {
2429     TRACE("(%p %d)\n", this, ch);
2430     return call_ctype_wchar_do_toupper_ch(this, ch);
2431 }
2432
2433 /* ?toupper@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2434 /* ?toupper@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2435 /* ?toupper@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2436 /* ?toupper@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2437 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper, 12)
2438 const wchar_t* __thiscall ctype_wchar_toupper(const ctype_wchar *this,
2439         wchar_t *first, const wchar_t *last)
2440 {
2441     TRACE("(%p %p %p)\n", this, first, last);
2442     return call_ctype_wchar_do_toupper(this, first, last);
2443 }
2444
2445 /* _Getwctypes */
2446 const wchar_t* __cdecl _Getwctypes(const wchar_t *first, const wchar_t *last,
2447         short *mask, const _Ctypevec *ctype)
2448 {
2449     TRACE("(%p %p %p %p)\n", first, last, mask, ctype);
2450     GetStringTypeW(CT_CTYPE1, first, last-first, (WORD*)mask);
2451     return last;
2452 }
2453
2454 /* _Getwctype */
2455 short __cdecl _Getwctype(wchar_t ch, const _Ctypevec *ctype)
2456 {
2457     short mask = 0;
2458     _Getwctypes(&ch, &ch+1, &mask, ctype);
2459     return mask;
2460 }
2461
2462 /* ?do_is@?$ctype@_W@std@@MBE_NF_W@Z */
2463 /* ?do_is@?$ctype@_W@std@@MEBA_NF_W@Z */
2464 /* ?do_is@?$ctype@G@std@@MBE_NFG@Z */
2465 /* ?do_is@?$ctype@G@std@@MEBA_NFG@Z */
2466 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is_ch, 12)
2467 #define call_ctype_wchar_do_is_ch(this, mask, ch) CALL_VTBL_FUNC(this, 8, \
2468         MSVCP_bool, (const ctype_wchar*, short, wchar_t), (this, mask, ch))
2469 MSVCP_bool __thiscall ctype_wchar_do_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2470 {
2471     TRACE("(%p %x %d)\n", this, mask, ch);
2472     return (_Getwctype(ch, &this->ctype) & mask) != 0;
2473 }
2474
2475 /* ?do_is@?$ctype@_W@std@@MBEPB_WPB_W0PAF@Z */
2476 /* ?do_is@?$ctype@_W@std@@MEBAPEB_WPEB_W0PEAF@Z */
2477 /* ?do_is@?$ctype@G@std@@MBEPBGPBG0PAF@Z */
2478 /* ?do_is@?$ctype@G@std@@MEBAPEBGPEBG0PEAF@Z */
2479 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is, 16)
2480 #define call_ctype_wchar_do_is(this, first, last, dest) CALL_VTBL_FUNC(this, 4, \
2481         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, short*), \
2482         (this, first, last, dest))
2483 const wchar_t* __thiscall ctype_wchar_do_is(const ctype_wchar *this,
2484         const wchar_t *first, const wchar_t *last, short *dest)
2485 {
2486     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2487     return _Getwctypes(first, last, dest, &this->ctype);
2488 }
2489
2490 /* ?is@?$ctype@_W@std@@QBE_NF_W@Z */
2491 /* ?is@?$ctype@_W@std@@QEBA_NF_W@Z */
2492 /* ?is@?$ctype@G@std@@QBE_NFG@Z */
2493 /* ?is@?$ctype@G@std@@QEBA_NFG@Z */
2494 DEFINE_THISCALL_WRAPPER(ctype_wchar_is_ch, 12)
2495 MSVCP_bool __thiscall ctype_wchar_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2496 {
2497     TRACE("(%p %x %d)\n", this, mask, ch);
2498     return call_ctype_wchar_do_is_ch(this, mask, ch);
2499 }
2500
2501 /* ?is@?$ctype@_W@std@@QBEPB_WPB_W0PAF@Z */
2502 /* ?is@?$ctype@_W@std@@QEBAPEB_WPEB_W0PEAF@Z */
2503 /* ?is@?$ctype@G@std@@QBEPBGPBG0PAF@Z */
2504 /* ?is@?$ctype@G@std@@QEBAPEBGPEBG0PEAF@Z */
2505 DEFINE_THISCALL_WRAPPER(ctype_wchar_is, 16)
2506 const wchar_t* __thiscall ctype_wchar_is(const ctype_wchar *this,
2507         const wchar_t *first, const wchar_t *last, short *dest)
2508 {
2509     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2510     return call_ctype_wchar_do_is(this, first, last, dest);
2511 }
2512
2513 /* ?do_scan_is@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2514 /* ?do_scan_is@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2515 /* ?do_scan_is@?$ctype@G@std@@MBEPBGFPBG0@Z */
2516 /* ?do_scan_is@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2517 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_is, 16)
2518 #define call_ctype_wchar_do_scan_is(this, mask, first, last) CALL_VTBL_FUNC(this, 12, \
2519         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2520         (this, mask, first, last))
2521 const wchar_t* __thiscall ctype_wchar_do_scan_is(const ctype_wchar *this,
2522         short mask, const wchar_t *first, const wchar_t *last)
2523 {
2524     TRACE("(%p %d %p %p)\n", this, mask, first, last);
2525     for(; first<last; first++)
2526         if(!ctype_wchar_is_ch(this, mask, *first))
2527             break;
2528     return first;
2529 }
2530
2531 /* ?scan_is@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2532 /* ?scan_is@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2533 /* ?scan_is@?$ctype@G@std@@QBEPBGFPBG0@Z */
2534 /* ?scan_is@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2535 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_is, 16)
2536 const wchar_t* __thiscall ctype_wchar_scan_is(const ctype_wchar *this,
2537         short mask, const wchar_t *first, const wchar_t *last)
2538 {
2539     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2540     return call_ctype_wchar_do_scan_is(this, mask, first, last);
2541 }
2542
2543 /* ?do_scan_not@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2544 /* ?do_scan_not@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2545 /* ?do_scan_not@?$ctype@G@std@@MBEPBGFPBG0@Z */
2546 /* ?do_scan_not@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2547 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_not, 16)
2548 #define call_ctype_wchar_do_scan_not(this, mask, first, last) CALL_VTBL_FUNC(this, 16, \
2549         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2550         (this, mask, first, last))
2551 const wchar_t* __thiscall ctype_wchar_do_scan_not(const ctype_wchar *this,
2552         short mask, const wchar_t *first, const wchar_t *last)
2553 {
2554     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2555     for(; first<last; first++)
2556         if(ctype_wchar_is_ch(this, mask, *first))
2557             break;
2558     return first;
2559 }
2560
2561 /* ?scan_not@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2562 /* ?scan_not@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2563 /* ?scan_not@?$ctype@G@std@@QBEPBGFPBG0@Z */
2564 /* ?scan_not@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2565 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_not, 16)
2566 const wchar_t* __thiscall ctype_wchar_scan_not(const ctype_wchar *this,
2567         short mask, const wchar_t *first, const wchar_t *last)
2568 {
2569     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2570     return call_ctype_wchar_do_scan_not(this, mask, first, last);
2571 }
2572
2573 /* ??_7codecvt_base@std@@6B@ */
2574 extern const vtable_ptr MSVCP_codecvt_base_vtable;
2575
2576 /* ??0codecvt_base@std@@QAE@I@Z */
2577 /* ??0codecvt_base@std@@QEAA@_K@Z */
2578 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor_refs, 8)
2579 codecvt_base* __thiscall codecvt_base_ctor_refs(codecvt_base *this, MSVCP_size_t refs)
2580 {
2581     TRACE("(%p %lu)\n", this, refs);
2582     locale_facet_ctor_refs(&this->facet, refs);
2583     this->facet.vtable = &MSVCP_codecvt_base_vtable;
2584     return this;
2585 }
2586
2587 /* ??_Fcodecvt_base@std@@QAEXXZ */
2588 /* ??_Fcodecvt_base@std@@QEAAXXZ */
2589 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor, 4)
2590 codecvt_base* __thiscall codecvt_base_ctor(codecvt_base *this)
2591 {
2592     return codecvt_base_ctor_refs(this, 0);
2593 }
2594
2595 /* ??1codecvt_base@std@@UAE@XZ */
2596 /* ??1codecvt_base@std@@UEAA@XZ */
2597 DEFINE_THISCALL_WRAPPER(codecvt_base_dtor, 4)
2598 void __thiscall codecvt_base_dtor(codecvt_base *this)
2599 {
2600     TRACE("(%p)\n", this);
2601     locale_facet_dtor(&this->facet);
2602 }
2603
2604 DEFINE_THISCALL_WRAPPER(codecvt_base_vector_dtor, 8)
2605 codecvt_base* __thiscall codecvt_base_vector_dtor(codecvt_base *this, unsigned int flags)
2606 {
2607     TRACE("(%p %x)\n", this, flags);
2608     if(flags & 2) {
2609         /* we have an array, with the number of elements stored before the first object */
2610         INT_PTR i, *ptr = (INT_PTR *)this-1;
2611
2612         for(i=*ptr-1; i>=0; i--)
2613             codecvt_base_dtor(this+i);
2614         MSVCRT_operator_delete(ptr);
2615     } else {
2616         codecvt_base_dtor(this);
2617         if(flags & 1)
2618             MSVCRT_operator_delete(this);
2619     }
2620
2621     return this;
2622 }
2623
2624 /* ?do_always_noconv@codecvt_base@std@@MBE_NXZ */
2625 /* ?do_always_noconv@codecvt_base@std@@MEBA_NXZ */
2626 #define call_codecvt_base_do_always_noconv(this) CALL_VTBL_FUNC(this, 4, \
2627         MSVCP_bool, (const codecvt_base*), (this))
2628 DEFINE_THISCALL_WRAPPER(codecvt_base_do_always_noconv, 4)
2629 MSVCP_bool __thiscall codecvt_base_do_always_noconv(const codecvt_base *this)
2630 {
2631     TRACE("(%p)\n", this);
2632     return TRUE;
2633 }
2634
2635 /* ?always_noconv@codecvt_base@std@@QBE_NXZ */
2636 /* ?always_noconv@codecvt_base@std@@QEBA_NXZ */
2637 DEFINE_THISCALL_WRAPPER(codecvt_base_always_noconv, 4)
2638 MSVCP_bool __thiscall codecvt_base_always_noconv(const codecvt_base *this)
2639 {
2640     TRACE("(%p)\n", this);
2641     return call_codecvt_base_do_always_noconv(this);
2642 }
2643
2644 /* ?do_max_length@codecvt_base@std@@MBEHXZ */
2645 /* ?do_max_length@codecvt_base@std@@MEBAHXZ */
2646 #define call_codecvt_base_do_max_length(this) CALL_VTBL_FUNC(this, 8, \
2647         int, (const codecvt_base*), (this))
2648 DEFINE_THISCALL_WRAPPER(codecvt_base_do_max_length, 4)
2649 int __thiscall codecvt_base_do_max_length(const codecvt_base *this)
2650 {
2651     TRACE("(%p)\n", this);
2652     return 1;
2653 }
2654
2655 /* ?max_length@codecvt_base@std@@QBEHXZ */
2656 /* ?max_length@codecvt_base@std@@QEBAHXZ */
2657 DEFINE_THISCALL_WRAPPER(codecvt_base_max_length, 4)
2658 int __thiscall codecvt_base_max_length(const codecvt_base *this)
2659 {
2660     TRACE("(%p)\n", this);
2661     return call_codecvt_base_do_max_length(this);
2662 }
2663
2664 /* ?do_encoding@codecvt_base@std@@MBEHXZ */
2665 /* ?do_encoding@codecvt_base@std@@MEBAHXZ */
2666 #define call_codecvt_base_do_encoding(this) CALL_VTBL_FUNC(this, 12, \
2667         int, (const codecvt_base*), (this))
2668 DEFINE_THISCALL_WRAPPER(codecvt_base_do_encoding, 4)
2669 int __thiscall codecvt_base_do_encoding(const codecvt_base *this)
2670 {
2671     TRACE("(%p)\n", this);
2672     return 1;
2673 }
2674
2675 /* ?encoding@codecvt_base@std@@QBEHXZ */
2676 /* ?encoding@codecvt_base@std@@QEBAHXZ */
2677 DEFINE_THISCALL_WRAPPER(codecvt_base_encoding, 4)
2678 int __thiscall codecvt_base_encoding(const codecvt_base *this)
2679 {
2680     TRACE("(%p)\n", this);
2681     return call_codecvt_base_do_encoding(this);
2682 }
2683
2684 /* ?id@?$codecvt@DDH@std@@2V0locale@2@A */
2685 locale_id codecvt_char_id = {0};
2686
2687 /* ??_7?$codecvt@DDH@std@@6B@ */
2688 extern const vtable_ptr MSVCP_codecvt_char_vtable;
2689
2690 /* ?_Init@?$codecvt@DDH@std@@IAEXABV_Locinfo@2@@Z */
2691 /* ?_Init@?$codecvt@DDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2692 DEFINE_THISCALL_WRAPPER(codecvt_char__Init, 8)
2693 void __thiscall codecvt_char__Init(codecvt_char *this, const _Locinfo *locinfo)
2694 {
2695     TRACE("(%p %p)\n", this, locinfo);
2696 }
2697
2698 /* ??0?$codecvt@DDH@std@@QAE@ABV_Locinfo@1@I@Z */
2699 /* ??0?$codecvt@DDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2700 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_locinfo, 12)
2701 codecvt_char* __thiscall codecvt_char_ctor_locinfo(codecvt_char *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2702 {
2703     TRACE("(%p %p %lu)\n", this, locinfo, refs);
2704     codecvt_base_ctor_refs(&this->base, refs);
2705     this->base.facet.vtable = &MSVCP_codecvt_char_vtable;
2706     return this;
2707 }
2708
2709 /* ??0?$codecvt@DDH@std@@QAE@I@Z */
2710 /* ??0?$codecvt@DDH@std@@QEAA@_K@Z */
2711 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_refs, 8)
2712 codecvt_char* __thiscall codecvt_char_ctor_refs(codecvt_char *this, MSVCP_size_t refs)
2713 {
2714     return codecvt_char_ctor_locinfo(this, NULL, refs);
2715 }
2716
2717 /* ??_F?$codecvt@DDH@std@@QAEXXZ */
2718 /* ??_F?$codecvt@DDH@std@@QEAAXXZ */
2719 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor, 4)
2720 codecvt_char* __thiscall codecvt_char_ctor(codecvt_char *this)
2721 {
2722     return codecvt_char_ctor_locinfo(this, NULL, 0);
2723 }
2724
2725 /* ??1?$codecvt@DDH@std@@MAE@XZ */
2726 /* ??1?$codecvt@DDH@std@@MEAA@XZ */
2727 DEFINE_THISCALL_WRAPPER(codecvt_char_dtor, 4)
2728 void __thiscall codecvt_char_dtor(codecvt_char *this)
2729 {
2730     TRACE("(%p)\n", this);
2731     codecvt_base_dtor(&this->base);
2732 }
2733
2734 DEFINE_THISCALL_WRAPPER(codecvt_char_vector_dtor, 8)
2735 codecvt_char* __thiscall codecvt_char_vector_dtor(codecvt_char *this, unsigned int flags)
2736 {
2737     TRACE("(%p %x)\n", this, flags);
2738     if(flags & 2) {
2739         /* we have an array, with the number of elements stored before the first object */
2740         INT_PTR i, *ptr = (INT_PTR *)this-1;
2741
2742         for(i=*ptr-1; i>=0; i--)
2743             codecvt_char_dtor(this+i);
2744         MSVCRT_operator_delete(ptr);
2745     } else {
2746         codecvt_char_dtor(this);
2747         if(flags & 1)
2748             MSVCRT_operator_delete(this);
2749     }
2750
2751     return this;
2752 }
2753
2754 /* ?_Getcat@?$codecvt@DDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2755 /* ?_Getcat@?$codecvt@DDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2756 MSVCP_size_t __cdecl codecvt_char__Getcat(const locale_facet **facet, const locale *loc)
2757 {
2758     TRACE("(%p %p)\n", facet, loc);
2759
2760     if(facet && !*facet) {
2761         *facet = MSVCRT_operator_new(sizeof(codecvt_char));
2762         if(!*facet) {
2763             ERR("Out of memory\n");
2764             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2765             return 0;
2766         }
2767         codecvt_char_ctor((codecvt_char*)*facet);
2768     }
2769
2770     return LC_CTYPE;
2771 }
2772
2773 codecvt_char* codecvt_char_use_facet(const locale *loc)
2774 {
2775     static codecvt_char *obj = NULL;
2776
2777     _Lockit lock;
2778     const locale_facet *fac;
2779
2780     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2781     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_char_id));
2782     if(fac) {
2783         _Lockit_dtor(&lock);
2784         return (codecvt_char*)fac;
2785     }
2786
2787     if(obj) {
2788         _Lockit_dtor(&lock);
2789         return obj;
2790     }
2791
2792     codecvt_char__Getcat(&fac, loc);
2793     obj = (codecvt_char*)fac;
2794     locale_facet__Incref(&obj->base.facet);
2795     locale_facet_register(&obj->base.facet);
2796     _Lockit_dtor(&lock);
2797
2798     return obj;
2799 }
2800
2801 /* ?do_in@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2802 /* ?do_in@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2803 #define call_codecvt_char_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
2804     CALL_VTBL_FUNC(this, 16, int, \
2805             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2806             (this, state, from, from_end, from_next, to, to_end, to_next))
2807 DEFINE_THISCALL_WRAPPER(codecvt_char_do_in, 32)
2808 int __thiscall codecvt_char_do_in(const codecvt_char *this, int *state,
2809         const char *from, const char *from_end, const char **from_next,
2810         char *to, char *to_end, char **to_next)
2811 {
2812     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2813             from_next, to, to_end, to_next);
2814     *from_next = from;
2815     *to_next = to;
2816     return CODECVT_noconv;
2817 }
2818
2819 /* ?in@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2820 /* ?in@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2821 DEFINE_THISCALL_WRAPPER(codecvt_char_in, 32)
2822 int __thiscall codecvt_char_in(const codecvt_char *this, int *state,
2823         const char *from, const char *from_end, const char **from_next,
2824         char *to, char *to_end, char **to_next)
2825 {
2826     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2827             from_next, to, to_end, to_next);
2828     return call_codecvt_char_do_in(this, state, from, from_end, from_next,
2829             to, to_end, to_next);
2830 }
2831
2832 /* ?do_out@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2833 /* ?do_out@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2834 #define call_codecvt_char_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
2835     CALL_VTBL_FUNC(this, 20, int, \
2836             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2837             (this, state, from, from_end, from_next, to, to_end, to_next))
2838 DEFINE_THISCALL_WRAPPER(codecvt_char_do_out, 32)
2839 int __thiscall codecvt_char_do_out(const codecvt_char *this, int *state,
2840         const char *from, const char *from_end, const char **from_next,
2841         char *to, char *to_end, char **to_next)
2842 {
2843     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2844             from_end, from_next, to, to_end, to_next);
2845     *from_next = from;
2846     *to_next = to;
2847     return CODECVT_noconv;
2848 }
2849
2850 /* ?out@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2851 /* ?out@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2852 DEFINE_THISCALL_WRAPPER(codecvt_char_out, 32)
2853 int __thiscall codecvt_char_out(const codecvt_char *this, int *state,
2854         const char *from, const char *from_end, const char **from_next,
2855         char *to, char *to_end, char **to_next)
2856 {
2857     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2858             from_next, to, to_end, to_next);
2859     return call_codecvt_char_do_out(this, state, from, from_end, from_next,
2860             to, to_end, to_next);
2861 }
2862
2863 /* ?do_unshift@?$codecvt@DDH@std@@MBEHAAHPAD1AAPAD@Z */
2864 /* ?do_unshift@?$codecvt@DDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
2865 #define call_codecvt_char_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
2866         int, (const codecvt_char*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
2867 DEFINE_THISCALL_WRAPPER(codecvt_char_do_unshift, 20)
2868 int __thiscall codecvt_char_do_unshift(const codecvt_char *this,
2869         int *state, char *to, char *to_end, char **to_next)
2870 {
2871     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2872     *to_next = to;
2873     return CODECVT_noconv;
2874 }
2875
2876 /* ?unshift@?$codecvt@DDH@std@@QBEHAAHPAD1AAPAD@Z */
2877 /* ?unshift@?$codecvt@DDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
2878 DEFINE_THISCALL_WRAPPER(codecvt_char_unshift, 20)
2879 int __thiscall codecvt_char_unshift(const codecvt_char *this,
2880         int *state, char *to, char *to_end, char **to_next)
2881 {
2882     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2883     return call_codecvt_char_do_unshift(this, state, to, to_end, to_next);
2884 }
2885
2886 /* ?do_length@?$codecvt@DDH@std@@MBEHABHPBD1I@Z */
2887 /* ?do_length@?$codecvt@DDH@std@@MEBAHAEBHPEBD1_K@Z */
2888 #define call_codecvt_char_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
2889         int, (const codecvt_char*, const int*, const char*, const char*, MSVCP_size_t), \
2890         (this, state, from, from_end, max))
2891 DEFINE_THISCALL_WRAPPER(codecvt_char_do_length, 20)
2892 int __thiscall codecvt_char_do_length(const codecvt_char *this, const int *state,
2893         const char *from, const char *from_end, MSVCP_size_t max)
2894 {
2895     TRACE("(%p %p %p %p %lu)\n", this, state, from, from_end, max);
2896     return (from_end-from > max ? max : from_end-from);
2897 }
2898
2899 /* ?length@?$codecvt@DDH@std@@QBEHABHPBD1I@Z */
2900 /* ?length@?$codecvt@DDH@std@@QEBAHAEBHPEBD1_K@Z */
2901 DEFINE_THISCALL_WRAPPER(codecvt_char_length, 20)
2902 int __thiscall codecvt_char_length(const codecvt_char *this, const int *state,
2903         const char *from, const char *from_end, MSVCP_size_t max)
2904 {
2905     TRACE("(%p %p %p %p %lu)\n", this, state, from, from_end, max);
2906     return call_codecvt_char_do_length(this, state, from, from_end, max);
2907 }
2908
2909 /* ?id@?$codecvt@_WDH@std@@2V0locale@2@A */
2910 locale_id codecvt_wchar_id = {0};
2911 /* ?id@?$codecvt@GDH@std@@2V0locale@2@A */
2912 locale_id codecvt_short_id = {0};
2913
2914 /* ??_7?$codecvt@_WDH@std@@6B@ */
2915 extern const vtable_ptr MSVCP_codecvt_wchar_vtable;
2916 /* ??_7?$codecvt@GDH@std@@6B@ */
2917 extern const vtable_ptr MSVCP_codecvt_short_vtable;
2918
2919 /* ?_Init@?$codecvt@GDH@std@@IAEXABV_Locinfo@2@@Z */
2920 /* ?_Init@?$codecvt@GDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2921 /* ?_Init@?$codecvt@_WDH@std@@IAEXABV_Locinfo@2@@Z */
2922 /* ?_Init@?$codecvt@_WDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2923 DEFINE_THISCALL_WRAPPER(codecvt_wchar__Init, 8)
2924 void __thiscall codecvt_wchar__Init(codecvt_wchar *this, const _Locinfo *locinfo)
2925 {
2926     TRACE("(%p %p)\n", this, locinfo);
2927     _Locinfo__Getcvt(locinfo, &this->cvt);
2928 }
2929
2930 /* ??0?$codecvt@_WDH@std@@QAE@ABV_Locinfo@1@I@Z */
2931 /* ??0?$codecvt@_WDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2932 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor_locinfo, 12)
2933 codecvt_wchar* __thiscall codecvt_wchar_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2934 {
2935     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2936
2937     codecvt_base_ctor_refs(&this->base, refs);
2938     this->base.facet.vtable = &MSVCP_codecvt_wchar_vtable;
2939
2940     codecvt_wchar__Init(this, locinfo);
2941     return this;
2942 }
2943
2944 /* ??0?$codecvt@GDH@std@@QAE@ABV_Locinfo@1@I@Z */
2945 /* ??0?$codecvt@GDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2946 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_locinfo, 12)
2947 codecvt_wchar* __thiscall codecvt_short_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2948 {
2949     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2950
2951     codecvt_wchar_ctor_locinfo(this, locinfo, refs);
2952     this->base.facet.vtable = &MSVCP_codecvt_short_vtable;
2953     return this;
2954 }
2955
2956 /* ??0?$codecvt@_WDH@std@@QAE@I@Z */
2957 /* ??0?$codecvt@_WDH@std@@QEAA@_K@Z */
2958 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor_refs, 8)
2959 codecvt_wchar* __thiscall codecvt_wchar_ctor_refs(codecvt_wchar *this, MSVCP_size_t refs)
2960 {
2961     _Locinfo locinfo;
2962
2963     TRACE("(%p %ld)\n", this, refs);
2964
2965     _Locinfo_ctor(&locinfo);
2966     codecvt_wchar_ctor_locinfo(this, &locinfo, refs);
2967     _Locinfo_dtor(&locinfo);
2968     return this;
2969 }
2970
2971 /* ??0?$codecvt@GDH@std@@QAE@I@Z */
2972 /* ??0?$codecvt@GDH@std@@QEAA@_K@Z */
2973 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_refs, 8)
2974 codecvt_wchar* __thiscall codecvt_short_ctor_refs(codecvt_wchar *this, MSVCP_size_t refs)
2975 {
2976     _Locinfo locinfo;
2977
2978     TRACE("(%p %ld)\n", this, refs);
2979
2980     _Locinfo_ctor(&locinfo);
2981     codecvt_short_ctor_locinfo(this, &locinfo, refs);
2982     _Locinfo_dtor(&locinfo);
2983     return this;
2984 }
2985
2986 /* ??0?$codecvt@GDH@std@@IAE@PBDI@Z */
2987 /* ??0?$codecvt@GDH@std@@IEAA@PEBD_K@Z */
2988 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_name, 12)
2989 codecvt_wchar* __thiscall codecvt_short_ctor_name(codecvt_wchar *this, const char *name, MSVCP_size_t refs)
2990 {
2991     _Locinfo locinfo;
2992
2993     TRACE("(%p %s %ld)\n", this, name, refs);
2994
2995     _Locinfo_ctor_cstr(&locinfo, name);
2996     codecvt_short_ctor_locinfo(this, &locinfo, refs);
2997     _Locinfo_dtor(&locinfo);
2998     return this;
2999 }
3000
3001 /* ??_F?$codecvt@_WDH@std@@QAEXXZ */
3002 /* ??_F?$codecvt@_WDH@std@@QEAAXXZ */
3003 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor, 4)
3004 codecvt_wchar* __thiscall codecvt_wchar_ctor(codecvt_wchar *this)
3005 {
3006     return codecvt_wchar_ctor_refs(this, 0);
3007 }
3008
3009 /* ??_F?$codecvt@GDH@std@@QAEXXZ */
3010 /* ??_F?$codecvt@GDH@std@@QEAAXXZ */
3011 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor, 4)
3012 codecvt_wchar* __thiscall codecvt_short_ctor(codecvt_wchar *this)
3013 {
3014     return codecvt_short_ctor_refs(this, 0);
3015 }
3016
3017 /* ??1?$codecvt@GDH@std@@MAE@XZ */
3018 /* ??1?$codecvt@GDH@std@@MEAA@XZ */
3019 /* ??1?$codecvt@_WDH@std@@MAE@XZ */
3020 /* ??1?$codecvt@_WDH@std@@MEAA@XZ */
3021 DEFINE_THISCALL_WRAPPER(codecvt_wchar_dtor, 4)
3022 void __thiscall codecvt_wchar_dtor(codecvt_wchar *this)
3023 {
3024     TRACE("(%p)\n", this);
3025     codecvt_base_dtor(&this->base);
3026 }
3027
3028 DEFINE_THISCALL_WRAPPER(codecvt_wchar_vector_dtor, 8)
3029 codecvt_wchar* __thiscall codecvt_wchar_vector_dtor(codecvt_wchar *this, unsigned int flags)
3030 {
3031     TRACE("(%p %x)\n", this, flags);
3032     if(flags & 2) {
3033         /* we have an array, with the number of elements stored before the first object */
3034         INT_PTR i, *ptr = (INT_PTR *)this-1;
3035
3036         for(i=*ptr-1; i>=0; i--)
3037             codecvt_wchar_dtor(this+i);
3038         MSVCRT_operator_delete(ptr);
3039     } else {
3040         codecvt_wchar_dtor(this);
3041         if(flags & 1)
3042             MSVCRT_operator_delete(this);
3043     }
3044
3045     return this;
3046 }
3047
3048 /* ?_Getcat@?$codecvt@_WDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3049 /* ?_Getcat@?$codecvt@_WDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3050 MSVCP_size_t __cdecl codecvt_wchar__Getcat(const locale_facet **facet, const locale *loc)
3051 {
3052     TRACE("(%p %p)\n", facet, loc);
3053
3054     if(facet && !*facet) {
3055         _Locinfo locinfo;
3056
3057         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
3058         if(!*facet) {
3059             ERR("Out of memory\n");
3060             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3061             return 0;
3062         }
3063
3064         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
3065         codecvt_wchar_ctor_locinfo((codecvt_wchar*)*facet, &locinfo, 0);
3066         _Locinfo_dtor(&locinfo);
3067     }
3068
3069     return LC_CTYPE;
3070 }
3071
3072 codecvt_wchar* codecvt_wchar_use_facet(const locale *loc)
3073 {
3074     static codecvt_wchar *obj = NULL;
3075
3076     _Lockit lock;
3077     const locale_facet *fac;
3078
3079     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3080     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_wchar_id));
3081     if(fac) {
3082         _Lockit_dtor(&lock);
3083         return (codecvt_wchar*)fac;
3084     }
3085
3086     if(obj) {
3087         _Lockit_dtor(&lock);
3088         return obj;
3089     }
3090
3091     codecvt_wchar__Getcat(&fac, loc);
3092     obj = (codecvt_wchar*)fac;
3093     locale_facet__Incref(&obj->base.facet);
3094     locale_facet_register(&obj->base.facet);
3095     _Lockit_dtor(&lock);
3096
3097     return obj;
3098 }
3099
3100 /* ?_Getcat@?$codecvt@GDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3101 /* ?_Getcat@?$codecvt@GDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3102 MSVCP_size_t __cdecl codecvt_short__Getcat(const locale_facet **facet, const locale *loc)
3103 {
3104     TRACE("(%p %p)\n", facet, loc);
3105
3106     if(facet && !*facet) {
3107         _Locinfo locinfo;
3108
3109         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
3110         if(!*facet) {
3111             ERR("Out of memory\n");
3112             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3113             return 0;
3114         }
3115
3116         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
3117         codecvt_short_ctor((codecvt_wchar*)*facet);
3118         _Locinfo_dtor(&locinfo);
3119     }
3120
3121     return LC_CTYPE;
3122 }
3123
3124 codecvt_wchar* codecvt_short_use_facet(const locale *loc)
3125 {
3126     static codecvt_wchar *obj = NULL;
3127
3128     _Lockit lock;
3129     const locale_facet *fac;
3130
3131     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3132     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_short_id));
3133     if(fac) {
3134         _Lockit_dtor(&lock);
3135         return (codecvt_wchar*)fac;
3136     }
3137
3138     if(obj) {
3139         _Lockit_dtor(&lock);
3140         return obj;
3141     }
3142
3143     codecvt_short__Getcat(&fac, loc);
3144     obj = (codecvt_wchar*)fac;
3145     locale_facet__Incref(&obj->base.facet);
3146     locale_facet_register(&obj->base.facet);
3147     _Lockit_dtor(&lock);
3148
3149     return obj;
3150 }
3151
3152 /* ?_Id_func@?$codecvt@_WDH@std@@SAAAVid@locale@2@XZ */
3153 /* ?_Id_func@?$codecvt@_WDH@std@@SAAEAVid@locale@2@XZ */
3154 locale_id* __cdecl codecvt_wchar__Id_func(void)
3155 {
3156     TRACE("()\n");
3157     return &codecvt_wchar_id;
3158 }
3159
3160 /* ?_Id_func@?$codecvt@GDH@std@@SAAAVid@locale@2@XZ */
3161 /* ?_Id_func@?$codecvt@GDH@std@@SAAEAVid@locale@2@XZ */
3162 locale_id* __cdecl codecvt_short__Id_func(void)
3163 {
3164     TRACE("()\n");
3165     return &codecvt_short_id;
3166 }
3167
3168 /* ?do_always_noconv@?$codecvt@GDH@std@@MBE_NXZ */
3169 /* ?do_always_noconv@?$codecvt@GDH@std@@MEBA_NXZ */
3170 /* ?do_always_noconv@?$codecvt@_WDH@std@@MBE_NXZ */
3171 /* ?do_always_noconv@?$codecvt@_WDH@std@@MEBA_NXZ */
3172 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_always_noconv, 4)
3173 MSVCP_bool __thiscall codecvt_wchar_do_always_noconv(const codecvt_wchar *this)
3174 {
3175     TRACE("(%p)\n", this);
3176     return FALSE;
3177 }
3178
3179 /* ?do_max_length@?$codecvt@GDH@std@@MBEHXZ */
3180 /* ?do_max_length@?$codecvt@GDH@std@@MEBAHXZ */
3181 /* ?do_max_length@?$codecvt@_WDH@std@@MBEHXZ */
3182 /* ?do_max_length@?$codecvt@_WDH@std@@MEBAHXZ */
3183 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_max_length, 4)
3184 int __thiscall codecvt_wchar_do_max_length(const codecvt_wchar *this)
3185 {
3186     TRACE("(%p)\n", this);
3187     return MB_LEN_MAX;
3188 }
3189
3190 /* ?do_in@?$codecvt@GDH@std@@MBEHAAHPBD1AAPBDPAG3AAPAG@Z */
3191 /* ?do_in@?$codecvt@GDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
3192 /* ?do_in@?$codecvt@_WDH@std@@MBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
3193 /* ?do_in@?$codecvt@_WDH@std@@MEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
3194 #define call_codecvt_wchar_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
3195     CALL_VTBL_FUNC(this, 16, int, \
3196             (const codecvt_wchar*, int*, const char*, const char*, const char**, wchar_t*, wchar_t*, wchar_t**), \
3197             (this, state, from, from_end, from_next, to, to_end, to_next))
3198 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_in, 32)
3199 int __thiscall codecvt_wchar_do_in(const codecvt_wchar *this, int *state,
3200         const char *from, const char *from_end, const char **from_next,
3201         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
3202 {
3203     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3204             from_end, from_next, to, to_end, to_next);
3205
3206     *from_next = from;
3207     *to_next = to;
3208
3209     while(*from_next!=from_end && *to_next!=to_end) {
3210         switch(_Mbrtowc(*to_next, *from_next, from_end-*from_next, state, &this->cvt)) {
3211         case -2:
3212             *from_next = from_end;
3213             return CODECVT_partial;
3214         case -1:
3215             return CODECVT_error;
3216         case 2:
3217             (*from_next)++;
3218             /* fall through */
3219         case 0:
3220         case 1:
3221             (*from_next)++;
3222             (*to_next)++;
3223         }
3224     }
3225
3226     return CODECVT_ok;
3227 }
3228
3229 /* ?in@?$codecvt@GDH@std@@QBEHAAHPBD1AAPBDPAG3AAPAG@Z */
3230 /* ?in@?$codecvt@GDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
3231 /* ?in@?$codecvt@_WDH@std@@QBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
3232 /* ?in@?$codecvt@_WDH@std@@QEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
3233 DEFINE_THISCALL_WRAPPER(codecvt_wchar_in, 32)
3234 int __thiscall codecvt_wchar_in(const codecvt_wchar *this, int *state,
3235         const char *from, const char *from_end, const char **from_next,
3236         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
3237 {
3238     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3239             from_end, from_next, to, to_end, to_next);
3240     return call_codecvt_wchar_do_in(this, state, from,
3241             from_end, from_next, to, to_end, to_next);
3242 }
3243
3244 /* ?do_out@?$codecvt@GDH@std@@MBEHAAHPBG1AAPBGPAD3AAPAD@Z */
3245 /* ?do_out@?$codecvt@GDH@std@@MEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
3246 /* ?do_out@?$codecvt@_WDH@std@@MBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
3247 /* ?do_out@?$codecvt@_WDH@std@@MEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
3248 #define call_codecvt_wchar_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
3249     CALL_VTBL_FUNC(this, 20, int, \
3250             (const codecvt_wchar*, int*, const wchar_t*, const wchar_t*, const wchar_t**, char*, char*, char**), \
3251             (this, state, from, from_end, from_next, to, to_end, to_next))
3252 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_out, 32)
3253 int __thiscall codecvt_wchar_do_out(const codecvt_wchar *this, int *state,
3254         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
3255         char *to, char *to_end, char **to_next)
3256 {
3257     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3258             from_end, from_next, to, to_end, to_next);
3259
3260     *from_next = from;
3261     *to_next = to;
3262
3263     while(*from_next!=from_end && *to_next!=to_end) {
3264         int old_state = *state, size;
3265         char buf[MB_LEN_MAX];
3266
3267         switch((size = _Wcrtomb(buf, **from_next, state, &this->cvt))) {
3268         case -1:
3269             return CODECVT_error;
3270         default:
3271             if(size > from_end-*from_next) {
3272                 *state = old_state;
3273                 return CODECVT_partial;
3274             }
3275
3276             (*from_next)++;
3277             memcpy_s(*to_next, to_end-*to_next, buf, size);
3278             (*to_next) += size;
3279         }
3280     }
3281
3282     return CODECVT_ok;
3283 }
3284
3285 /* ?out@?$codecvt@GDH@std@@QBEHAAHPBG1AAPBGPAD3AAPAD@Z */
3286 /* ?out@?$codecvt@GDH@std@@QEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
3287 /* ?out@?$codecvt@_WDH@std@@QBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
3288 /* ?out@?$codecvt@_WDH@std@@QEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
3289 DEFINE_THISCALL_WRAPPER(codecvt_wchar_out, 32)
3290 int __thiscall codecvt_wchar_out(const codecvt_wchar *this, int *state,
3291         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
3292         char *to, char *to_end, char **to_next)
3293 {
3294     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3295             from_end, from_next, to, to_end, to_next);
3296     return call_codecvt_wchar_do_out(this, state, from,
3297             from_end, from_next, to, to_end, to_next);
3298 }
3299
3300 /* ?do_unshift@?$codecvt@GDH@std@@MBEHAAHPAD1AAPAD@Z */
3301 /* ?do_unshift@?$codecvt@GDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
3302 /* ?do_unshift@?$codecvt@_WDH@std@@MBEHAAHPAD1AAPAD@Z */
3303 /* ?do_unshift@?$codecvt@_WDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
3304 #define call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
3305         int, (const codecvt_wchar*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
3306 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_unshift, 20)
3307 int __thiscall codecvt_wchar_do_unshift(const codecvt_wchar *this,
3308         int *state, char *to, char *to_end, char **to_next)
3309 {
3310     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
3311     if(*state)
3312         WARN("unexpected state: %x\n", *state);
3313
3314     *to_next = to;
3315     return CODECVT_ok;
3316 }
3317
3318 /* ?unshift@?$codecvt@GDH@std@@QBEHAAHPAD1AAPAD@Z */
3319 /* ?unshift@?$codecvt@GDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
3320 /* ?unshift@?$codecvt@_WDH@std@@QBEHAAHPAD1AAPAD@Z */
3321 /* ?unshift@?$codecvt@_WDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
3322 DEFINE_THISCALL_WRAPPER(codecvt_wchar_unshift, 20)
3323 int __thiscall codecvt_wchar_unshift(const codecvt_wchar *this,
3324         int *state, char *to, char *to_end, char **to_next)
3325 {
3326     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
3327     return call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next);
3328 }
3329
3330 /* ?do_length@?$codecvt@GDH@std@@MBEHABHPBD1I@Z */
3331 /* ?do_length@?$codecvt@GDH@std@@MEBAHAEBHPEBD1_K@Z */
3332 /* ?do_length@?$codecvt@_WDH@std@@MBEHABHPBD1I@Z */
3333 /* ?do_length@?$codecvt@_WDH@std@@MEBAHAEBHPEBD1_K@Z */
3334 #define call_codecvt_wchar_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
3335         int, (const codecvt_wchar*, const int*, const char*, const char*, MSVCP_size_t), \
3336         (this, state, from, from_end, max))
3337 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_length, 20)
3338 int __thiscall codecvt_wchar_do_length(const codecvt_wchar *this, const int *state,
3339         const char *from, const char *from_end, MSVCP_size_t max)
3340 {
3341     int tmp_state = *state, ret=0;
3342
3343     TRACE("(%p %p %p %p %ld)\n", this, state, from, from_end, max);
3344
3345     while(ret<max && from!=from_end) {
3346         switch(_Mbrtowc(NULL, from, from_end-from, &tmp_state, &this->cvt)) {
3347         case -2:
3348         case -1:
3349             return ret;
3350         case 2:
3351             from++;
3352             /* fall through */
3353         case 0:
3354         case 1:
3355             from++;
3356             ret++;
3357         }
3358     }
3359
3360     return ret;
3361 }
3362
3363 /* ?length@?$codecvt@GDH@std@@QBEHABHPBD1I@Z */
3364 /* ?length@?$codecvt@GDH@std@@QEBAHAEBHPEBD1_K@Z */
3365 /* ?length@?$codecvt@_WDH@std@@QBEHABHPBD1I@Z */
3366 /* ?length@?$codecvt@_WDH@std@@QEBAHAEBHPEBD1_K@Z */
3367 DEFINE_THISCALL_WRAPPER(codecvt_wchar_length, 20)
3368 int __thiscall codecvt_wchar_length(const codecvt_wchar *this, const int *state,
3369         const char *from, const char *from_end, MSVCP_size_t max)
3370 {
3371     TRACE("(%p %p %p %p %ld)\n", this, state, from, from_end, max);
3372     return call_codecvt_wchar_do_length(this, state, from, from_end, max);
3373 }
3374
3375 /* ?id@?$numpunct@D@std@@2V0locale@2@A */
3376 locale_id numpunct_char_id = {0};
3377
3378 /* ??_7?$numpunct@D@std@@6B@ */
3379 extern const vtable_ptr MSVCP_numpunct_char_vtable;
3380
3381 /* ?_Init@?$numpunct@D@std@@IAEXABV_Locinfo@2@_N@Z */
3382 /* ?_Init@?$numpunct@D@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3383 DEFINE_THISCALL_WRAPPER(numpunct_char__Init, 12)
3384 void __thiscall numpunct_char__Init(numpunct_char *this, const _Locinfo *locinfo, MSVCP_bool isdef)
3385 {
3386     int len;
3387
3388     TRACE("(%p %p %d)\n", this, locinfo, isdef);
3389
3390     len = strlen(_Locinfo__Getfalse(locinfo))+1;
3391     this->false_name = MSVCRT_operator_new(len);
3392     if(this->false_name)
3393         memcpy((char*)this->false_name, _Locinfo__Getfalse(locinfo), len);
3394
3395     len = strlen(_Locinfo__Gettrue(locinfo))+1;
3396     this->true_name = MSVCRT_operator_new(len);
3397     if(this->true_name)
3398         memcpy((char*)this->true_name, _Locinfo__Gettrue(locinfo), len);
3399
3400     if(isdef) {
3401         this->grouping = MSVCRT_operator_new(1);
3402         if(this->grouping)
3403             *(char*)this->grouping = 0;
3404
3405         this->dp = '.';
3406         this->sep = ',';
3407     } else {
3408         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3409
3410         len = strlen(lc->grouping)+1;
3411         this->grouping = MSVCRT_operator_new(len);
3412         if(this->grouping)
3413             memcpy((char*)this->grouping, lc->grouping, len);
3414
3415         this->dp = lc->decimal_point[0];
3416         this->sep = lc->thousands_sep[0];
3417     }
3418
3419     if(!this->false_name || !this->true_name || !this->grouping) {
3420         MSVCRT_operator_delete((char*)this->grouping);
3421         MSVCRT_operator_delete((char*)this->false_name);
3422         MSVCRT_operator_delete((char*)this->true_name);
3423
3424         ERR("Out of memory\n");
3425         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3426     }
3427 }
3428
3429 /* ?_Tidy@?$numpunct@D@std@@AAEXXZ */
3430 /* ?_Tidy@?$numpunct@D@std@@AEAAXXZ */
3431 DEFINE_THISCALL_WRAPPER(numpunct_char__Tidy, 4)
3432 void __thiscall numpunct_char__Tidy(numpunct_char *this)
3433 {
3434     TRACE("(%p)\n", this);
3435
3436     MSVCRT_operator_delete((char*)this->grouping);
3437     MSVCRT_operator_delete((char*)this->false_name);
3438     MSVCRT_operator_delete((char*)this->true_name);
3439 }
3440
3441 /* ??0?$numpunct@D@std@@QAE@ABV_Locinfo@1@I_N@Z */
3442 /* ??0?$numpunct@D@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3443 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_locinfo, 16)
3444 numpunct_char* __thiscall numpunct_char_ctor_locinfo(numpunct_char *this,
3445         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3446 {
3447     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3448     locale_facet_ctor_refs(&this->facet, refs);
3449     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3450     numpunct_char__Init(this, locinfo, usedef);
3451     return this;
3452 }
3453
3454 /* ??0?$numpunct@D@std@@IAE@PBDI_N@Z */
3455 /* ??0?$numpunct@D@std@@IEAA@PEBD_K_N@Z */
3456 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_name, 16)
3457 numpunct_char* __thiscall numpunct_char_ctor_name(numpunct_char *this,
3458         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3459 {
3460     _Locinfo locinfo;
3461
3462     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3463     locale_facet_ctor_refs(&this->facet, refs);
3464     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3465
3466     _Locinfo_ctor_cstr(&locinfo, name);
3467     numpunct_char__Init(this, &locinfo, usedef);
3468     _Locinfo_dtor(&locinfo);
3469     return this;
3470 }
3471
3472 /* ??0?$numpunct@D@std@@QAE@I@Z */
3473 /* ??0?$numpunct@D@std@@QEAA@_K@Z */
3474 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_refs, 8)
3475 numpunct_char* __thiscall numpunct_char_ctor_refs(numpunct_char *this, MSVCP_size_t refs)
3476 {
3477     TRACE("(%p %lu)\n", this, refs);
3478     return numpunct_char_ctor_name(this, "C", refs, FALSE);
3479 }
3480
3481 /* ??_F?$numpunct@D@std@@QAEXXZ */
3482 /* ??_F?$numpunct@D@std@@QEAAXXZ */
3483 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor, 4)
3484 numpunct_char* __thiscall numpunct_char_ctor(numpunct_char *this)
3485 {
3486     return numpunct_char_ctor_refs(this, 0);
3487 }
3488
3489 /* ??1?$numpunct@D@std@@MAE@XZ */
3490 /* ??1?$numpunct@D@std@@MEAA@XZ */
3491 DEFINE_THISCALL_WRAPPER(numpunct_char_dtor, 4)
3492 void __thiscall numpunct_char_dtor(numpunct_char *this)
3493 {
3494     TRACE("(%p)\n", this);
3495     numpunct_char__Tidy(this);
3496 }
3497
3498 DEFINE_THISCALL_WRAPPER(numpunct_char_vector_dtor, 8)
3499 numpunct_char* __thiscall numpunct_char_vector_dtor(numpunct_char *this, unsigned int flags)
3500 {
3501     TRACE("(%p %x)\n", this, flags);
3502     if(flags & 2) {
3503         /* we have an array, with the number of elements stored before the first object */
3504         INT_PTR i, *ptr = (INT_PTR *)this-1;
3505
3506         for(i=*ptr-1; i>=0; i--)
3507             numpunct_char_dtor(this+i);
3508         MSVCRT_operator_delete(ptr);
3509     } else {
3510         numpunct_char_dtor(this);
3511         if(flags & 1)
3512             MSVCRT_operator_delete(this);
3513     }
3514
3515     return this;
3516 }
3517
3518 /* ?_Getcat@?$numpunct@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3519 /* ?_Getcat@?$numpunct@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3520 MSVCP_size_t __cdecl numpunct_char__Getcat(const locale_facet **facet, const locale *loc)
3521 {
3522     TRACE("(%p %p)\n", facet, loc);
3523
3524     if(facet && !*facet) {
3525         *facet = MSVCRT_operator_new(sizeof(numpunct_char));
3526         if(!*facet) {
3527             ERR("Out of memory\n");
3528             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3529             return 0;
3530         }
3531         numpunct_char_ctor_name((numpunct_char*)*facet,
3532                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3533     }
3534
3535     return LC_NUMERIC;
3536 }
3537
3538 static numpunct_char* numpunct_char_use_facet(const locale *loc)
3539 {
3540     static numpunct_char *obj = NULL;
3541
3542     _Lockit lock;
3543     const locale_facet *fac;
3544
3545     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3546     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_char_id));
3547     if(fac) {
3548         _Lockit_dtor(&lock);
3549         return (numpunct_char*)fac;
3550     }
3551
3552     if(obj) {
3553         _Lockit_dtor(&lock);
3554         return obj;
3555     }
3556
3557     numpunct_char__Getcat(&fac, loc);
3558     obj = (numpunct_char*)fac;
3559     locale_facet__Incref(&obj->facet);
3560     locale_facet_register(&obj->facet);
3561     _Lockit_dtor(&lock);
3562
3563     return obj;
3564 }
3565
3566 /* ?do_decimal_point@?$numpunct@D@std@@MBEDXZ */
3567 /* ?do_decimal_point@?$numpunct@D@std@@MEBADXZ */
3568 DEFINE_THISCALL_WRAPPER(numpunct_char_do_decimal_point, 4)
3569 #define call_numpunct_char_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3570         char, (const numpunct_char *this), (this))
3571 char __thiscall numpunct_char_do_decimal_point(const numpunct_char *this)
3572 {
3573     TRACE("(%p)\n", this);
3574     return this->dp;
3575 }
3576
3577 /* ?decimal_point@?$numpunct@D@std@@QBEDXZ */
3578 /* ?decimal_point@?$numpunct@D@std@@QEBADXZ */
3579 DEFINE_THISCALL_WRAPPER(numpunct_char_decimal_point, 4)
3580 char __thiscall numpunct_char_decimal_point(const numpunct_char *this)
3581 {
3582     TRACE("(%p)\n", this);
3583     return call_numpunct_char_do_decimal_point(this);
3584 }
3585
3586 /* ?do_thousands_sep@?$numpunct@D@std@@MBEDXZ */
3587 /* ?do_thousands_sep@?$numpunct@D@std@@MEBADXZ */
3588 DEFINE_THISCALL_WRAPPER(numpunct_char_do_thousands_sep, 4)
3589 #define call_numpunct_char_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
3590         char, (const numpunct_char*), (this))
3591 char __thiscall numpunct_char_do_thousands_sep(const numpunct_char *this)
3592 {
3593     TRACE("(%p)\n", this);
3594     return this->sep;
3595 }
3596
3597 /* ?thousands_sep@?$numpunct@D@std@@QBEDXZ */
3598 /* ?thousands_sep@?$numpunct@D@std@@QEBADXZ */
3599 DEFINE_THISCALL_WRAPPER(numpunct_char_thousands_sep, 4)
3600 char __thiscall numpunct_char_thousands_sep(const numpunct_char *this)
3601 {
3602     TRACE("(%p)\n", this);
3603     return call_numpunct_char_do_thousands_sep(this);
3604 }
3605
3606 /* ?do_grouping@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3607 /* ?do_grouping@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3608 DEFINE_THISCALL_WRAPPER(numpunct_char_do_grouping, 8)
3609 #define call_numpunct_char_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
3610         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3611 basic_string_char* __thiscall numpunct_char_do_grouping(
3612         const numpunct_char *this, basic_string_char *ret)
3613 {
3614     TRACE("(%p)\n", this);
3615     return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping);
3616 }
3617
3618 /* ?grouping@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3619 /* ?grouping@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3620 DEFINE_THISCALL_WRAPPER(numpunct_char_grouping, 8)
3621 basic_string_char* __thiscall numpunct_char_grouping(const numpunct_char *this, basic_string_char *ret)
3622 {
3623     TRACE("(%p)\n", this);
3624     return call_numpunct_char_do_grouping(this, ret);
3625 }
3626
3627 /* ?do_falsename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3628 /* ?do_falsename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3629 DEFINE_THISCALL_WRAPPER(numpunct_char_do_falsename, 8)
3630 #define call_numpunct_char_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
3631         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3632 basic_string_char* __thiscall numpunct_char_do_falsename(
3633         const numpunct_char *this, basic_string_char *ret)
3634 {
3635     TRACE("(%p)\n", this);
3636     return MSVCP_basic_string_char_ctor_cstr(ret, this->false_name);
3637 }
3638
3639 /* ?falsename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3640 /* ?falsename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3641 DEFINE_THISCALL_WRAPPER(numpunct_char_falsename, 8)
3642 basic_string_char* __thiscall numpunct_char_falsename(const numpunct_char *this, basic_string_char *ret)
3643 {
3644     TRACE("(%p)\n", this);
3645     return call_numpunct_char_do_falsename(this, ret);
3646 }
3647
3648 /* ?do_truename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3649 /* ?do_truename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3650 DEFINE_THISCALL_WRAPPER(numpunct_char_do_truename, 8)
3651 #define call_numpunct_char_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
3652         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3653 basic_string_char* __thiscall numpunct_char_do_truename(
3654         const numpunct_char *this, basic_string_char *ret)
3655 {
3656     TRACE("(%p)\n", this);
3657     return MSVCP_basic_string_char_ctor_cstr(ret, this->true_name);
3658 }
3659
3660 /* ?truename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3661 /* ?truename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3662 DEFINE_THISCALL_WRAPPER(numpunct_char_truename, 8)
3663 basic_string_char* __thiscall numpunct_char_truename(const numpunct_char *this, basic_string_char *ret)
3664 {
3665     TRACE("(%p)\n", this);
3666     return call_numpunct_char_do_truename(this, ret);
3667 }
3668
3669 /* ?id@?$numpunct@_W@std@@2V0locale@2@A */
3670 locale_id numpunct_wchar_id = {0};
3671 /* ?id@?$numpunct@G@std@@2V0locale@2@A */
3672 locale_id numpunct_short_id = {0};
3673
3674 /* ??_7?$numpunct@_W@std@@6B@ */
3675 extern const vtable_ptr MSVCP_numpunct_wchar_vtable;
3676 /* ??_7?$numpunct@G@std@@6B@ */
3677 extern const vtable_ptr MSVCP_numpunct_short_vtable;
3678
3679 /* ?_Init@?$numpunct@_W@std@@IAEXABV_Locinfo@2@_N@Z */
3680 /* ?_Init@?$numpunct@_W@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3681 /* ?_Init@?$numpunct@G@std@@IAEXABV_Locinfo@2@_N@Z */
3682 /* ?_Init@?$numpunct@G@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3683 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Init, 12)
3684 void __thiscall numpunct_wchar__Init(numpunct_wchar *this,
3685         const _Locinfo *locinfo, MSVCP_bool isdef)
3686 {
3687     const char *to_convert;
3688     _Cvtvec cvt;
3689     int len;
3690
3691     TRACE("(%p %p %d)\n", this, locinfo, isdef);
3692
3693     _Locinfo__Getcvt(locinfo, &cvt);
3694
3695     to_convert = _Locinfo__Getfalse(locinfo);
3696     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3697     this->false_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3698     if(this->false_name)
3699         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3700                 (wchar_t*)this->false_name, len);
3701
3702     to_convert = _Locinfo__Gettrue(locinfo);
3703     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3704     this->true_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3705     if(this->true_name)
3706         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3707                 (wchar_t*)this->true_name, len);
3708
3709     if(isdef) {
3710         this->grouping = MSVCRT_operator_new(1);
3711         if(this->grouping)
3712             *(char*)this->grouping = 0;
3713
3714         this->dp = '.';
3715         this->sep = ',';
3716     } else {
3717         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3718
3719         len = strlen(lc->grouping)+1;
3720         this->grouping = MSVCRT_operator_new(len);
3721         if(this->grouping)
3722             memcpy((char*)this->grouping, lc->grouping, len);
3723
3724         this->dp = lc->decimal_point[0];
3725         this->sep = lc->thousands_sep[0];
3726     }
3727
3728     if(!this->false_name || !this->true_name || !this->grouping) {
3729         MSVCRT_operator_delete((char*)this->grouping);
3730         MSVCRT_operator_delete((wchar_t*)this->false_name);
3731         MSVCRT_operator_delete((wchar_t*)this->true_name);
3732
3733         ERR("Out of memory\n");
3734         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3735     }
3736 }
3737
3738 /* ?_Tidy@?$numpunct@_W@std@@AAEXXZ */
3739 /* ?_Tidy@?$numpunct@_W@std@@AEAAXXZ */
3740 /* ?_Tidy@?$numpunct@G@std@@AAEXXZ */
3741 /* ?_Tidy@?$numpunct@G@std@@AEAAXXZ */
3742 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Tidy, 4)
3743 void __thiscall numpunct_wchar__Tidy(numpunct_wchar *this)
3744 {
3745     TRACE("(%p)\n", this);
3746
3747     MSVCRT_operator_delete((char*)this->grouping);
3748     MSVCRT_operator_delete((wchar_t*)this->false_name);
3749     MSVCRT_operator_delete((wchar_t*)this->true_name);
3750 }
3751
3752 /* ??0?$numpunct@_W@std@@QAE@ABV_Locinfo@1@I_N@Z */
3753 /* ??0?$numpunct@_W@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3754 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_locinfo, 16)
3755 numpunct_wchar* __thiscall numpunct_wchar_ctor_locinfo(numpunct_wchar *this,
3756         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3757 {
3758     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3759     locale_facet_ctor_refs(&this->facet, refs);
3760     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3761     numpunct_wchar__Init(this, locinfo, usedef);
3762     return this;
3763 }
3764
3765 /* ??0?$numpunct@G@std@@QAE@ABV_Locinfo@1@I_N@Z */
3766 /* ??0?$numpunct@G@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3767 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_locinfo, 16)
3768 numpunct_wchar* __thiscall numpunct_short_ctor_locinfo(numpunct_wchar *this,
3769         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3770 {
3771     numpunct_wchar_ctor_locinfo(this, locinfo, refs, usedef);
3772     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3773     return this;
3774 }
3775
3776 /* ??0?$numpunct@_W@std@@IAE@PBDI_N@Z */
3777 /* ??0?$numpunct@_W@std@@IEAA@PEBD_K_N@Z */
3778 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_name, 16)
3779 numpunct_wchar* __thiscall numpunct_wchar_ctor_name(numpunct_wchar *this,
3780         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3781 {
3782     _Locinfo locinfo;
3783
3784     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3785     locale_facet_ctor_refs(&this->facet, refs);
3786     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3787
3788     _Locinfo_ctor_cstr(&locinfo, name);
3789     numpunct_wchar__Init(this, &locinfo, usedef);
3790     _Locinfo_dtor(&locinfo);
3791     return this;
3792 }
3793
3794 /* ??0?$numpunct@G@std@@IAE@PBDI_N@Z */
3795 /* ??0?$numpunct@G@std@@IEAA@PEBD_K_N@Z */
3796     DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_name, 16)
3797 numpunct_wchar* __thiscall numpunct_short_ctor_name(numpunct_wchar *this,
3798         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3799 {
3800     numpunct_wchar_ctor_name(this, name, refs, usedef);
3801     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3802     return this;
3803 }
3804
3805 /* ??0?$numpunct@_W@std@@QAE@I@Z */
3806 /* ??0?$numpunct@_W@std@@QEAA@_K@Z */
3807     DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_refs, 8)
3808 numpunct_wchar* __thiscall numpunct_wchar_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3809 {
3810     TRACE("(%p %lu)\n", this, refs);
3811     return numpunct_wchar_ctor_name(this, "C", refs, FALSE);
3812 }
3813
3814 /* ??0?$numpunct@G@std@@QAE@I@Z */
3815 /* ??0?$numpunct@G@std@@QEAA@_K@Z */
3816 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_refs, 8)
3817 numpunct_wchar* __thiscall numpunct_short_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3818 {
3819     numpunct_wchar_ctor_refs(this, refs);
3820     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3821     return this;
3822 }
3823
3824 /* ??_F?$numpunct@_W@std@@QAEXXZ */
3825 /* ??_F?$numpunct@_W@std@@QEAAXXZ */
3826 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor, 4)
3827 numpunct_wchar* __thiscall numpunct_wchar_ctor(numpunct_wchar *this)
3828 {
3829     return numpunct_wchar_ctor_refs(this, 0);
3830 }
3831
3832 /* ??_F?$numpunct@G@std@@QAEXXZ */
3833 /* ??_F?$numpunct@G@std@@QEAAXXZ */
3834 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor, 4)
3835 numpunct_wchar* __thiscall numpunct_short_ctor(numpunct_wchar *this)
3836 {
3837     return numpunct_short_ctor_refs(this, 0);
3838 }
3839
3840 /* ??1?$numpunct@_W@std@@MAE@XZ */
3841 /* ??1?$numpunct@_W@std@@MEAA@XZ */
3842 /* ??1?$numpunct@G@std@@MAE@XZ */
3843 /* ??1?$numpunct@G@std@@MEAA@XZ */
3844 DEFINE_THISCALL_WRAPPER(numpunct_wchar_dtor, 4)
3845 void __thiscall numpunct_wchar_dtor(numpunct_wchar *this)
3846 {
3847     TRACE("(%p)\n", this);
3848     numpunct_wchar__Tidy(this);
3849 }
3850
3851 DEFINE_THISCALL_WRAPPER(numpunct_wchar_vector_dtor, 8)
3852 numpunct_wchar* __thiscall numpunct_wchar_vector_dtor(numpunct_wchar *this, unsigned int flags)
3853 {
3854     TRACE("(%p %x)\n", this, flags);
3855     if(flags & 2) {
3856         /* we have an array, with the number of elements stored before the first object */
3857         INT_PTR i, *ptr = (INT_PTR *)this-1;
3858
3859         for(i=*ptr-1; i>=0; i--)
3860             numpunct_wchar_dtor(this+i);
3861         MSVCRT_operator_delete(ptr);
3862     } else {
3863         numpunct_wchar_dtor(this);
3864         if(flags & 1)
3865             MSVCRT_operator_delete(this);
3866     }
3867
3868     return this;
3869 }
3870
3871 /* ?_Getcat@?$numpunct@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3872 /* ?_Getcat@?$numpunct@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3873 MSVCP_size_t __cdecl numpunct_wchar__Getcat(const locale_facet **facet, const locale *loc)
3874 {
3875     TRACE("(%p %p)\n", facet, loc);
3876
3877     if(facet && !*facet) {
3878         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3879         if(!*facet) {
3880             ERR("Out of memory\n");
3881             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3882             return 0;
3883         }
3884         numpunct_wchar_ctor_name((numpunct_wchar*)*facet,
3885                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3886     }
3887
3888     return LC_NUMERIC;
3889 }
3890
3891 static numpunct_wchar* numpunct_wchar_use_facet(const locale *loc)
3892 {
3893     static numpunct_wchar *obj = NULL;
3894
3895     _Lockit lock;
3896     const locale_facet *fac;
3897
3898     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3899     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_wchar_id));
3900     if(fac) {
3901         _Lockit_dtor(&lock);
3902         return (numpunct_wchar*)fac;
3903     }
3904
3905     if(obj) {
3906         _Lockit_dtor(&lock);
3907         return obj;
3908     }
3909
3910     numpunct_wchar__Getcat(&fac, loc);
3911     obj = (numpunct_wchar*)fac;
3912     locale_facet__Incref(&obj->facet);
3913     locale_facet_register(&obj->facet);
3914     _Lockit_dtor(&lock);
3915
3916     return obj;
3917 }
3918
3919 /* ?_Getcat@?$numpunct@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3920 /* ?_Getcat@?$numpunct@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3921 MSVCP_size_t __cdecl numpunct_short__Getcat(const locale_facet **facet, const locale *loc)
3922 {
3923     TRACE("(%p %p)\n", facet, loc);
3924
3925     if(facet && !*facet) {
3926         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3927         if(!*facet) {
3928             ERR("Out of memory\n");
3929             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3930             return 0;
3931         }
3932         numpunct_short_ctor_name((numpunct_wchar*)*facet,
3933                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3934     }
3935
3936     return LC_NUMERIC;
3937 }
3938
3939 static numpunct_wchar* numpunct_short_use_facet(const locale *loc)
3940 {
3941     static numpunct_wchar *obj = NULL;
3942
3943     _Lockit lock;
3944     const locale_facet *fac;
3945
3946     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3947     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_short_id));
3948     if(fac) {
3949         _Lockit_dtor(&lock);
3950         return (numpunct_wchar*)fac;
3951     }
3952
3953     if(obj) {
3954         _Lockit_dtor(&lock);
3955         return obj;
3956     }
3957
3958     numpunct_short__Getcat(&fac, loc);
3959     obj = (numpunct_wchar*)fac;
3960     locale_facet__Incref(&obj->facet);
3961     locale_facet_register(&obj->facet);
3962     _Lockit_dtor(&lock);
3963
3964     return obj;
3965 }
3966
3967 /* ?do_decimal_point@?$numpunct@_W@std@@MBE_WXZ */
3968 /* ?do_decimal_point@?$numpunct@_W@std@@MEBA_WXZ */
3969 /* ?do_decimal_point@?$numpunct@G@std@@MBEGXZ */
3970 /* ?do_decimal_point@?$numpunct@G@std@@MEBAGXZ */
3971 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_decimal_point, 4)
3972 #define call_numpunct_wchar_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3973         wchar_t, (const numpunct_wchar *this), (this))
3974 wchar_t __thiscall numpunct_wchar_do_decimal_point(const numpunct_wchar *this)
3975 {
3976     TRACE("(%p)\n", this);
3977     return this->dp;
3978 }
3979
3980 /* ?decimal_point@?$numpunct@_W@std@@QBE_WXZ */
3981 /* ?decimal_point@?$numpunct@_W@std@@QEBA_WXZ */
3982 /* ?decimal_point@?$numpunct@G@std@@QBEGXZ */
3983 /* ?decimal_point@?$numpunct@G@std@@QEBAGXZ */
3984 DEFINE_THISCALL_WRAPPER(numpunct_wchar_decimal_point, 4)
3985 wchar_t __thiscall numpunct_wchar_decimal_point(const numpunct_wchar *this)
3986 {
3987     TRACE("(%p)\n", this);
3988     return call_numpunct_wchar_do_decimal_point(this);
3989 }
3990
3991 /* ?do_thousands_sep@?$numpunct@_W@std@@MBE_WXZ */
3992 /* ?do_thousands_sep@?$numpunct@_W@std@@MEBA_WXZ */
3993 /* ?do_thousands_sep@?$numpunct@G@std@@MBEGXZ */
3994 /* ?do_thousands_sep@?$numpunct@G@std@@MEBAGXZ */
3995 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_thousands_sep, 4)
3996 #define call_numpunct_wchar_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
3997         wchar_t, (const numpunct_wchar *this), (this))
3998 wchar_t __thiscall numpunct_wchar_do_thousands_sep(const numpunct_wchar *this)
3999 {
4000     TRACE("(%p)\n", this);
4001     return this->sep;
4002 }
4003
4004 /* ?thousands_sep@?$numpunct@_W@std@@QBE_WXZ */
4005 /* ?thousands_sep@?$numpunct@_W@std@@QEBA_WXZ */
4006 /* ?thousands_sep@?$numpunct@G@std@@QBEGXZ */
4007 /* ?thousands_sep@?$numpunct@G@std@@QEBAGXZ */
4008 DEFINE_THISCALL_WRAPPER(numpunct_wchar_thousands_sep, 4)
4009 wchar_t __thiscall numpunct_wchar_thousands_sep(const numpunct_wchar *this)
4010 {
4011     TRACE("(%p)\n", this);
4012     return call_numpunct_wchar_do_thousands_sep(this);
4013 }
4014
4015 /* ?do_grouping@?$numpunct@_W@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4016 /* ?do_grouping@?$numpunct@_W@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4017 /* ?do_grouping@?$numpunct@G@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4018 /* ?do_grouping@?$numpunct@G@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4019 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_grouping, 8)
4020 #define call_numpunct_wchar_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
4021         basic_string_char*, (const numpunct_wchar*, basic_string_char*), (this, ret))
4022 basic_string_char* __thiscall numpunct_wchar_do_grouping(const numpunct_wchar *this, basic_string_char *ret)
4023 {
4024     TRACE("(%p)\n", this);
4025     return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping);
4026 }
4027
4028 /* ?grouping@?$numpunct@_W@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4029 /* ?grouping@?$numpunct@_W@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4030 /* ?grouping@?$numpunct@G@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4031 /* ?grouping@?$numpunct@G@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4032 DEFINE_THISCALL_WRAPPER(numpunct_wchar_grouping, 8)
4033 basic_string_char* __thiscall numpunct_wchar_grouping(const numpunct_wchar *this, basic_string_char *ret)
4034 {
4035     TRACE("(%p)\n", this);
4036     return call_numpunct_wchar_do_grouping(this, ret);
4037 }
4038
4039 /* ?do_falsename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4040 /* ?do_falsename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4041 /* ?do_falsename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4042 /* ?do_falsename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4043 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_falsename, 8)
4044 #define call_numpunct_wchar_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
4045         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
4046 basic_string_wchar* __thiscall numpunct_wchar_do_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
4047 {
4048     TRACE("(%p)\n", this);
4049     return MSVCP_basic_string_wchar_ctor_cstr(ret, this->false_name);
4050 }
4051
4052 /* ?falsename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4053 /* ?falsename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4054 /* ?falsename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4055 /* ?falsename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4056 DEFINE_THISCALL_WRAPPER(numpunct_wchar_falsename, 8)
4057 basic_string_wchar* __thiscall numpunct_wchar_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
4058 {
4059     TRACE("(%p)\n", this);
4060     return call_numpunct_wchar_do_falsename(this, ret);
4061 }
4062
4063 /* ?do_truename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4064 /* ?do_truename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4065 /* ?do_truename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4066 /* ?do_truename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4067 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_truename, 8)
4068 #define call_numpunct_wchar_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
4069         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
4070 basic_string_wchar* __thiscall numpunct_wchar_do_truename(const numpunct_wchar *this, basic_string_wchar *ret)
4071 {
4072     TRACE("(%p)\n", this);
4073     return MSVCP_basic_string_wchar_ctor_cstr(ret, this->true_name);
4074 }
4075
4076 /* ?truename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4077 /* ?truename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4078 /* ?truename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4079 /* ?truename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4080 DEFINE_THISCALL_WRAPPER(numpunct_wchar_truename, 8)
4081 basic_string_wchar* __thiscall numpunct_wchar_truename(const numpunct_wchar *this, basic_string_wchar *ret)
4082 {
4083     TRACE("(%p)\n", this);
4084     return call_numpunct_wchar_do_truename(this, ret);
4085 }
4086
4087 double __cdecl _Stod(const char *buf, char **buf_end, LONG exp)
4088 {
4089     double ret = strtod(buf, buf_end);
4090
4091     if(exp)
4092         ret *= pow(10, exp);
4093     return ret;
4094 }
4095
4096 double __cdecl _Stodx(const char *buf, char **buf_end, LONG exp, int *err)
4097 {
4098     double ret;
4099
4100     *err = *_errno();
4101     *_errno() = 0;
4102     ret = _Stod(buf, buf_end, exp);
4103     if(*_errno()) {
4104         *err = *_errno();
4105     }else {
4106         *_errno() = *err;
4107         *err = 0;
4108     }
4109     return ret;
4110 }
4111
4112 float __cdecl _Stof(const char *buf, char **buf_end, LONG exp)
4113 {
4114     return _Stod(buf, buf_end, exp);
4115 }
4116
4117 float __cdecl _Stofx(const char *buf, char **buf_end, LONG exp, int *err)
4118 {
4119     return _Stodx(buf, buf_end, exp, err);
4120 }
4121
4122 __int64 __cdecl _Stoll(const char *buf, char **buf_end, int base)
4123 {
4124     return _strtoi64(buf, buf_end, base);
4125 }
4126
4127 __int64 __cdecl _Stollx(const char *buf, char **buf_end, int base, int *err)
4128 {
4129     __int64 ret;
4130
4131     *err = *_errno();
4132     *_errno() = 0;
4133     ret = _strtoi64(buf, buf_end, base);
4134     if(*_errno()) {
4135         *err = *_errno();
4136     }else {
4137         *_errno() = *err;
4138         *err = 0;
4139     }
4140     return ret;
4141 }
4142
4143 LONG __cdecl _Stolx(const char *buf, char **buf_end, int base, int *err)
4144 {
4145     __int64 i = _Stollx(buf, buf_end, base, err);
4146     if(!*err && i!=(__int64)((LONG)i))
4147         *err = ERANGE;
4148     return i;
4149 }
4150
4151 unsigned __int64 __cdecl _Stoull(const char *buf, char **buf_end, int base)
4152 {
4153     return _strtoui64(buf, buf_end, base);
4154 }
4155
4156 unsigned __int64 __cdecl _Stoullx(const char *buf, char **buf_end, int base, int *err)
4157 {
4158     unsigned __int64 ret;
4159
4160     *err = *_errno();
4161     *_errno() = 0;
4162     ret = _strtoui64(buf, buf_end, base);
4163     if(*_errno()) {
4164         *err = *_errno();
4165     }else {
4166         *_errno() = *err;
4167         *err = 0;
4168     }
4169     return ret;
4170 }
4171
4172 ULONG __cdecl _Stoul(const char *buf, char **buf_end, int base)
4173 {
4174     int err;
4175     unsigned __int64 i = _Stoullx(buf[0]=='-' ? buf+1 : buf, buf_end, base, &err);
4176     if(!err && i!=(unsigned __int64)((ULONG)i))
4177         *_errno() = ERANGE;
4178     return buf[0]=='-' ? -i : i;
4179 }
4180
4181 ULONG __cdecl _Stoulx(const char *buf, char **buf_end, int base, int *err)
4182 {
4183     unsigned __int64 i = _Stoullx(buf[0]=='-' ? buf+1 : buf, buf_end, base, err);
4184     if(!*err && i!=(unsigned __int64)((ULONG)i))
4185         *err = ERANGE;
4186     return buf[0]=='-' ? -i : i;
4187 }
4188
4189 /* ?id@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
4190 locale_id num_get_wchar_id = {0};
4191 /* ?id@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@2V0locale@2@A */
4192 locale_id num_get_short_id = {0};
4193
4194 /* ??_7?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
4195 extern const vtable_ptr MSVCP_num_get_wchar_vtable;
4196 /* ??_7?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@6B@ */
4197 extern const vtable_ptr MSVCP_num_get_short_vtable;
4198
4199 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4200 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4201 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4202 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4203 DEFINE_THISCALL_WRAPPER(num_get_wchar__Init, 8)
4204 void __thiscall num_get_wchar__Init(num_get *this, const _Locinfo *locinfo)
4205 {
4206     TRACE("(%p %p)\n", this, locinfo);
4207     _Locinfo__Getcvt(locinfo, &this->cvt);
4208 }
4209
4210 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4211 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4212 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_locinfo, 12)
4213 num_get* __thiscall num_get_wchar_ctor_locinfo(num_get *this,
4214         const _Locinfo *locinfo, MSVCP_size_t refs)
4215 {
4216     TRACE("(%p %p %lu)\n", this, locinfo, refs);
4217
4218     locale_facet_ctor_refs(&this->facet, refs);
4219     this->facet.vtable = &MSVCP_num_get_wchar_vtable;
4220
4221     num_get_wchar__Init(this, locinfo);
4222     return this;
4223 }
4224
4225 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4226 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4227 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_locinfo, 12)
4228 num_get* __thiscall num_get_short_ctor_locinfo(num_get *this,
4229         const _Locinfo *locinfo, MSVCP_size_t refs)
4230 {
4231     num_get_wchar_ctor_locinfo(this, locinfo, refs);
4232     this->facet.vtable = &MSVCP_num_get_short_vtable;
4233     return this;
4234 }
4235
4236 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
4237 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
4238 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_refs, 8)
4239 num_get* __thiscall num_get_wchar_ctor_refs(num_get *this, MSVCP_size_t refs)
4240 {
4241     _Locinfo locinfo;
4242
4243     TRACE("(%p %lu)\n", this, refs);
4244
4245     _Locinfo_ctor(&locinfo);
4246     num_get_wchar_ctor_locinfo(this, &locinfo, refs);
4247     _Locinfo_dtor(&locinfo);
4248     return this;
4249 }
4250
4251 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@I@Z */
4252 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@_K@Z */
4253 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_refs, 8)
4254 num_get* __thiscall num_get_short_ctor_refs(num_get *this, MSVCP_size_t refs)
4255 {
4256     num_get_wchar_ctor_refs(this, refs);
4257     this->facet.vtable = &MSVCP_num_get_short_vtable;
4258     return this;
4259 }
4260
4261 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
4262 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
4263 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor, 4)
4264 num_get* __thiscall num_get_wchar_ctor(num_get *this)
4265 {
4266     return num_get_wchar_ctor_refs(this, 0);
4267 }
4268
4269 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
4270 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
4271 DEFINE_THISCALL_WRAPPER(num_get_short_ctor, 4)
4272 num_get* __thiscall num_get_short_ctor(num_get *this)
4273 {
4274     return num_get_short_ctor_refs(this, 0);
4275 }
4276
4277 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
4278 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
4279 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MAE@XZ */
4280 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEAA@XZ */
4281 DEFINE_THISCALL_WRAPPER(num_get_wchar_dtor, 4)
4282 void __thiscall num_get_wchar_dtor(num_get *this)
4283 {
4284     TRACE("(%p)\n", this);
4285     locale_facet_dtor(&this->facet);
4286 }
4287
4288 DEFINE_THISCALL_WRAPPER(num_get_wchar_vector_dtor, 8)
4289 num_get* __thiscall num_get_wchar_vector_dtor(num_get *this, unsigned int flags)
4290 {
4291     TRACE("(%p %x)\n", this, flags);
4292     if(flags & 2) {
4293         /* we have an array, with the number of elements stored before the first object */
4294         INT_PTR i, *ptr = (INT_PTR *)this-1;
4295
4296         for(i=*ptr-1; i>=0; i--)
4297             num_get_wchar_dtor(this+i);
4298         MSVCRT_operator_delete(ptr);
4299     } else {
4300         num_get_wchar_dtor(this);
4301         if(flags & 1)
4302             MSVCRT_operator_delete(this);
4303     }
4304
4305     return this;
4306 }
4307
4308 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4309 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4310 MSVCP_size_t __cdecl num_get_wchar__Getcat(const locale_facet **facet, const locale *loc)
4311 {
4312     TRACE("(%p %p)\n", facet, loc);
4313
4314     if(facet && !*facet) {
4315         _Locinfo locinfo;
4316
4317         *facet = MSVCRT_operator_new(sizeof(num_get));
4318         if(!*facet) {
4319             ERR("Out of memory\n");
4320             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
4321             return 0;
4322         }
4323
4324         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
4325         num_get_wchar_ctor_locinfo((num_get*)*facet, &locinfo, 0);
4326         _Locinfo_dtor(&locinfo);
4327     }
4328
4329     return LC_NUMERIC;
4330 }
4331
4332 num_get* num_get_wchar_use_facet(const locale *loc)
4333 {
4334         static num_get *obj = NULL;
4335
4336         _Lockit lock;
4337         const locale_facet *fac;
4338
4339         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
4340         fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_wchar_id));
4341         if(fac) {
4342             _Lockit_dtor(&lock);
4343             return (num_get*)fac;
4344         }
4345
4346         if(obj) {
4347             _Lockit_dtor(&lock);
4348             return obj;
4349         }
4350
4351         num_get_wchar__Getcat(&fac, loc);
4352         obj = (num_get*)fac;
4353         locale_facet__Incref(&obj->facet);
4354         locale_facet_register(&obj->facet);
4355         _Lockit_dtor(&lock);
4356
4357         return obj;
4358 }
4359
4360 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4361 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4362 MSVCP_size_t __cdecl num_get_short__Getcat(const locale_facet **facet, const locale *loc)
4363 {
4364     if(facet && !*facet) {
4365         num_get_wchar__Getcat(facet, loc);
4366         (*(locale_facet**)facet)->vtable = &MSVCP_num_get_short_vtable;
4367     }
4368
4369     return LC_NUMERIC;
4370 }
4371
4372 num_get* num_get_short_use_facet(const locale *loc)
4373 {
4374     static num_get *obj = NULL;
4375
4376     _Lockit lock;
4377     const locale_facet *fac;
4378
4379     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
4380     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_short_id));
4381     if(fac) {
4382         _Lockit_dtor(&lock);
4383         return (num_get*)fac;
4384     }
4385
4386     if(obj) {
4387         _Lockit_dtor(&lock);
4388         return obj;
4389     }
4390
4391     num_get_short__Getcat(&fac, loc);
4392     obj = (num_get*)fac;
4393     locale_facet__Incref(&obj->facet);
4394     locale_facet_register(&obj->facet);
4395     _Lockit_dtor(&lock);
4396
4397     return obj;
4398 }
4399
4400 static inline wchar_t mb_to_wc(char ch, const _Cvtvec *cvt)
4401 {
4402     int state = 0;
4403     wchar_t ret;
4404
4405     return _Mbrtowc(&ret, &ch, 1, &state, cvt) == 1 ? ret : 0;
4406 }
4407
4408 static int num_get__Getffld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4409         istreambuf_iterator_wchar *last, const locale *loc, numpunct_wchar *numpunct)
4410 {
4411     basic_string_char grouping_bstr;
4412     basic_string_char groups_found;
4413     int i, groups_no = 0, cur_group = 0, exp = 0;
4414     char *dest_beg = dest, *num_end = dest+25, *exp_end = dest+31;
4415     wchar_t sep, digits[11], *digits_pos;
4416     const char *grouping, *groups;
4417     BOOL error = FALSE, got_digit = FALSE, got_nonzero = FALSE;
4418
4419     TRACE("(%p %p %p %p)\n", dest, first, last, loc);
4420
4421     for(i=0; i<10; i++)
4422         digits[i] = mb_to_wc('0'+i, &this->cvt);
4423     digits[10] = 0;
4424
4425     numpunct_wchar_grouping(numpunct, &grouping_bstr);
4426     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
4427     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : 0;
4428
4429     if(sep)
4430         MSVCP_basic_string_char_ctor(&groups_found);
4431
4432     istreambuf_iterator_wchar_val(first);
4433     /* get sign */
4434     if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4435         *dest++ = '-';
4436         istreambuf_iterator_wchar_inc(first);
4437     }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4438         *dest++ = '+';
4439         istreambuf_iterator_wchar_inc(first);
4440     }
4441
4442     /* read possibly grouped numbers before decimal */
4443     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4444         if(!(digits_pos = wcschr(digits, first->val))) {
4445             if(sep && first->val==sep) {
4446                 if(!groups_no) break; /* empty group - stop parsing */
4447                 MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
4448                 groups_no = 0;
4449                 ++cur_group;
4450             }else {
4451                 break;
4452             }
4453         }else {
4454             got_digit = TRUE; /* found a digit, zero or non-zero */
4455             /* write digit to dest if not a leading zero (to not waste dest buffer) */
4456             if(!got_nonzero && first->val == digits[0])
4457             {
4458                 ++groups_no;
4459                 continue;
4460             }
4461             got_nonzero = TRUE;
4462             if(dest < num_end)
4463                 *dest++ = '0'+digits_pos-digits;
4464             else
4465                 exp++; /* too many digits, just multiply by 10 */
4466             if(sep && groups_no<CHAR_MAX)
4467                 ++groups_no;
4468         }
4469     }
4470
4471     /* if all leading zeroes, we didn't write anything so put a zero we check for a decimal */
4472     if(got_digit && !got_nonzero)
4473         *dest++ = '0';
4474
4475     /* get decimal, if any */
4476     if(first->strbuf && first->val==numpunct_wchar_decimal_point(numpunct)) {
4477         if(dest < num_end)
4478             *dest++ = *localeconv()->decimal_point;
4479         istreambuf_iterator_wchar_inc(first);
4480     }
4481
4482     /* read non-grouped after decimal */
4483     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4484         if(!(digits_pos = wcschr(digits, first->val)))
4485             break;
4486         else if(dest<num_end) {
4487             got_digit = TRUE;
4488             *dest++ = '0'+digits_pos-digits;
4489         }
4490     }
4491
4492     /* read exponent, if any */
4493     if(first->strbuf && (first->val==mb_to_wc('e', &this->cvt) || first->val==mb_to_wc('E', &this->cvt))) {
4494         *dest++ = 'e';
4495         istreambuf_iterator_wchar_inc(first);
4496
4497         if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4498             *dest++ = '-';
4499             istreambuf_iterator_wchar_inc(first);
4500         }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4501             *dest++ = '+';
4502             istreambuf_iterator_wchar_inc(first);
4503         }
4504
4505         got_digit = got_nonzero = FALSE;
4506         error = TRUE;
4507         /* skip any leading zeroes */
4508         for(; first->strbuf && first->val==digits[0]; istreambuf_iterator_wchar_inc(first))
4509             error = FALSE;
4510
4511         for(; first->strbuf && (digits_pos = wcschr(digits, first->val)); istreambuf_iterator_wchar_inc(first)) {
4512             got_digit = got_nonzero = TRUE; /* leading zeroes would have been skipped, so first digit is non-zero */
4513             error = FALSE;
4514             if(dest<exp_end)
4515                 *dest++ = '0'+digits_pos-digits;
4516         }
4517
4518         /* if just found zeroes for exponent, use that */
4519         if(got_digit && !got_nonzero)
4520         {
4521             error = FALSE;
4522             if(dest<exp_end)
4523                 *dest++ = '0';
4524         }
4525     }
4526
4527     if(sep && groups_no)
4528         MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
4529
4530     if(!cur_group) /* no groups, skip loop */
4531         cur_group--;
4532     else if(!(groups = MSVCP_basic_string_char_c_str(&groups_found))[cur_group])
4533         error = TRUE; /* trailing empty */
4534
4535     for(; cur_group>=0 && !error; cur_group--) {
4536         if(*grouping == CHAR_MAX) {
4537             if(cur_group)
4538                 error = TRUE;
4539             break;
4540         }else if((cur_group && *grouping!=groups[cur_group])
4541                 || (!cur_group && *grouping<groups[cur_group])) {
4542             error = TRUE;
4543             break;
4544         }else if(grouping[1]) {
4545             grouping++;
4546         }
4547     }
4548     MSVCP_basic_string_char_dtor(&grouping_bstr);
4549     if(sep)
4550         MSVCP_basic_string_char_dtor(&groups_found);
4551
4552     if(error) {
4553         *dest_beg = '\0';
4554         return 0;
4555     }
4556     *dest++ = '\0';
4557     return exp;
4558 }
4559
4560 /* ?_Getffld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1ABVlocale@2@@Z */
4561 /* ?_Getffld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1AEBVlocale@2@@Z */
4562 int __cdecl num_get_wchar__Getffld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4563     istreambuf_iterator_wchar *last, const locale *loc)
4564 {
4565     return num_get__Getffld(this, dest, first, last, loc, numpunct_wchar_use_facet(loc));
4566 }
4567
4568 /* ?_Getffld@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1ABVlocale@2@@Z */
4569 /* ?_Getffld@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1AEBVlocale@2@@Z */
4570 int __cdecl num_get_short__Getffld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4571     istreambuf_iterator_wchar *last, const locale *loc)
4572 {
4573     return num_get__Getffld(this, dest, first, last, loc, numpunct_short_use_facet(loc));
4574 }
4575
4576 /* ?_Getffldx@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1AAVios_base@2@PAH@Z */
4577 /* ?_Getffldx@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1AEAVios_base@2@PEAH@Z */
4578 /* ?_Getffldx@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1AAVios_base@2@PAH@Z */
4579 /* ?_Getffldx@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1AEAVios_base@2@PEAH@Z */
4580 int __cdecl num_get_wchar__Getffldx(num_get *this, char *dest, istreambuf_iterator_wchar *first,
4581     istreambuf_iterator_wchar *last, ios_base *ios, int *phexexp)
4582 {
4583     FIXME("(%p %p %p %p %p) stub\n", dest, first, last, ios, phexexp);
4584     return -1;
4585 }
4586
4587 static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4588     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc, numpunct_wchar *numpunct)
4589 {
4590     wchar_t digits[23], *digits_pos, sep;
4591     basic_string_char grouping_bstr;
4592     basic_string_char groups_found;
4593     int i, basefield, base, groups_no = 0, cur_group = 0;
4594     char *dest_beg = dest, *dest_end = dest+24;
4595     const char *grouping, *groups;
4596     BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
4597
4598     TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
4599
4600     for(i=0; i<10; i++)
4601         digits[i] = mb_to_wc('0'+i, &this->cvt);
4602     for(i=0; i<6; i++) {
4603         digits[10+i] = mb_to_wc('a'+i, &this->cvt);
4604         digits[16+i] = mb_to_wc('A'+i, &this->cvt);
4605     }
4606
4607     numpunct_wchar_grouping(numpunct, &grouping_bstr);
4608     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
4609     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
4610
4611     basefield = fmtflags & FMTFLAG_basefield;
4612     if(basefield == FMTFLAG_oct)
4613         base = 8;
4614     else if(basefield == FMTFLAG_hex)
4615         base = 22; /* equal to the size of digits buffer */
4616     else if(!basefield)
4617         base = 0;
4618     else
4619         base = 10;
4620
4621     istreambuf_iterator_wchar_val(first);
4622     if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4623         *dest++ = '-';
4624         istreambuf_iterator_wchar_inc(first);
4625     }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4626         *dest++ = '+';
4627         istreambuf_iterator_wchar_inc(first);
4628     }
4629
4630     if(first->strbuf && first->val==digits[0]) {
4631         found_zero = TRUE;
4632         istreambuf_iterator_wchar_inc(first);
4633         if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('X', &this->cvt))) {
4634             if(!base || base == 22) {
4635                 found_zero = FALSE;
4636                 istreambuf_iterator_wchar_inc(first);
4637                 base = 22;
4638             }else {
4639                 base = 10;
4640             }
4641         }else {
4642             error = FALSE;
4643             if(!base) base = 8;
4644         }
4645     }else {
4646         if(!base) base = 10;
4647     }
4648     digits[base] = 0;
4649
4650     if(sep) {
4651         MSVCP_basic_string_char_ctor(&groups_found);
4652         if(found_zero) ++groups_no;
4653     }
4654
4655     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4656         if(!(digits_pos = wcschr(digits, first->val))) {
4657             if(sep && first->val==sep) {
4658                 if(!groups_no) break; /* empty group - stop parsing */
4659                 MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
4660                 groups_no = 0;
4661                 ++cur_group;
4662             }else {
4663                 break;
4664             }
4665         }else {
4666             error = FALSE;
4667             if(dest_empty && first->val == digits[0]) {
4668                 found_zero = TRUE;
4669                 ++groups_no;
4670                 continue;
4671             }
4672             dest_empty = FALSE;
4673             /* skip digits that can't be copied to dest buffer, other
4674              * functions are responsible for detecting overflows */
4675             if(dest < dest_end)
4676                 *dest++ = (digits_pos-digits<10 ? '0'+digits_pos-digits :
4677                         (digits_pos-digits<16 ? 'a'+digits_pos-digits-10 :
4678                          'A'+digits_pos-digits-16));
4679             if(sep && groups_no<CHAR_MAX)
4680                 ++groups_no;
4681         }
4682     }
4683
4684     if(sep && groups_no)
4685         MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
4686
4687     if(!cur_group) { /* no groups, skip loop */
4688         cur_group--;
4689     }else if(!(groups = MSVCP_basic_string_char_c_str(&groups_found))[cur_group]) {
4690         error = TRUE; /* trailing empty */
4691         found_zero = FALSE;
4692     }
4693
4694     for(; cur_group>=0 && !error; cur_group--) {
4695         if(*grouping == CHAR_MAX) {
4696             if(cur_group)
4697                 error = TRUE;
4698             break;
4699         }else if((cur_group && *grouping!=groups[cur_group])
4700                 || (!cur_group && *grouping<groups[cur_group])) {
4701             error = TRUE;
4702             break;
4703         }else if(grouping[1]) {
4704             grouping++;
4705         }
4706     }
4707
4708     MSVCP_basic_string_char_dtor(&grouping_bstr);
4709     if(sep)
4710         MSVCP_basic_string_char_dtor(&groups_found);
4711
4712     if(error) {
4713         if (found_zero)
4714             *dest++ = '0';
4715         else
4716             dest = dest_beg;
4717     }else if(dest_empty)
4718         *dest++ = '0';
4719     *dest = '\0';
4720
4721     return (base==22 ? 16 : base);
4722 }
4723
4724 /* ?_Getifld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1HABVlocale@2@@Z */
4725 /* ?_Getifld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1HAEBVlocale@2@@Z */
4726 int __cdecl num_get_wchar__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4727     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
4728 {
4729     return num_get__Getifld(this, dest, first, last,
4730             fmtflags, loc, numpunct_wchar_use_facet(loc));
4731 }
4732
4733 /* ?_Getifld@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1HABVlocale@2@@Z */
4734 /* ?_Getifld@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1HAEBVlocale@2@@Z */
4735 int __cdecl num_get_short__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4736     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
4737 {
4738     return num_get__Getifld(this, dest, first, last,
4739             fmtflags, loc, numpunct_short_use_facet(loc));
4740 }
4741
4742 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABEH_W000@Z */
4743 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAH_W000@Z */
4744 /* ?_Hexdig@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABEHGGGG@Z */
4745 /* ?_Hexdig@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHGGGG@Z */
4746 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_wchar__Hexdig, 20)
4747 int __thiscall MSVCP_num_get_wchar__Hexdig(num_get *this, wchar_t dig, wchar_t e0, wchar_t al, wchar_t au)
4748 {
4749     FIXME("(%p %c %c %c %c) stub\n", this, dig, e0, al, au);
4750     return -1;
4751 }
4752
4753 static istreambuf_iterator_wchar* num_get_do_get_void(const num_get *this,
4754         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4755         istreambuf_iterator_wchar last, ios_base *base, int *state,
4756         void **pval, numpunct_wchar *numpunct)
4757 {
4758     unsigned __int64 v;
4759     char tmp[25], *end;
4760     int err;
4761
4762     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4763
4764     v = _Stoullx(tmp, &end, num_get__Getifld(this, tmp, &first,
4765                 &last, FMTFLAG_hex, base->loc, numpunct), &err);
4766     if(v!=(unsigned __int64)((INT_PTR)v))
4767         *state |= IOSTATE_failbit;
4768     else if(end!=tmp && !err)
4769         *pval = (void*)((INT_PTR)v);
4770     else
4771         *state |= IOSTATE_failbit;
4772
4773     if(!first.strbuf)
4774         *state |= IOSTATE_eofbit;
4775
4776     *ret = first;
4777     return ret;
4778 }
4779
4780 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4781 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4782 #define call_num_get_wchar_do_get_void(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 4, istreambuf_iterator_wchar*, \
4783         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, void**), \
4784         (this, ret, first, last, base, state, pval))
4785 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_void,36)
4786 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4787     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4788 {
4789     return num_get_do_get_void(this, ret, first, last, base,
4790             state, pval, numpunct_wchar_use_facet(base->loc));
4791 }
4792
4793 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4794 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4795 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_void,36)
4796 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4797     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4798 {
4799     return num_get_do_get_void(this, ret, first, last, base,
4800             state, pval, numpunct_short_use_facet(base->loc));
4801 }
4802
4803 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4804 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4805 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4806 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4807 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_void,36)
4808 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4809     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4810 {
4811     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4812     return call_num_get_wchar_do_get_void(this, ret, first, last, base, state, pval);
4813 }
4814
4815 static istreambuf_iterator_wchar* num_get_do_get_double(const num_get *this,
4816         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4817         istreambuf_iterator_wchar last, ios_base *base, int *state,
4818         double *pval, numpunct_wchar *numpunct)
4819 {
4820     double v;
4821     char tmp[32], *end;
4822     int err;
4823
4824     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4825
4826     v = _Stodx(tmp, &end, num_get__Getffld(this, tmp, &first, &last, base->loc, numpunct), &err);
4827     if(end!=tmp && !err)
4828         *pval = v;
4829     else
4830         *state |= IOSTATE_failbit;
4831
4832     if(!first.strbuf)
4833         *state |= IOSTATE_eofbit;
4834
4835     *ret = first;
4836     return ret;
4837 }
4838
4839 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4840 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4841 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4842 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4843 #define call_num_get_wchar_do_get_ldouble(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 8, istreambuf_iterator_wchar*, \
4844         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, double*), \
4845         (this, ret, first, last, base, state, pval))
4846 #define call_num_get_wchar_do_get_double(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 12, istreambuf_iterator_wchar*, \
4847         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, double*), \
4848         (this, ret, first, last, base, state, pval))
4849 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_double,36)
4850 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4851     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4852 {
4853     return num_get_do_get_double(this, ret, first, last, base,
4854             state, pval, numpunct_wchar_use_facet(base->loc));
4855 }
4856
4857 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4858 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4859 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4860 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4861 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_double,36)
4862 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4863     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4864 {
4865     return num_get_do_get_double(this, ret, first, last, base,
4866             state, pval, numpunct_short_use_facet(base->loc));
4867 }
4868
4869 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4870 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4871 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4872 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4873 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ldouble,36)
4874 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ldouble(const num_get *this, istreambuf_iterator_wchar *ret,
4875         istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4876 {
4877     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4878     return call_num_get_wchar_do_get_ldouble(this, ret, first, last, base, state, pval);
4879 }
4880
4881 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4882 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4883 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4884 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4885 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_double,36)
4886 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4887     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4888 {
4889     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4890     return call_num_get_wchar_do_get_double(this, ret, first, last, base, state, pval);
4891 }
4892
4893 static istreambuf_iterator_wchar* num_get_do_get_float(const num_get *this,
4894         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4895         istreambuf_iterator_wchar last, ios_base *base, int *state,
4896         float *pval, numpunct_wchar *numpunct)
4897 {
4898     float v;
4899     char tmp[32], *end;
4900     int err;
4901
4902     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4903
4904     v = _Stofx(tmp, &end, num_get__Getffld(this, tmp, &first,
4905                 &last, base->loc, numpunct), &err);
4906     if(end!=tmp && !err)
4907         *pval = v;
4908     else
4909         *state |= IOSTATE_failbit;
4910
4911     if(!first.strbuf)
4912         *state |= IOSTATE_eofbit;
4913
4914     *ret = first;
4915     return ret;
4916 }
4917
4918 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4919 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4920 #define call_num_get_wchar_do_get_float(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 16, istreambuf_iterator_wchar*, \
4921         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, float*), \
4922         (this, ret, first, last, base, state, pval))
4923 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_float,36)
4924 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4925     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4926 {
4927     return num_get_do_get_float(this, ret, first, last, base,
4928             state, pval, numpunct_wchar_use_facet(base->loc));
4929 }
4930
4931 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4932 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4933 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_float,36)
4934 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4935     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4936 {
4937     return num_get_do_get_float(this, ret, first, last, base,
4938             state, pval, numpunct_short_use_facet(base->loc));
4939 }
4940
4941 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4942 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4943 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4944 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4945 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_float,36)
4946 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4947     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4948 {
4949     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4950     return call_num_get_wchar_do_get_float(this, ret, first, last, base, state, pval);
4951 }
4952
4953 static istreambuf_iterator_wchar* num_get_do_get_uint64(const num_get *this,
4954         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4955         istreambuf_iterator_wchar last, ios_base *base, int *state,
4956         ULONGLONG *pval, numpunct_wchar *numpunct)
4957 {
4958     unsigned __int64 v;
4959     char tmp[25], *end;
4960     int err;
4961
4962     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4963
4964     v = _Stoullx(tmp, &end, num_get__Getifld(this, tmp, &first,
4965                 &last, base->fmtfl, base->loc, numpunct), &err);
4966     if(end!=tmp && !err)
4967         *pval = v;
4968     else
4969         *state |= IOSTATE_failbit;
4970
4971     if(!first.strbuf)
4972         *state |= IOSTATE_eofbit;
4973
4974     *ret = first;
4975     return ret;
4976 }
4977
4978 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
4979 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
4980 #define call_num_get_wchar_do_get_uint64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 20, istreambuf_iterator_wchar*, \
4981         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, ULONGLONG*), \
4982         (this, ret, first, last, base, state, pval))
4983 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint64,36)
4984 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
4985     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
4986 {
4987     return num_get_do_get_uint64(this, ret, first, last, base,
4988             state, pval, numpunct_wchar_use_facet(base->loc));
4989 }
4990
4991 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
4992 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
4993 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_uint64,36)
4994 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
4995     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
4996 {
4997     return num_get_do_get_uint64(this, ret, first, last, base,
4998             state, pval, numpunct_short_use_facet(base->loc));
4999 }
5000
5001 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
5002 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
5003 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
5004 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
5005 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint64,36)
5006 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
5007     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
5008 {
5009     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5010     return call_num_get_wchar_do_get_uint64(this, ret, first, last, base, state, pval);
5011 }
5012
5013 static istreambuf_iterator_wchar* num_get_do_get_int64(const num_get *this,
5014         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5015         istreambuf_iterator_wchar last, ios_base *base, int *state,
5016         LONGLONG *pval, numpunct_wchar *numpunct)
5017 {
5018     __int64 v;
5019     char tmp[25], *end;
5020     int err;
5021
5022     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5023
5024     v = _Stollx(tmp, &end, num_get__Getifld(this, tmp, &first,
5025                 &last, base->fmtfl, base->loc, numpunct), &err);
5026     if(end!=tmp && !err)
5027         *pval = v;
5028     else
5029         *state |= IOSTATE_failbit;
5030
5031     if(!first.strbuf)
5032         *state |= IOSTATE_eofbit;
5033
5034     *ret = first;
5035     return ret;
5036 }
5037
5038 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
5039 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
5040 #define call_num_get_wchar_do_get_int64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 24, istreambuf_iterator_wchar*, \
5041         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, LONGLONG*), \
5042         (this, ret, first, last, base, state, pval))
5043 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_int64,36)
5044 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
5045     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
5046 {
5047     return num_get_do_get_int64(this, ret, first, last, base,
5048             state, pval, numpunct_wchar_use_facet(base->loc));
5049 }
5050
5051 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
5052 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
5053 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_int64,36)
5054 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
5055     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
5056 {
5057     return num_get_do_get_int64(this, ret, first, last, base,
5058             state, pval, numpunct_short_use_facet(base->loc));
5059 }
5060
5061 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
5062 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
5063 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
5064 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
5065 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_int64,36)
5066 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
5067     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
5068 {
5069     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5070     return call_num_get_wchar_do_get_int64(this, ret, first, last, base, state, pval);
5071 }
5072
5073 static istreambuf_iterator_wchar* num_get_do_get_ulong(const num_get *this,
5074         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5075         istreambuf_iterator_wchar last, ios_base *base, int *state,
5076         ULONG *pval, numpunct_wchar *numpunct)
5077 {
5078     ULONG v;
5079     char tmp[25], *end;
5080     int err;
5081
5082     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5083
5084     v = _Stoulx(tmp, &end, num_get__Getifld(this, tmp, &first,
5085                 &last, base->fmtfl, base->loc, numpunct), &err);
5086     if(end!=tmp && !err)
5087         *pval = v;
5088     else
5089         *state |= IOSTATE_failbit;
5090
5091     if(!first.strbuf)
5092         *state |= IOSTATE_eofbit;
5093
5094     *ret = first;
5095     return ret;
5096 }
5097
5098 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
5099 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
5100 #define call_num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 28, istreambuf_iterator_wchar*, \
5101         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, ULONG*), \
5102         (this, ret, first, last, base, state, pval))
5103 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ulong,36)
5104 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
5105     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
5106 {
5107     return num_get_do_get_ulong(this, ret, first, last, base,
5108             state, pval, numpunct_wchar_use_facet(base->loc));
5109 }
5110
5111 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
5112 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
5113 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_ulong,36)
5114 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
5115     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
5116 {
5117     return num_get_do_get_ulong(this, ret, first, last, base,
5118             state, pval, numpunct_short_use_facet(base->loc));
5119 }
5120
5121 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
5122 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
5123 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
5124 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
5125 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ulong,36)
5126 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
5127     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
5128 {
5129     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5130     return call_num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval);
5131 }
5132
5133 static istreambuf_iterator_wchar* num_get_do_get_long(const num_get *this,
5134         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5135         istreambuf_iterator_wchar last, ios_base *base, int *state,
5136         LONG *pval, numpunct_wchar *numpunct)
5137 {
5138     LONG v;
5139     char tmp[25], *end;
5140     int err;
5141
5142     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5143
5144     v = _Stolx(tmp, &end, num_get__Getifld(this, tmp, &first,
5145                 &last, base->fmtfl, base->loc, numpunct), &err);
5146     if(end!=tmp && !err)
5147         *pval = v;
5148     else
5149         *state |= IOSTATE_failbit;
5150
5151     if(!first.strbuf)
5152         *state |= IOSTATE_eofbit;
5153
5154     *ret = first;
5155     return ret;
5156 }
5157
5158 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
5159 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
5160 #define call_num_get_wchar_do_get_long(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 32, istreambuf_iterator_wchar*, \
5161         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, LONG*), \
5162         (this, ret, first, last, base, state, pval))
5163 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_long,36)
5164 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
5165     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
5166 {
5167     return num_get_do_get_long(this, ret, first, last, base,
5168             state, pval, numpunct_wchar_use_facet(base->loc));
5169 }
5170
5171 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
5172 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
5173 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_long,36)
5174 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
5175     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
5176 {
5177     return num_get_do_get_long(this, ret, first, last, base,
5178         state, pval, numpunct_short_use_facet(base->loc));
5179 }
5180
5181 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
5182 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
5183 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
5184 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
5185 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_long,36)
5186 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
5187     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
5188 {
5189     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5190     return call_num_get_wchar_do_get_long(this, ret, first, last, base, state, pval);
5191 }
5192
5193 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
5194 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
5195 #define call_num_get_wchar_do_get_uint(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 36, istreambuf_iterator_wchar*, \
5196         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, unsigned int*), \
5197         (this, ret, first, last, base, state, pval))
5198 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint,36)
5199 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
5200     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
5201 {
5202     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5203     return num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval);
5204 }
5205
5206 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
5207 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
5208 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_uint,36)
5209 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
5210     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
5211 {
5212     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5213     return num_get_short_do_get_ulong(this, ret, first, last, base, state, pval);
5214 }
5215
5216 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
5217 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
5218 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
5219 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
5220 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint,36)
5221 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
5222     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
5223 {
5224     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5225     return call_num_get_wchar_do_get_uint(this, ret, first, last, base, state, pval);
5226 }
5227
5228 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
5229 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
5230 #define call_num_get_wchar_do_get_ushort(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 40, istreambuf_iterator_wchar*, \
5231         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, unsigned short*), \
5232         (this, ret, first, last, base, state, pval))
5233 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ushort,36)
5234 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
5235     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
5236 {
5237     ULONG v;
5238     char tmp[25], *beg, *end;
5239     int err, b;
5240
5241     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5242
5243     b = num_get_wchar__Getifld(this, tmp,
5244             &first, &last, base->fmtfl, base->loc);
5245     beg = tmp + (tmp[0]=='-' ? 1 : 0);
5246     v = _Stoulx(beg, &end, b, &err);
5247
5248     if(v != (ULONG)((unsigned short)v))
5249         *state |= IOSTATE_failbit;
5250     else if(end!=beg && !err)
5251         *pval = (tmp[0]=='-' ? -((unsigned short)v) : v);
5252     else
5253         *state |= IOSTATE_failbit;
5254
5255     if(!first.strbuf)
5256         *state |= IOSTATE_eofbit;
5257
5258     *ret = first;
5259     return ret;
5260 }
5261
5262 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
5263 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
5264 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_ushort,36)
5265 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
5266     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
5267 {
5268     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
5269     return ret;
5270 }
5271
5272 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
5273 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
5274 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAG@ */
5275 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
5276 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ushort,36)
5277 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
5278     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
5279 {
5280     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5281     return call_num_get_wchar_do_get_ushort(this, ret, first, last, base, state, pval);
5282 }
5283
5284 static istreambuf_iterator_wchar* num_get_do_get_bool(const num_get *this,
5285         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5286         istreambuf_iterator_wchar last, ios_base *base, int *state,
5287         MSVCP_bool *pval, numpunct_wchar *numpunct)
5288 {
5289     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5290
5291     if(base->fmtfl & FMTFLAG_boolalpha) {
5292         basic_string_wchar false_bstr, true_bstr;
5293         const wchar_t *pfalse, *ptrue;
5294
5295         numpunct_wchar_falsename(numpunct, &false_bstr);
5296         numpunct_wchar_truename(numpunct, &true_bstr);
5297         pfalse = MSVCP_basic_string_wchar_c_str(&false_bstr);
5298         ptrue = MSVCP_basic_string_wchar_c_str(&true_bstr);
5299
5300         for(istreambuf_iterator_wchar_val(&first); first.strbuf;
5301                 istreambuf_iterator_wchar_inc(&first)) {
5302             if(pfalse && *pfalse && first.val!=*pfalse)
5303                 pfalse = NULL;
5304             if(ptrue && *ptrue && first.val!=*ptrue)
5305                 ptrue = NULL;
5306
5307             if(pfalse && *pfalse && ptrue && !*ptrue)
5308                 ptrue = NULL;
5309             if(ptrue && *ptrue && pfalse && !*pfalse)
5310                 pfalse = NULL;
5311
5312             if(pfalse)
5313                 pfalse++;
5314             if(ptrue)
5315                 ptrue++;
5316
5317             if((!pfalse || !*pfalse) && (!ptrue || !*ptrue))
5318                 break;
5319         }
5320
5321         if(ptrue)
5322             *pval = TRUE;
5323         else if(pfalse)
5324             *pval = FALSE;
5325         else
5326             *state |= IOSTATE_failbit;
5327
5328         MSVCP_basic_string_wchar_dtor(&false_bstr);
5329         MSVCP_basic_string_wchar_dtor(&true_bstr);
5330     }else {
5331         char tmp[25], *end;
5332         int err;
5333         LONG v = _Stolx(tmp, &end, num_get__Getifld(this, tmp, &first,
5334                     &last, base->fmtfl, base->loc, numpunct), &err);
5335
5336         if(end!=tmp && err==0 && (v==0 || v==1))
5337             *pval = v;
5338         else
5339             *state |= IOSTATE_failbit;
5340     }
5341
5342     if(!first.strbuf)
5343         *state |= IOSTATE_eofbit;
5344     memcpy(ret, &first, sizeof(first));
5345     return ret;
5346 }
5347
5348 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
5349 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
5350 #define call_num_get_wchar_do_get_bool(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 44, istreambuf_iterator_wchar*, \
5351         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, MSVCP_bool*), \
5352         (this, ret, first, last, base, state, pval))
5353 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_bool,36)
5354 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
5355     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
5356 {
5357     return num_get_do_get_bool(this, ret, first, last, base,
5358             state, pval, numpunct_wchar_use_facet(base->loc));
5359 }
5360
5361 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
5362 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
5363 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_bool,36)
5364 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
5365     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
5366 {
5367     return num_get_do_get_bool(this, ret, first, last, base,
5368             state, pval, numpunct_short_use_facet(base->loc));
5369 }
5370
5371 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
5372 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
5373 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
5374 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
5375 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_bool,36)
5376 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
5377     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
5378 {
5379     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5380     return call_num_get_wchar_do_get_bool(this, ret, first, last, base, state, pval);
5381 }
5382
5383 /* ?id@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
5384 locale_id num_get_char_id = {0};
5385
5386 /* ??_7?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
5387 extern const vtable_ptr MSVCP_num_get_char_vtable;
5388
5389 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
5390 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
5391 DEFINE_THISCALL_WRAPPER(num_get_char__Init, 8)
5392 void __thiscall num_get_char__Init(num_get *this, const _Locinfo *locinfo)
5393 {
5394     TRACE("(%p %p)\n", this, locinfo);
5395     _Locinfo__Getcvt(locinfo, &this->cvt);
5396 }
5397
5398 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
5399 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
5400 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_locinfo, 12)
5401 num_get* __thiscall num_get_char_ctor_locinfo(num_get *this,
5402         const _Locinfo *locinfo, MSVCP_size_t refs)
5403 {
5404     TRACE("(%p %p %lu)\n", this, locinfo, refs);
5405
5406     locale_facet_ctor_refs(&this->facet, refs);
5407     this->facet.vtable = &MSVCP_num_get_char_vtable;
5408
5409     num_get_char__Init(this, locinfo);
5410     return this;
5411 }
5412
5413 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
5414 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
5415 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_refs, 8)
5416 num_get* __thiscall num_get_char_ctor_refs(num_get *this, MSVCP_size_t refs)
5417 {
5418     _Locinfo locinfo;
5419
5420     TRACE("(%p %lu)\n", this, refs);
5421
5422     _Locinfo_ctor(&locinfo);
5423     num_get_char_ctor_locinfo(this, &locinfo, refs);
5424     _Locinfo_dtor(&locinfo);
5425     return this;
5426 }
5427
5428 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
5429 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
5430 DEFINE_THISCALL_WRAPPER(num_get_char_ctor, 4)
5431 num_get* __thiscall num_get_char_ctor(num_get *this)
5432 {
5433     return num_get_char_ctor_refs(this, 0);
5434 }
5435
5436 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
5437 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
5438 DEFINE_THISCALL_WRAPPER(num_get_char_dtor, 4)
5439 void __thiscall num_get_char_dtor(num_get *this)
5440 {
5441     TRACE("(%p)\n", this);
5442     locale_facet_dtor(&this->facet);
5443 }
5444
5445 DEFINE_THISCALL_WRAPPER(num_get_char_vector_dtor, 8)
5446 num_get* __thiscall num_get_char_vector_dtor(num_get *this, unsigned int flags)
5447 {
5448     TRACE("(%p %x)\n", this, flags);
5449     if(flags & 2) {
5450         /* we have an array, with the number of elements stored before the first object */
5451         INT_PTR i, *ptr = (INT_PTR *)this-1;
5452
5453         for(i=*ptr-1; i>=0; i--)
5454             num_get_char_dtor(this+i);
5455         MSVCRT_operator_delete(ptr);
5456     } else {
5457         num_get_char_dtor(this);
5458         if(flags & 1)
5459             MSVCRT_operator_delete(this);
5460     }
5461
5462     return this;
5463 }
5464
5465 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
5466 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
5467 MSVCP_size_t __cdecl num_get_char__Getcat(const locale_facet **facet, const locale *loc)
5468 {
5469     TRACE("(%p %p)\n", facet, loc);
5470
5471     if(facet && !*facet) {
5472         _Locinfo locinfo;
5473
5474         *facet = MSVCRT_operator_new(sizeof(num_get));
5475         if(!*facet) {
5476             ERR("Out of memory\n");
5477             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
5478             return 0;
5479         }
5480
5481         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
5482         num_get_char_ctor_locinfo((num_get*)*facet, &locinfo, 0);
5483         _Locinfo_dtor(&locinfo);
5484     }
5485
5486     return LC_NUMERIC;
5487 }
5488
5489 num_get* num_get_char_use_facet(const locale *loc)
5490 {
5491     static num_get *obj = NULL;
5492
5493     _Lockit lock;
5494     const locale_facet *fac;
5495
5496     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
5497     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_char_id));
5498     if(fac) {
5499         _Lockit_dtor(&lock);
5500         return (num_get*)fac;
5501     }
5502
5503     if(obj) {
5504         _Lockit_dtor(&lock);
5505         return obj;
5506     }
5507
5508     num_get_char__Getcat(&fac, loc);
5509     obj = (num_get*)fac;
5510     locale_facet__Incref(&obj->facet);
5511     locale_facet_register(&obj->facet);
5512     _Lockit_dtor(&lock);
5513
5514     return obj;
5515 }
5516
5517 /* ?_Getffld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1ABVlocale@2@@Z */
5518 /* ?_Getffld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1AEBVlocale@2@@Z */
5519 /* Copies number to dest buffer, validates grouping and skips separators.
5520  * Updates first so it points past the number, all digits are skipped.
5521  * Returns how exponent needs to changed.
5522  * Size of dest buffer is not specified, assuming it's not smaller than 32:
5523  * strlen(+0.e+) + 22(digits) + 4(expontent) + 1(nullbyte)
5524  */
5525 int __cdecl num_get_char__Getffld(const num_get *this, char *dest, istreambuf_iterator_char *first,
5526         istreambuf_iterator_char *last, const locale *loc)
5527 {
5528     numpunct_char *numpunct = numpunct_char_use_facet(loc);
5529     basic_string_char grouping_bstr;
5530     basic_string_char groups_found;
5531     int groups_no = 0, cur_group = 0, exp = 0;
5532     char *dest_beg = dest, *num_end = dest+25, *exp_end = dest+31, sep;
5533     const char *grouping, *groups;
5534     BOOL error = FALSE, got_digit = FALSE, got_nonzero = FALSE;
5535
5536     TRACE("(%p %p %p %p)\n", dest, first, last, loc);
5537
5538     numpunct_char_grouping(numpunct, &grouping_bstr);
5539     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
5540     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
5541
5542     if(sep)
5543         MSVCP_basic_string_char_ctor(&groups_found);
5544
5545     istreambuf_iterator_char_val(first);
5546     /* get sign */
5547     if(first->strbuf && (first->val=='-' || first->val=='+')) {
5548         *dest++ = first->val;
5549         istreambuf_iterator_char_inc(first);
5550     }
5551
5552     /* read possibly grouped numbers before decimal */
5553     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5554         if(first->val<'0' || first->val>'9') {
5555             if(sep && first->val==sep) {
5556                 if(!groups_no) break; /* empty group - stop parsing */
5557                 MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
5558                 groups_no = 0;
5559                 ++cur_group;
5560             }else {
5561                 break;
5562             }
5563         }else {
5564             got_digit = TRUE; /* found a digit, zero or non-zero */
5565             /* write digit to dest if not a leading zero (to not waste dest buffer) */
5566             if(!got_nonzero && first->val == '0')
5567             {
5568                 ++groups_no;
5569                 continue;
5570             }
5571             got_nonzero = TRUE;
5572             if(dest < num_end)
5573                 *dest++ = first->val;
5574             else
5575                 exp++; /* too many digits, just multiply by 10 */
5576             if(sep && groups_no<CHAR_MAX)
5577                 ++groups_no;
5578         }
5579     }
5580
5581     /* if all leading zeroes, we didn't write anything so put a zero we check for a decimal */
5582     if(got_digit && !got_nonzero)
5583         *dest++ = '0';
5584
5585     /* get decimal, if any */
5586     if(first->strbuf && first->val==numpunct_char_decimal_point(numpunct)) {
5587         if(dest < num_end)
5588             *dest++ = *localeconv()->decimal_point;
5589         istreambuf_iterator_char_inc(first);
5590     }
5591
5592     /* read non-grouped after decimal */
5593     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5594         if(first->val<'0' || first->val>'9')
5595             break;
5596         else if(dest<num_end) {
5597             got_digit = TRUE;
5598             *dest++ = first->val;
5599         }
5600     }
5601
5602     /* read exponent, if any */
5603     if(first->strbuf && (first->val=='e' || first->val=='E')) {
5604         *dest++ = first->val;
5605         istreambuf_iterator_char_inc(first);
5606
5607         if(first->strbuf && (first->val=='-' || first->val=='+')) {
5608             *dest++ = first->val;
5609             istreambuf_iterator_char_inc(first);
5610         }
5611
5612         got_digit = got_nonzero = FALSE;
5613         error = TRUE;
5614         /* skip any leading zeroes */
5615         for(; first->strbuf && first->val=='0'; istreambuf_iterator_char_inc(first))
5616             got_digit = TRUE;
5617
5618         for(; first->strbuf && first->val>='0' && first->val<='9'; istreambuf_iterator_char_inc(first)) {
5619             got_digit = got_nonzero = TRUE; /* leading zeroes would have been skipped, so first digit is non-zero */
5620             error = FALSE;
5621             if(dest<exp_end)
5622                 *dest++ = first->val;
5623         }
5624
5625         /* if just found zeroes for exponent, use that */
5626         if(got_digit && !got_nonzero)
5627         {
5628             error = FALSE;
5629             if(dest<exp_end)
5630                 *dest++ = '0';
5631         }
5632     }
5633
5634     if(sep && groups_no)
5635         MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
5636
5637     if(!cur_group) /* no groups, skip loop */
5638         cur_group--;
5639     else if(!(groups = MSVCP_basic_string_char_c_str(&groups_found))[cur_group])
5640         error = TRUE; /* trailing empty */
5641
5642     for(; cur_group>=0 && !error; cur_group--) {
5643         if(*grouping == CHAR_MAX) {
5644             if(cur_group)
5645                 error = TRUE;
5646             break;
5647         }else if((cur_group && *grouping!=groups[cur_group])
5648                 || (!cur_group && *grouping<groups[cur_group])) {
5649             error = TRUE;
5650             break;
5651         }else if(grouping[1]) {
5652             grouping++;
5653         }
5654     }
5655     MSVCP_basic_string_char_dtor(&grouping_bstr);
5656     if(sep)
5657         MSVCP_basic_string_char_dtor(&groups_found);
5658
5659     if(error) {
5660         *dest_beg = '\0';
5661         return 0;
5662     }
5663     *dest++ = '\0';
5664     return exp;
5665 }
5666
5667 /* ?_Getffldx@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1AAVios_base@2@PAH@Z */
5668 /* ?_Getffldx@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1AEAVios_base@2@PEAH@Z */
5669 int __cdecl num_get_char__Getffldx(const num_get *this, char *dest, istreambuf_iterator_char *first,
5670     istreambuf_iterator_char *last, ios_base *ios, int *phexexp)
5671 {
5672     FIXME("(%p %p %p %p %p) stub\n", dest, first, last, ios, phexexp);
5673     return -1;
5674 }
5675
5676 /* ?_Getifld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1HABVlocale@2@@Z */
5677 /* ?_Getifld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1HAEBVlocale@2@@Z */
5678 /* Copies number to dest buffer, validates grouping and skips separators.
5679  * Updates first so it points past the number, all digits are skipped.
5680  * Returns number base (8, 10 or 16).
5681  * Size of dest buffer is not specified, assuming it's not smaller than 25:
5682  * 22(8^22>2^64)+1(detect overflows)+1(sign)+1(nullbyte) = 25
5683  */
5684 int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_iterator_char *first,
5685         istreambuf_iterator_char *last, int fmtflags, const locale *loc)
5686 {
5687     static const char digits[] = "0123456789abcdefABCDEF";
5688
5689     numpunct_char *numpunct = numpunct_char_use_facet(loc);
5690     basic_string_char grouping_bstr;
5691     basic_string_char groups_found;
5692     int basefield, base, groups_no = 0, cur_group = 0;
5693     char *dest_beg = dest, *dest_end = dest+24, sep;
5694     const char *grouping, *groups;
5695     BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
5696
5697     TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
5698
5699     numpunct_char_grouping(numpunct, &grouping_bstr);
5700     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
5701     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
5702
5703     basefield = fmtflags & FMTFLAG_basefield;
5704     if(basefield == FMTFLAG_oct)
5705         base = 8;
5706     else if(basefield == FMTFLAG_hex)
5707         base = 22; /* equal to the size of digits buffer */
5708     else if(!basefield)
5709         base = 0;
5710     else
5711         base = 10;
5712
5713     istreambuf_iterator_char_val(first);
5714     if(first->strbuf && (first->val=='-' || first->val=='+')) {
5715         *dest++ = first->val;
5716         istreambuf_iterator_char_inc(first);
5717     }
5718
5719     if(first->strbuf && first->val=='0') {
5720         found_zero = TRUE;
5721         istreambuf_iterator_char_inc(first);
5722         if(first->strbuf && (first->val=='x' || first->val=='X')) {
5723             if(!base || base == 22) {
5724                 found_zero = FALSE;
5725                 istreambuf_iterator_char_inc(first);
5726                 base = 22;
5727             }else {
5728                 base = 10;
5729             }
5730         }else {
5731             error = FALSE;
5732             if(!base) base = 8;
5733         }
5734     }else {
5735         if (!base) base = 10;
5736     }
5737
5738     if(sep)
5739     {
5740         MSVCP_basic_string_char_ctor(&groups_found);
5741         if(found_zero) ++groups_no;
5742     }
5743
5744     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5745         if(!memchr(digits, first->val, base)) {
5746             if(sep && first->val==sep) {
5747                 if(!groups_no) break; /* empty group - stop parsing */
5748                 MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
5749                 groups_no = 0;
5750                 ++cur_group;
5751             }else {
5752                 break;
5753             }
5754         }else {
5755             error = FALSE;
5756             if(dest_empty && first->val == '0')
5757             {
5758                 found_zero = TRUE;
5759                 ++groups_no;
5760                 continue;
5761             }
5762             dest_empty = FALSE;
5763             /* skip digits that can't be copied to dest buffer, other
5764              * functions are responsible for detecting overflows */
5765             if(dest < dest_end)
5766                 *dest++ = first->val;
5767             if(sep && groups_no<CHAR_MAX)
5768                 ++groups_no;
5769         }
5770     }
5771
5772     if(sep && groups_no)
5773         MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
5774
5775     if(!cur_group) { /* no groups, skip loop */
5776         cur_group--;
5777     }else if(!(groups = MSVCP_basic_string_char_c_str(&groups_found))[cur_group]) {
5778         error = TRUE; /* trailing empty */
5779         found_zero = FALSE;
5780     }
5781
5782     for(; cur_group>=0 && !error; cur_group--) {
5783         if(*grouping == CHAR_MAX) {
5784             if(cur_group)
5785                 error = TRUE;
5786             break;
5787         }else if((cur_group && *grouping!=groups[cur_group])
5788                 || (!cur_group && *grouping<groups[cur_group])) {
5789             error = TRUE;
5790             break;
5791         }else if(grouping[1]) {
5792             grouping++;
5793         }
5794     }
5795
5796     MSVCP_basic_string_char_dtor(&grouping_bstr);
5797     if(sep)
5798         MSVCP_basic_string_char_dtor(&groups_found);
5799
5800     if(error) {
5801         if (found_zero)
5802             *dest++ = '0';
5803         else
5804             dest = dest_beg;
5805     }else if(dest_empty)
5806         *dest++ = '0';
5807     *dest = '\0';
5808
5809     return (base==22 ? 16 : base);
5810 }
5811
5812 /* ?_Hexdig@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABEHD000@Z */
5813 /* ?_Hexdig@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHD000@Z */
5814 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_char__Hexdig, 20)
5815 int __thiscall MSVCP_num_get_char__Hexdig(num_get *this, char dig, char e0, char al, char au)
5816 {
5817     FIXME("(%p %c %c %c %c) stub\n", this, dig, e0, al, au);
5818     return -1;
5819 }
5820
5821 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
5822 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
5823 #define call_num_get_char_do_get_void(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 4, istreambuf_iterator_char*, \
5824         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, void**), \
5825         (this, ret, first, last, base, state, pval))
5826 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_void,36)
5827 istreambuf_iterator_char *__thiscall num_get_char_do_get_void(const num_get *this, istreambuf_iterator_char *ret,
5828     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
5829 {
5830     unsigned __int64 v;
5831     char tmp[25], *end;
5832     int err;
5833
5834     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5835
5836     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
5837                 &first, &last, FMTFLAG_hex, base->loc), &err);
5838     if(v!=(unsigned __int64)((INT_PTR)v))
5839         *state |= IOSTATE_failbit;
5840     else if(end!=tmp && !err)
5841         *pval = (void*)((INT_PTR)v);
5842     else
5843         *state |= IOSTATE_failbit;
5844
5845     if(!first.strbuf)
5846         *state |= IOSTATE_eofbit;
5847
5848     *ret = first;
5849     return ret;
5850 }
5851
5852 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
5853 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
5854 DEFINE_THISCALL_WRAPPER(num_get_char_get_void,36)
5855 istreambuf_iterator_char *__thiscall num_get_char_get_void(const num_get *this, istreambuf_iterator_char *ret,
5856     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
5857 {
5858     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5859     return call_num_get_char_do_get_void(this, ret, first, last, base, state, pval);
5860 }
5861
5862 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
5863 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
5864 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
5865 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
5866 #define call_num_get_char_do_get_ldouble(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 8, istreambuf_iterator_char*, \
5867         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
5868         (this, ret, first, last, base, state, pval))
5869 #define call_num_get_char_do_get_double(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 12, istreambuf_iterator_char*, \
5870         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
5871         (this, ret, first, last, base, state, pval))
5872 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_double,36)
5873 istreambuf_iterator_char *__thiscall num_get_char_do_get_double(const num_get *this, istreambuf_iterator_char *ret,
5874     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5875 {
5876     double v;
5877     char tmp[32], *end;
5878     int err;
5879
5880     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5881
5882     v = _Stodx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
5883     if(end!=tmp && !err)
5884         *pval = v;
5885     else
5886         *state |= IOSTATE_failbit;
5887
5888     if(!first.strbuf)
5889         *state |= IOSTATE_eofbit;
5890
5891     *ret = first;
5892     return ret;
5893 }
5894
5895 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
5896 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
5897 DEFINE_THISCALL_WRAPPER(num_get_char_get_ldouble,36)
5898 istreambuf_iterator_char *__thiscall num_get_char_get_ldouble(const num_get *this, istreambuf_iterator_char *ret,
5899         istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5900 {
5901     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5902     return call_num_get_char_do_get_ldouble(this, ret, first, last, base, state, pval);
5903 }
5904
5905 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
5906 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
5907 DEFINE_THISCALL_WRAPPER(num_get_char_get_double,36)
5908 istreambuf_iterator_char *__thiscall num_get_char_get_double(const num_get *this, istreambuf_iterator_char *ret,
5909     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5910 {
5911     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5912     return call_num_get_char_do_get_double(this, ret, first, last, base, state, pval);
5913 }
5914
5915 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
5916 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
5917 #define call_num_get_char_do_get_float(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 16, istreambuf_iterator_char*, \
5918         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, float*), \
5919         (this, ret, first, last, base, state, pval))
5920 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_float,36)
5921 istreambuf_iterator_char *__thiscall num_get_char_do_get_float(const num_get *this, istreambuf_iterator_char *ret,
5922     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
5923 {
5924     float v;
5925     char tmp[32], *end;
5926     int err;
5927
5928     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5929
5930     v = _Stofx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
5931     if(end!=tmp && !err)
5932         *pval = v;
5933     else
5934         *state |= IOSTATE_failbit;
5935
5936     if(!first.strbuf)
5937         *state |= IOSTATE_eofbit;
5938
5939     *ret = first;
5940     return ret;
5941 }
5942
5943 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
5944 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
5945 DEFINE_THISCALL_WRAPPER(num_get_char_get_float,36)
5946 istreambuf_iterator_char *__thiscall num_get_char_get_float(const num_get *this, istreambuf_iterator_char *ret,
5947     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
5948 {
5949     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5950     return call_num_get_char_do_get_float(this, ret, first, last, base, state, pval);
5951 }
5952
5953 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
5954 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
5955 #define call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 20, istreambuf_iterator_char*, \
5956         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONGLONG*), \
5957         (this, ret, first, last, base, state, pval))
5958 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint64,36)
5959 istreambuf_iterator_char *__thiscall num_get_char_do_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5960     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5961 {
5962     unsigned __int64 v;
5963     char tmp[25], *end;
5964     int err;
5965
5966     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5967
5968     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
5969                 &first, &last, base->fmtfl, base->loc), &err);
5970     if(end!=tmp && !err)
5971         *pval = v;
5972     else
5973         *state |= IOSTATE_failbit;
5974
5975     if(!first.strbuf)
5976         *state |= IOSTATE_eofbit;
5977
5978     *ret = first;
5979     return ret;
5980 }
5981
5982 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
5983 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
5984 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint64,36)
5985 istreambuf_iterator_char *__thiscall num_get_char_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5986     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5987 {
5988     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5989     return call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval);
5990 }
5991
5992 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
5993 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
5994 #define call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 24, istreambuf_iterator_char*, \
5995         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONGLONG*), \
5996         (this, ret, first, last, base, state, pval))
5997 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_int64,36)
5998 istreambuf_iterator_char *__thiscall num_get_char_do_get_int64(const num_get *this, istreambuf_iterator_char *ret,
5999     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
6000 {
6001     __int64 v;
6002     char tmp[25], *end;
6003     int err;
6004
6005     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6006
6007     v = _Stollx(tmp, &end, num_get_char__Getifld(this, tmp,
6008                 &first, &last, base->fmtfl, base->loc), &err);
6009     if(end!=tmp && !err)
6010         *pval = v;
6011     else
6012         *state |= IOSTATE_failbit;
6013
6014     if(!first.strbuf)
6015         *state |= IOSTATE_eofbit;
6016
6017     *ret = first;
6018     return ret;
6019 }
6020
6021 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
6022 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
6023 DEFINE_THISCALL_WRAPPER(num_get_char_get_int64,36)
6024 istreambuf_iterator_char *__thiscall num_get_char_get_int64(const num_get *this, istreambuf_iterator_char *ret,
6025     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
6026 {
6027     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6028     return call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval);
6029 }
6030
6031 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
6032 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
6033 #define call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 28, istreambuf_iterator_char*, \
6034         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONG*), \
6035         (this, ret, first, last, base, state, pval))
6036 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ulong,36)
6037 istreambuf_iterator_char *__thiscall num_get_char_do_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
6038     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
6039 {
6040     ULONG v;
6041     char tmp[25], *end;
6042     int err;
6043
6044     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6045
6046     v = _Stoulx(tmp, &end, num_get_char__Getifld(this, tmp,
6047                 &first, &last, base->fmtfl, base->loc), &err);
6048     if(end!=tmp && !err)
6049         *pval = v;
6050     else
6051         *state |= IOSTATE_failbit;
6052
6053     if(!first.strbuf)
6054         *state |= IOSTATE_eofbit;
6055
6056     *ret = first;
6057     return ret;
6058 }
6059
6060 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
6061 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
6062 DEFINE_THISCALL_WRAPPER(num_get_char_get_ulong,36)
6063 istreambuf_iterator_char *__thiscall num_get_char_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
6064     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
6065 {
6066     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6067     return call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
6068 }
6069
6070 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
6071 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
6072 #define call_num_get_char_do_get_long(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 32, istreambuf_iterator_char*, \
6073         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONG*), \
6074         (this, ret, first, last, base, state, pval))
6075 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_long,36)
6076 istreambuf_iterator_char *__thiscall num_get_char_do_get_long(const num_get *this, istreambuf_iterator_char *ret,
6077     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
6078 {
6079     LONG v;
6080     char tmp[25], *end;
6081     int err;
6082
6083     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6084
6085     v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
6086                 &first, &last, base->fmtfl, base->loc), &err);
6087     if(end!=tmp && !err)
6088         *pval = v;
6089     else
6090         *state |= IOSTATE_failbit;
6091
6092     if(!first.strbuf)
6093         *state |= IOSTATE_eofbit;
6094
6095     *ret = first;
6096     return ret;
6097 }
6098
6099 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
6100 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
6101 DEFINE_THISCALL_WRAPPER(num_get_char_get_long,36)
6102 istreambuf_iterator_char *__thiscall num_get_char_get_long(const num_get *this, istreambuf_iterator_char *ret,
6103     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
6104 {
6105     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6106     return call_num_get_char_do_get_long(this, ret, first, last, base, state, pval);
6107 }
6108
6109 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
6110 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
6111 #define call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 36, istreambuf_iterator_char*, \
6112         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned int*), \
6113         (this, ret, first, last, base, state, pval))
6114 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint,36)
6115 istreambuf_iterator_char *__thiscall num_get_char_do_get_uint(const num_get *this, istreambuf_iterator_char *ret,
6116     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned int *pval)
6117 {
6118     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6119     return num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
6120 }
6121
6122 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
6123 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
6124 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint,36)
6125 istreambuf_iterator_char *__thiscall num_get_char_get_uint(const num_get *this, istreambuf_iterator_char *ret,
6126     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned int *pval)
6127 {
6128     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6129     return call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval);
6130 }
6131
6132 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
6133 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
6134 #define call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 40, istreambuf_iterator_char*, \
6135         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned short*), \
6136         (this, ret, first, last, base, state, pval))
6137 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ushort,36)
6138 istreambuf_iterator_char *__thiscall num_get_char_do_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
6139     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
6140 {
6141     ULONG v;
6142     char tmp[25], *beg, *end;
6143     int err, b;
6144
6145     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6146
6147     b = num_get_char__Getifld(this, tmp,
6148             &first, &last, base->fmtfl, base->loc);
6149     beg = tmp + (tmp[0]=='-' ? 1 : 0);
6150     v = _Stoulx(beg, &end, b, &err);
6151
6152     if(v != (ULONG)((unsigned short)v))
6153         *state |= IOSTATE_failbit;
6154     else if(end!=beg && !err)
6155         *pval = (tmp[0]=='-' ? -((unsigned short)v) : v);
6156     else
6157         *state |= IOSTATE_failbit;
6158
6159     if(!first.strbuf)
6160         *state |= IOSTATE_eofbit;
6161
6162     *ret = first;
6163     return ret;
6164 }
6165
6166 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
6167 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
6168 DEFINE_THISCALL_WRAPPER(num_get_char_get_ushort,36)
6169 istreambuf_iterator_char *__thiscall num_get_char_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
6170     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
6171 {
6172     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6173     return call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval);
6174 }
6175
6176 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
6177 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
6178 #define call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 44, istreambuf_iterator_char*, \
6179         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, MSVCP_bool*), \
6180         (this, ret, first, last, base, state, pval))
6181 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_bool,36)
6182 istreambuf_iterator_char *__thiscall num_get_char_do_get_bool(const num_get *this, istreambuf_iterator_char *ret,
6183     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
6184 {
6185     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6186
6187     if(base->fmtfl & FMTFLAG_boolalpha) {
6188         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6189         basic_string_char false_bstr, true_bstr;
6190         const char *pfalse, *ptrue;
6191
6192         numpunct_char_falsename(numpunct, &false_bstr);
6193         numpunct_char_truename(numpunct, &true_bstr);
6194         pfalse = MSVCP_basic_string_char_c_str(&false_bstr);
6195         ptrue = MSVCP_basic_string_char_c_str(&true_bstr);
6196
6197         for(istreambuf_iterator_char_val(&first); first.strbuf;
6198                 istreambuf_iterator_char_inc(&first)) {
6199             if(pfalse && *pfalse && first.val!=*pfalse)
6200                 pfalse = NULL;
6201             if(ptrue && *ptrue && first.val!=*ptrue)
6202                 ptrue = NULL;
6203
6204             if(pfalse && *pfalse && ptrue && !*ptrue)
6205                 ptrue = NULL;
6206             if(ptrue && *ptrue && pfalse && !*pfalse)
6207                 pfalse = NULL;
6208
6209             if(pfalse)
6210                 pfalse++;
6211             if(ptrue)
6212                 ptrue++;
6213
6214             if((!pfalse || !*pfalse) && (!ptrue || !*ptrue))
6215                 break;
6216         }
6217
6218         if(ptrue)
6219             *pval = TRUE;
6220         else if(pfalse)
6221             *pval = FALSE;
6222         else
6223             *state |= IOSTATE_failbit;
6224
6225         MSVCP_basic_string_char_dtor(&false_bstr);
6226         MSVCP_basic_string_char_dtor(&true_bstr);
6227     }else {
6228         char tmp[25], *end;
6229         int err;
6230         LONG v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
6231                     &first, &last, base->fmtfl, base->loc), &err);
6232
6233         if(end!=tmp && err==0 && (v==0 || v==1))
6234             *pval = v;
6235         else
6236             *state |= IOSTATE_failbit;
6237     }
6238
6239     if(!first.strbuf)
6240         *state |= IOSTATE_eofbit;
6241     memcpy(ret, &first, sizeof(first));
6242     return ret;
6243 }
6244
6245 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
6246 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
6247 DEFINE_THISCALL_WRAPPER(num_get_char_get_bool,36)
6248 istreambuf_iterator_char *__thiscall num_get_char_get_bool(const num_get *this, istreambuf_iterator_char *ret,
6249     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
6250 {
6251     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6252     return call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval);
6253 }
6254
6255 /* ?id@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
6256 locale_id num_put_char_id = {0};
6257
6258 /* num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
6259 extern const vtable_ptr MSVCP_num_put_char_vtable;
6260
6261 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
6262 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
6263 DEFINE_THISCALL_WRAPPER(num_put_char__Init, 8)
6264 void __thiscall num_put_char__Init(num_put *this, const _Locinfo *locinfo)
6265 {
6266     TRACE("(%p %p)\n", this, locinfo);
6267     _Locinfo__Getcvt(locinfo, &this->cvt);
6268 }
6269
6270 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6271 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6272 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_locinfo, 12)
6273 num_put* __thiscall num_put_char_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6274 {
6275     TRACE("(%p %p %ld)\n", this, locinfo, refs);
6276
6277     locale_facet_ctor_refs(&this->facet, refs);
6278     this->facet.vtable = &MSVCP_num_put_char_vtable;
6279
6280     num_put_char__Init(this, locinfo);
6281     return this;
6282 }
6283
6284 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
6285 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
6286 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_refs, 8)
6287 num_put* __thiscall num_put_char_ctor_refs(num_put *this, MSVCP_size_t refs)
6288 {
6289      _Locinfo locinfo;
6290
6291      TRACE("(%p %lu)\n", this, refs);
6292
6293      _Locinfo_ctor(&locinfo);
6294      num_put_char_ctor_locinfo(this, &locinfo, refs);
6295      _Locinfo_dtor(&locinfo);
6296      return this;
6297 }
6298
6299 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
6300 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
6301 DEFINE_THISCALL_WRAPPER(num_put_char_ctor, 4)
6302 num_put* __thiscall num_put_char_ctor(num_put *this)
6303 {
6304     return num_put_char_ctor_refs(this, 0);
6305 }
6306
6307 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
6308 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
6309 DEFINE_THISCALL_WRAPPER(num_put_char_dtor, 4)
6310 void __thiscall num_put_char_dtor(num_put *this)
6311 {
6312     TRACE("(%p)\n", this);
6313     locale_facet_dtor(&this->facet);
6314 }
6315
6316 DEFINE_THISCALL_WRAPPER(num_put_char_vector_dtor, 8)
6317 num_put* __thiscall num_put_char_vector_dtor(num_put *this, unsigned int flags)
6318 {
6319     TRACE("(%p %x)\n", this, flags);
6320     if(flags & 2) {
6321         /* we have an array, with the number of elements stored before the first object */
6322         INT_PTR i, *ptr = (INT_PTR *)this-1;
6323
6324         for(i=*ptr-1; i>=0; i--)
6325             num_put_char_dtor(this+i);
6326         MSVCRT_operator_delete(ptr);
6327     } else {
6328         num_put_char_dtor(this);
6329         if(flags & 1)
6330             MSVCRT_operator_delete(this);
6331     }
6332
6333     return this;
6334 }
6335
6336 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
6337 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
6338 MSVCP_size_t __cdecl num_put_char__Getcat(const locale_facet **facet, const locale *loc)
6339 {
6340     TRACE("(%p %p)\n", facet, loc);
6341
6342     if(facet && !*facet) {
6343         _Locinfo locinfo;
6344
6345         *facet = MSVCRT_operator_new(sizeof(num_put));
6346         if(!*facet) {
6347             ERR("Out of memory\n");
6348             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6349             return 0;
6350         }
6351
6352         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
6353         num_put_char_ctor_locinfo((num_put*)*facet, &locinfo, 0);
6354         _Locinfo_dtor(&locinfo);
6355     }
6356
6357     return LC_NUMERIC;
6358 }
6359
6360 num_put* num_put_char_use_facet(const locale *loc)
6361 {
6362     static num_put *obj = NULL;
6363
6364     _Lockit lock;
6365     const locale_facet *fac;
6366
6367     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
6368     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_char_id));
6369     if(fac) {
6370         _Lockit_dtor(&lock);
6371         return (num_put*)fac;
6372     }
6373
6374     if(obj) {
6375         _Lockit_dtor(&lock);
6376         return obj;
6377     }
6378
6379     num_put_char__Getcat(&fac, loc);
6380     obj = (num_put*)fac;
6381     locale_facet__Incref(&obj->facet);
6382     locale_facet_register(&obj->facet);
6383     _Lockit_dtor(&lock);
6384
6385     return obj;
6386 }
6387
6388 /* ?_Put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PBDI@Z */
6389 /* ?_Put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PEBD_K@Z */
6390 ostreambuf_iterator_char* __cdecl num_put_char__Put(const num_put *this, ostreambuf_iterator_char *ret,
6391         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count)
6392 {
6393     TRACE("(%p %p %p %ld)\n", this, ret, ptr, count);
6394
6395     for(; count>0; count--)
6396         ostreambuf_iterator_char_put(&dest, *ptr++);
6397
6398     *ret = dest;
6399     return ret;
6400 }
6401
6402 /* ?_Putc@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PBDI@Z */
6403 /* ?_Putc@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PEBD_K@Z */
6404 ostreambuf_iterator_char* __cdecl num_put_char__Putc(const num_put *this, ostreambuf_iterator_char *ret,
6405         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count)
6406 {
6407     TRACE("(%p %p %p %ld)\n", this, ret, ptr, count);
6408
6409     for(; count>0; count--)
6410         ostreambuf_iterator_char_put(&dest, *ptr++);
6411
6412     *ret = dest;
6413     return ret;
6414 }
6415
6416 /* ?_Putgrouped@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PBDID@Z */
6417 /* ?_Putgrouped@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PEBD_KD@Z */
6418 ostreambuf_iterator_char* __cdecl num_put_char__Putgrouped(const num_put *this, ostreambuf_iterator_char *ret,
6419         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count, char delim)
6420 {
6421     FIXME("(%p %p %p %ld %d) stub\n", this, ret, ptr, count, delim);
6422     return NULL;
6423 }
6424
6425 /* ?_Rep@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@DI@Z */
6426 /* ?_Rep@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@D_K@Z */
6427 ostreambuf_iterator_char* __cdecl num_put_char__Rep(const num_put *this, ostreambuf_iterator_char *ret,
6428         ostreambuf_iterator_char dest, char c, MSVCP_size_t count)
6429 {
6430     TRACE("(%p %p %d %ld)\n", this, ret, c, count);
6431
6432     for(; count>0; count--)
6433         ostreambuf_iterator_char_put(&dest, c);
6434
6435     *ret = dest;
6436     return ret;
6437 }
6438
6439 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADDH@Z */
6440 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADDH@Z */
6441 char* __cdecl num_put_char__Ffmt(const num_put *this, char *fmt, char spec, int fmtfl)
6442 {
6443     int type = fmtfl & FMTFLAG_floatfield;
6444     char *p = fmt;
6445
6446     TRACE("(%p %p %d %d)\n", this, fmt, spec, fmtfl);
6447
6448     *p++ = '%';
6449     if(fmtfl & FMTFLAG_showpos)
6450         *p++ = '+';
6451     if(fmtfl & FMTFLAG_showbase)
6452         *p++ = '#';
6453     *p++ = '.';
6454     *p++ = '*';
6455     if(spec)
6456         *p++ = spec;
6457
6458     if(type == FMTFLAG_fixed)
6459         *p++ = 'f';
6460     else if(type == FMTFLAG_scientific)
6461         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'E' : 'e';
6462     else if(type == (FMTFLAG_fixed|FMTFLAG_scientific))
6463         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'A' : 'a';
6464     else
6465         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'G' : 'g';
6466
6467     *p++ = '\0';
6468     return fmt;
6469 }
6470
6471 /* ?_Fput@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DPBDIIII@Z */
6472 /* ?_Fput@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DPEBD_K333@Z */
6473 ostreambuf_iterator_char* __cdecl num_put_char__Fput(const num_put *this, ostreambuf_iterator_char *ret,
6474         ostreambuf_iterator_char dest, ios_base *base, char fill, const char *buf, MSVCP_size_t bef_point,
6475         MSVCP_size_t aft_point, MSVCP_size_t trailing, MSVCP_size_t count)
6476 {
6477     FIXME("(%p %p %p %d %p %ld %ld %ld %ld) stub\n", this, ret, base,
6478             fill, buf, bef_point, aft_point, trailing, count);
6479     return NULL;
6480 }
6481
6482 /* TODO: This function should be removed when num_put_char__Fput is implemented */
6483 static ostreambuf_iterator_char* num_put_char_fput(const num_put *this, ostreambuf_iterator_char *ret,
6484         ostreambuf_iterator_char dest, ios_base *base, char fill, char *buf, MSVCP_size_t count)
6485 {
6486     numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6487     basic_string_char grouping_bstr;
6488     const char *grouping;
6489     char *p, sep = *localeconv()->decimal_point;
6490     int cur_group = 0, group_size = 0;
6491     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
6492     MSVCP_size_t pad;
6493
6494     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
6495
6496     /* Change decimal point */
6497     for(p=buf; p<buf+count; p++) {
6498         if(*p == sep) {
6499             *p = numpunct_char_decimal_point(numpunct);
6500             break;
6501         }
6502     }
6503     p--;
6504
6505     /* Add separators to number */
6506     numpunct_char_grouping(numpunct, &grouping_bstr);
6507     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
6508     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
6509
6510     for(; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
6511         group_size++;
6512         if(group_size == grouping[cur_group]) {
6513             group_size = 0;
6514             if(grouping[cur_group+1])
6515                 cur_group++;
6516
6517             memmove(p+1, p, buf+count-p);
6518             *p = sep;
6519             count++;
6520         }
6521     }
6522     MSVCP_basic_string_char_dtor(&grouping_bstr);
6523
6524     /* Display number with padding */
6525     if(count >= base->wide)
6526         pad = 0;
6527     else
6528         pad = base->wide-count;
6529     base->wide = 0;
6530
6531     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
6532         num_put_char__Putc(this, &dest, dest, buf, 1);
6533         buf++;
6534     }
6535     if(adjustfield != FMTFLAG_left) {
6536         num_put_char__Rep(this, ret, dest, fill, pad);
6537         pad = 0;
6538     }
6539     num_put_char__Putc(this, &dest, dest, buf, count);
6540     return num_put_char__Rep(this, ret, dest, fill, pad);
6541 }
6542
6543 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADPBDH@Z */
6544 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
6545 char* __cdecl num_put_char__Ifmt(const num_put *this, char *fmt, const char *spec, int fmtfl)
6546 {
6547     int base = fmtfl & FMTFLAG_basefield;
6548     char *p = fmt;
6549
6550     TRACE("(%p %p %p %d)\n", this, fmt, spec, fmtfl);
6551
6552     *p++ = '%';
6553     if(fmtfl & FMTFLAG_showpos)
6554         *p++ = '+';
6555     if(fmtfl & FMTFLAG_showbase)
6556         *p++ = '#';
6557
6558     *p++ = *spec++;
6559     if(*spec == 'l')
6560         *p++ = *spec++;
6561
6562     if(base == FMTFLAG_oct)
6563         *p++ = 'o';
6564     else if(base == FMTFLAG_hex)
6565         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'X' : 'x';
6566     else
6567         *p++ = *spec;
6568
6569     *p++ = '\0';
6570     return fmt;
6571 }
6572
6573 /* ?_Iput@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DPADI@Z */
6574 /* ?_Iput@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DPEAD_K@Z */
6575 ostreambuf_iterator_char* __cdecl num_put_char__Iput(const num_put *this, ostreambuf_iterator_char *ret,
6576         ostreambuf_iterator_char dest, ios_base *base, char fill, char *buf, MSVCP_size_t count)
6577 {
6578     numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6579     basic_string_char grouping_bstr;
6580     const char *grouping;
6581     char *p, sep;
6582     int cur_group = 0, group_size = 0;
6583     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
6584     MSVCP_size_t pad;
6585
6586     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
6587
6588     /* Add separators to number */
6589     numpunct_char_grouping(numpunct, &grouping_bstr);
6590     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
6591     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
6592
6593     for(p=buf+count-1; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
6594         group_size++;
6595         if(group_size == grouping[cur_group]) {
6596             group_size = 0;
6597             if(grouping[cur_group+1])
6598                 cur_group++;
6599
6600             memmove(p+1, p, buf+count-p);
6601             *p = sep;
6602             count++;
6603         }
6604     }
6605     MSVCP_basic_string_char_dtor(&grouping_bstr);
6606
6607     /* Display number with padding */
6608     if(count >= base->wide)
6609         pad = 0;
6610     else
6611         pad = base->wide-count;
6612     base->wide = 0;
6613
6614     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
6615         num_put_char__Putc(this, &dest, dest, buf, 1);
6616         buf++;
6617     }else if((adjustfield & FMTFLAG_internal) && (buf[1]=='x' || buf[1]=='X')) {
6618         num_put_char__Putc(this, &dest, dest, buf, 2);
6619         buf += 2;
6620     }
6621     if(adjustfield != FMTFLAG_left) {
6622         num_put_char__Rep(this, ret, dest, fill, pad);
6623         pad = 0;
6624     }
6625     num_put_char__Putc(this, &dest, dest, buf, count);
6626     return num_put_char__Rep(this, ret, dest, fill, pad);
6627 }
6628
6629 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DJ@Z */
6630 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DJ@Z */
6631 #define call_num_put_char_do_put_long(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 28, ostreambuf_iterator_char*, \
6632         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, LONG), \
6633         (this, ret, dest, base, fill, v))
6634 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_long, 28)
6635 ostreambuf_iterator_char* __thiscall num_put_char_do_put_long(const num_put *this, ostreambuf_iterator_char *ret,
6636         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
6637 {
6638     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6639     char fmt[7]; /* strlen("%+#lld")+1 */
6640
6641     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6642
6643     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6644             sprintf(tmp, num_put_char__Ifmt(this, fmt, "ld", base->fmtfl), v));
6645 }
6646
6647 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DJ@Z */
6648 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DJ@Z */
6649 DEFINE_THISCALL_WRAPPER(num_put_char_put_long, 28)
6650 ostreambuf_iterator_char* __thiscall num_put_char_put_long(const num_put *this, ostreambuf_iterator_char *ret,
6651         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
6652 {
6653     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6654     return call_num_put_char_do_put_long(this, ret, dest, base, fill, v);
6655 }
6656
6657 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DK@Z */
6658 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DK@Z */
6659 #define call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 24, ostreambuf_iterator_char*, \
6660         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, ULONG), \
6661         (this, ret, dest, base, fill, v))
6662 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ulong, 28)
6663 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
6664         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
6665 {
6666     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6667     char fmt[7]; /* strlen("%+#lld")+1 */
6668
6669     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6670
6671     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6672             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lu", base->fmtfl), v));
6673 }
6674
6675 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DK@Z */
6676 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DK@Z */
6677 DEFINE_THISCALL_WRAPPER(num_put_char_put_ulong, 28)
6678 ostreambuf_iterator_char* __thiscall num_put_char_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
6679         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
6680 {
6681     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6682     return call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v);
6683 }
6684
6685 static inline streamsize get_precision(const ios_base *base)
6686 {
6687     return base->prec <= 0 && !(base->fmtfl & FMTFLAG_fixed) ? 6 : base->prec;
6688 }
6689
6690 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DN@Z */
6691 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DN@Z */
6692 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DO@Z */
6693 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DO@Z */
6694 #define call_num_put_char_do_put_double(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 12, ostreambuf_iterator_char*, \
6695         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
6696         (this, ret, dest, base, fill, v))
6697 #define call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 8, ostreambuf_iterator_char*, \
6698         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
6699         (this, ret, dest, base, fill, v))
6700 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_double, 32)
6701 ostreambuf_iterator_char* __thiscall num_put_char_do_put_double(const num_put *this, ostreambuf_iterator_char *ret,
6702         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6703 {
6704     char *tmp;
6705     char fmt[8]; /* strlen("%+#.*lg")+1 */
6706     int size;
6707     streamsize prec;
6708
6709     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6710
6711     num_put_char__Ffmt(this, fmt, '\0', base->fmtfl);
6712     prec = get_precision(base);
6713     size = _scprintf(fmt, prec, v);
6714
6715     /* TODO: don't use dynamic allocation */
6716     tmp = MSVCRT_operator_new(size*2);
6717     if(!tmp) {
6718         ERR("Out of memory\n");
6719         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6720     }
6721     num_put_char_fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, prec, v));
6722     MSVCRT_operator_delete(tmp);
6723     return ret;
6724 }
6725
6726 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DN@Z */
6727 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DN@Z */
6728 DEFINE_THISCALL_WRAPPER(num_put_char_put_double, 32)
6729 ostreambuf_iterator_char* __thiscall num_put_char_put_double(const num_put *this, ostreambuf_iterator_char *ret,
6730         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6731 {
6732     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6733     return call_num_put_char_do_put_double(this, ret, dest, base, fill, v);
6734 }
6735
6736 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DO@Z */
6737 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DO@Z */
6738 DEFINE_THISCALL_WRAPPER(num_put_char_put_ldouble, 32)
6739 ostreambuf_iterator_char* __thiscall num_put_char_put_ldouble(const num_put *this, ostreambuf_iterator_char *ret,
6740         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6741 {
6742     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6743     return call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v);
6744 }
6745
6746 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DPBX@Z */
6747 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DPEBX@Z */
6748 #define call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 4, ostreambuf_iterator_char*, \
6749         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, const void*), \
6750         (this, ret, dest, base, fill, v))
6751 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ptr, 28)
6752 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
6753         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
6754 {
6755     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
6756
6757     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
6758
6759     return num_put_char__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
6760 }
6761
6762 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DPBX@Z */
6763 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DPEBX@Z */
6764 DEFINE_THISCALL_WRAPPER(num_put_char_put_ptr, 28)
6765 ostreambuf_iterator_char* __thiscall num_put_char_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
6766         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
6767 {
6768     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
6769     return call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v);
6770 }
6771
6772 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_J@Z */
6773 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_J@Z */
6774 #define call_num_put_char_do_put_int64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 20, ostreambuf_iterator_char*, \
6775         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, __int64), \
6776         (this, ret, dest, base, fill, v))
6777 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_int64, 32)
6778 ostreambuf_iterator_char* __thiscall num_put_char_do_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
6779         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
6780 {
6781     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6782     char fmt[7]; /* strlen("%+#lld")+1 */
6783
6784     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6785
6786     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6787             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lld", base->fmtfl), v));
6788 }
6789
6790 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_J@Z */
6791 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_J@Z */
6792 DEFINE_THISCALL_WRAPPER(num_put_char_put_int64, 32)
6793 ostreambuf_iterator_char* __thiscall num_put_char_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
6794         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
6795 {
6796     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6797     return call_num_put_char_do_put_int64(this, ret, dest, base, fill, v);
6798 }
6799
6800 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_K@Z */
6801 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_K@Z */
6802 #define call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 16, ostreambuf_iterator_char*, \
6803         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, unsigned __int64), \
6804         (this, ret, dest, base, fill, v))
6805 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_uint64, 32)
6806 ostreambuf_iterator_char* __thiscall num_put_char_do_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
6807         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
6808 {
6809     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6810     char fmt[7]; /* strlen("%+#lld")+1 */
6811
6812     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6813
6814     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6815             sprintf(tmp, num_put_char__Ifmt(this, fmt, "llu", base->fmtfl), v));
6816 }
6817
6818 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_K@Z */
6819 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_K@Z */
6820 DEFINE_THISCALL_WRAPPER(num_put_char_put_uint64, 32)
6821 ostreambuf_iterator_char* __thiscall num_put_char_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
6822         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
6823 {
6824     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6825     return call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v);
6826 }
6827
6828 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_N@Z */
6829 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_N@Z */
6830 #define call_num_put_char_do_put_bool(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 32, ostreambuf_iterator_char*, \
6831         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, MSVCP_bool), \
6832         (this, ret, dest, base, fill, v))
6833 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_bool, 28)
6834 ostreambuf_iterator_char* __thiscall num_put_char_do_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
6835         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
6836 {
6837     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6838
6839     if(base->fmtfl & FMTFLAG_boolalpha) {
6840         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6841         basic_string_char str;
6842         MSVCP_size_t pad, len;
6843
6844         if(v)
6845             numpunct_char_truename(numpunct, &str);
6846         else
6847             numpunct_char_falsename(numpunct, &str);
6848
6849         len = MSVCP_basic_string_char_length(&str);
6850         pad = (len>base->wide ? 0 : base->wide-len);
6851         base->wide = 0;
6852
6853         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
6854             num_put_char__Rep(this, &dest, dest, fill, pad);
6855             pad = 0;
6856         }
6857         num_put_char__Putc(this, &dest, dest, MSVCP_basic_string_char_c_str(&str), len);
6858         MSVCP_basic_string_char_dtor(&str);
6859         return num_put_char__Rep(this, ret, dest, fill, pad);
6860     }
6861
6862     return num_put_char_put_long(this, ret, dest, base, fill, v);
6863 }
6864
6865 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_N@Z */
6866 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_N@Z */
6867 DEFINE_THISCALL_WRAPPER(num_put_char_put_bool, 28)
6868 ostreambuf_iterator_char* __thiscall num_put_char_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
6869         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
6870 {
6871     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6872     return call_num_put_char_do_put_bool(this, ret, dest, base, fill, v);
6873 }
6874
6875 /* ?id@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
6876 locale_id num_put_wchar_id = {0};
6877 /* ?id@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@2V0locale@2@A */
6878 locale_id num_put_short_id = {0};
6879
6880 /* num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
6881 extern const vtable_ptr MSVCP_num_put_wchar_vtable;
6882 /* num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@6B@ */
6883 extern const vtable_ptr MSVCP_num_put_short_vtable;
6884
6885 /* ?_Init@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
6886 /* ?_Init@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
6887 DEFINE_THISCALL_WRAPPER(num_put_wchar__Init, 8)
6888 void __thiscall num_put_wchar__Init(num_put *this, const _Locinfo *locinfo)
6889 {
6890     TRACE("(%p %p)\n", this, locinfo);
6891     _Locinfo__Getcvt(locinfo, &this->cvt);
6892 }
6893
6894 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6895 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6896 DEFINE_THISCALL_WRAPPER(num_put_wchar_ctor_locinfo, 12)
6897 num_put* __thiscall num_put_wchar_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6898 {
6899     TRACE("(%p %p %ld)\n", this, locinfo, refs);
6900
6901     locale_facet_ctor_refs(&this->facet, refs);
6902     this->facet.vtable = &MSVCP_num_put_wchar_vtable;
6903
6904     num_put_wchar__Init(this, locinfo);
6905     return this;
6906 }
6907
6908 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6909 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6910 DEFINE_THISCALL_WRAPPER(num_put_short_ctor_locinfo, 12)
6911 num_put* __thiscall num_put_short_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6912 {
6913     num_put_wchar_ctor_locinfo(this, locinfo, refs);
6914     this->facet.vtable = &MSVCP_num_put_short_vtable;
6915     return this;
6916 }
6917
6918 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
6919 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
6920 DEFINE_THISCALL_WRAPPER(num_put_wchar_ctor_refs, 8)
6921 num_put* __thiscall num_put_wchar_ctor_refs(num_put *this, MSVCP_size_t refs)
6922 {
6923     _Locinfo locinfo;
6924
6925     TRACE("(%p %lu)\n", this, refs);
6926
6927     _Locinfo_ctor(&locinfo);
6928     num_put_wchar_ctor_locinfo(this, &locinfo, refs);
6929     _Locinfo_dtor(&locinfo);
6930     return this;
6931 }
6932
6933 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@I@Z */
6934 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@_K@Z */
6935 DEFINE_THISCALL_WRAPPER(num_put_short_ctor_refs, 8)
6936 num_put* __thiscall num_put_short_ctor_refs(num_put *this, MSVCP_size_t refs)
6937 {
6938     num_put_wchar_ctor_refs(this, refs);
6939     this->facet.vtable = &MSVCP_num_put_short_vtable;
6940     return this;
6941 }
6942
6943 /* ??_F?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
6944 /* ??_F?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
6945 DEFINE_THISCALL_WRAPPER(num_put_wchar_ctor, 4)
6946 num_put* __thiscall num_put_wchar_ctor(num_put *this)
6947 {
6948     return num_put_wchar_ctor_refs(this, 0);
6949 }
6950
6951 /* ??_F?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAEXXZ */
6952 /* ??_F?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAAXXZ */
6953 DEFINE_THISCALL_WRAPPER(num_put_short_ctor, 4)
6954 num_put* __thiscall num_put_short_ctor(num_put *this)
6955 {
6956     return num_put_short_ctor_refs(this, 0);
6957 }
6958
6959 /* ??1?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
6960 /* ??1?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
6961 /* ??1?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MAE@XZ */
6962 /* ??1?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEAA@XZ */
6963 DEFINE_THISCALL_WRAPPER(num_put_wchar_dtor, 4)
6964 void __thiscall num_put_wchar_dtor(num_put *this)
6965 {
6966     TRACE("(%p)\n", this);
6967     locale_facet_dtor(&this->facet);
6968 }
6969
6970 DEFINE_THISCALL_WRAPPER(num_put_wchar_vector_dtor, 8)
6971 num_put* __thiscall num_put_wchar_vector_dtor(num_put *this, unsigned int flags)
6972 {
6973     TRACE("(%p %x)\n", this, flags);
6974     if(flags & 2) {
6975         /* we have an array, with the number of elements stored before the first object */
6976         INT_PTR i, *ptr = (INT_PTR *)this-1;
6977
6978         for(i=*ptr-1; i>=0; i--)
6979             num_put_wchar_dtor(this+i);
6980         MSVCRT_operator_delete(ptr);
6981     } else {
6982         num_put_wchar_dtor(this);
6983         if(flags & 1)
6984             MSVCRT_operator_delete(this);
6985     }
6986
6987     return this;
6988 }
6989
6990 /* ?_Getcat@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
6991 /* ?_Getcat@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
6992 MSVCP_size_t __cdecl num_put_wchar__Getcat(const locale_facet **facet, const locale *loc)
6993 {
6994     TRACE("(%p %p)\n", facet, loc);
6995
6996     if(facet && !*facet) {
6997         _Locinfo locinfo;
6998
6999         *facet = MSVCRT_operator_new(sizeof(num_put));
7000         if(!*facet) {
7001             ERR("Out of memory\n");
7002             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7003             return 0;
7004         }
7005
7006         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
7007         num_put_wchar_ctor_locinfo((num_put*)*facet, &locinfo, 0);
7008         _Locinfo_dtor(&locinfo);
7009     }
7010
7011     return LC_NUMERIC;
7012 }
7013
7014 /* ?_Getcat@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
7015 /* ?_Getcat@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
7016 MSVCP_size_t __cdecl num_put_short__Getcat(const locale_facet **facet, const locale *loc)
7017 {
7018     TRACE("(%p %p)\n", facet, loc);
7019
7020     if(facet && !*facet) {
7021         _Locinfo locinfo;
7022
7023         *facet = MSVCRT_operator_new(sizeof(num_put));
7024         if(!*facet) {
7025             ERR("Out of memory\n");
7026             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7027             return 0;
7028         }
7029
7030         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
7031         num_put_short_ctor_locinfo((num_put*)*facet, &locinfo, 0);
7032         _Locinfo_dtor(&locinfo);
7033     }
7034
7035     return LC_NUMERIC;
7036 }
7037
7038 num_put* num_put_wchar_use_facet(const locale *loc)
7039 {
7040     static num_put *obj = NULL;
7041
7042     _Lockit lock;
7043     const locale_facet *fac;
7044
7045     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7046     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_wchar_id));
7047     if(fac) {
7048         _Lockit_dtor(&lock);
7049         return (num_put*)fac;
7050     }
7051
7052     if(obj) {
7053         _Lockit_dtor(&lock);
7054         return obj;
7055     }
7056
7057     num_put_wchar__Getcat(&fac, loc);
7058     obj = (num_put*)fac;
7059     locale_facet__Incref(&obj->facet);
7060     locale_facet_register(&obj->facet);
7061     _Lockit_dtor(&lock);
7062
7063     return obj;
7064 }
7065
7066 num_put* num_put_short_use_facet(const locale *loc)
7067 {
7068     static num_put *obj = NULL;
7069
7070     _Lockit lock;
7071     const locale_facet *fac;
7072
7073     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7074     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_short_id));
7075     if(fac) {
7076         _Lockit_dtor(&lock);
7077         return (num_put*)fac;
7078     }
7079
7080     if(obj) {
7081         _Lockit_dtor(&lock);
7082         return obj;
7083     }
7084
7085     num_put_short__Getcat(&fac, loc);
7086     obj = (num_put*)fac;
7087     locale_facet__Incref(&obj->facet);
7088     locale_facet_register(&obj->facet);
7089     _Lockit_dtor(&lock);
7090
7091     return obj;
7092 }
7093
7094 /* ?_Put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PB_WI@Z */
7095 /* ?_Put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PEB_W_K@Z */
7096 /* ?_Put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PBGI@Z */
7097 /* ?_Put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PEBG_K@Z */
7098 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Put(const num_put *this, ostreambuf_iterator_wchar *ret,
7099         ostreambuf_iterator_wchar dest, const wchar_t *ptr, MSVCP_size_t count)
7100 {
7101     TRACE("(%p %p %s %ld)\n", this, ret, debugstr_wn(ptr, count), count);
7102
7103     for(; count>0; count--)
7104         ostreambuf_iterator_wchar_put(&dest, *ptr++);
7105
7106     *ret = dest;
7107     return ret;
7108 }
7109
7110 /* ?_Putc@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PBDI@Z */
7111 /* ?_Putc@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PEBD_K@Z */
7112 /* ?_Putc@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PBDI@Z */
7113 /* ?_Putc@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PEBD_K@Z */
7114 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Putc(const num_put *this, ostreambuf_iterator_wchar *ret,
7115         ostreambuf_iterator_wchar dest, const char *ptr, MSVCP_size_t count)
7116 {
7117     int state = 0;
7118     wchar_t ch;
7119
7120     TRACE("(%p %p %s %ld)\n", this, ret, debugstr_an(ptr, count), count);
7121
7122     for(; count>0; count--) {
7123         if(_Mbrtowc(&ch, ptr++, 1, &state, &this->cvt) == 1)
7124             ostreambuf_iterator_wchar_put(&dest, ch);
7125     }
7126
7127     *ret = dest;
7128     return ret;
7129 }
7130
7131 /* ?_Putgrouped@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PBDI_W@Z */
7132 /* ?_Putgrouped@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PEBD_K_W@Z */
7133 /* ?_Putgrouped@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PBDIG@Z */
7134 /* ?_Putgrouped@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PEBD_KG@Z */
7135 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Putgrouped(const num_put *this, ostreambuf_iterator_wchar *ret,
7136         ostreambuf_iterator_wchar dest, const char *ptr, MSVCP_size_t count, wchar_t delim)
7137 {
7138     FIXME("(%p %p %p %ld %d) stub\n", this, ret, ptr, count, delim);
7139     return NULL;
7140 }
7141
7142 /* ?_Rep@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@_WI@Z */
7143 /* ?_Rep@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@_W_K@Z */
7144 /* ?_Rep@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@GI@Z */
7145 /* ?_Rep@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@G_K@Z */
7146 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Rep(const num_put *this, ostreambuf_iterator_wchar *ret,
7147         ostreambuf_iterator_wchar dest, wchar_t c, MSVCP_size_t count)
7148 {
7149     TRACE("(%p %p %d %ld)\n", this, ret, c, count);
7150
7151     for(; count>0; count--)
7152         ostreambuf_iterator_wchar_put(&dest, c);
7153
7154     *ret = dest;
7155     return ret;
7156 }
7157
7158 /* ?_Ffmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAPADPADDH@Z */
7159 /* ?_Ffmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAPEADPEADDH@Z */
7160 /* ?_Ffmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAPADPADDH@Z */
7161 /* ?_Ffmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAPEADPEADDH@Z */
7162 char* __cdecl num_put_wchar__Ffmt(const num_put *this, char *fmt, char spec, int fmtfl)
7163 {
7164     int type = fmtfl & FMTFLAG_floatfield;
7165     char *p = fmt;
7166
7167     TRACE("(%p %p %d %d)\n", this, fmt, spec, fmtfl);
7168
7169     *p++ = '%';
7170     if(fmtfl & FMTFLAG_showpos)
7171         *p++ = '+';
7172     if(fmtfl & FMTFLAG_showbase)
7173         *p++ = '#';
7174     *p++ = '.';
7175     *p++ = '*';
7176     if(spec)
7177         *p++ = spec;
7178
7179     if(type == FMTFLAG_fixed)
7180         *p++ = 'f';
7181     else if(type == FMTFLAG_scientific)
7182         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'E' : 'e';
7183     else if(type == (FMTFLAG_fixed|FMTFLAG_scientific))
7184         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'A' : 'a';
7185     else
7186         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'G' : 'g';
7187
7188     *p++ = '\0';
7189     return fmt;
7190 }
7191
7192 /* ?_Fput@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WPBDIIII@Z */
7193 /* ?_Fput@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WPEBD_K444@Z */
7194 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Fput(const num_put *this, ostreambuf_iterator_wchar *ret,
7195         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const char *buf, MSVCP_size_t bef_point,
7196         MSVCP_size_t aft_point, MSVCP_size_t trailing, MSVCP_size_t count)
7197 {
7198     FIXME("(%p %p %p %d %p %ld %ld %ld %ld) stub\n", this, ret, base,
7199             fill, buf, bef_point, aft_point, trailing, count);
7200     return NULL;
7201 }
7202
7203 /* ?_Fput@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GPBDIIII@Z */
7204 /* ?_Fput@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GPEBD_K333@Z */
7205 ostreambuf_iterator_wchar* __cdecl num_put_short__Fput(const num_put *this, ostreambuf_iterator_wchar *ret,
7206         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const char *buf, MSVCP_size_t bef_point,
7207         MSVCP_size_t aft_point, MSVCP_size_t trailing, MSVCP_size_t count)
7208 {
7209     FIXME("(%p %p %p %d %p %ld %ld %ld %ld) stub\n", this, ret, base,
7210             fill, buf, bef_point, aft_point, trailing, count);
7211     return NULL;
7212 }
7213
7214 /* TODO: This function should be removed when num_put_wchar__Fput is implemented */
7215 static ostreambuf_iterator_wchar* num_put__fput(const num_put *this, ostreambuf_iterator_wchar *ret,
7216         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf,
7217         MSVCP_size_t count, numpunct_wchar *numpunct)
7218 {
7219     basic_string_char grouping_bstr;
7220     const char *grouping;
7221     char *p, dec_point = *localeconv()->decimal_point;
7222     wchar_t sep;
7223     int cur_group = 0, group_size = 0;
7224     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
7225     MSVCP_size_t i, pad;
7226
7227     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
7228
7229     for(p=buf; p<buf+count; p++) {
7230         if(*p == dec_point)
7231             break;
7232     }
7233     p--;
7234
7235     /* Add separators to number */
7236     numpunct_wchar_grouping(numpunct, &grouping_bstr);
7237     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
7238     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
7239
7240     for(; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
7241         group_size++;
7242         if(group_size == grouping[cur_group]) {
7243             group_size = 0;
7244             if(grouping[cur_group+1])
7245                 cur_group++;
7246
7247             memmove(p+1, p, buf+count-p);
7248             *p = '\0'; /* mark thousands separator positions */
7249             count++;
7250         }
7251     }
7252     MSVCP_basic_string_char_dtor(&grouping_bstr);
7253
7254     /* Display number with padding */
7255     if(count >= base->wide)
7256         pad = 0;
7257     else
7258         pad = base->wide-count;
7259     base->wide = 0;
7260
7261     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
7262         num_put_wchar__Putc(this, &dest, dest, buf, 1);
7263         buf++;
7264     }
7265     if(adjustfield != FMTFLAG_left) {
7266         num_put_wchar__Rep(this, ret, dest, fill, pad);
7267         pad = 0;
7268     }
7269
7270     for(i=0; i<count; i++) {
7271         if(buf[i] == dec_point)
7272             num_put_wchar__Rep(this, &dest, dest, numpunct_wchar_decimal_point(numpunct), 1);
7273         else if(!buf[i])
7274             num_put_wchar__Rep(this, &dest, dest, sep, 1);
7275         else
7276             num_put_wchar__Putc(this, &dest, dest, buf+i, 1);
7277     }
7278
7279     return num_put_wchar__Rep(this, ret, dest, fill, pad);
7280 }
7281
7282 /* ?_Ifmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAPADPADPBDH@Z */
7283 /* ?_Ifmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
7284 /* ?_Ifmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAPADPADPBDH@Z */
7285 /* ?_Ifmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
7286 char* __cdecl num_put_wchar__Ifmt(const num_put *this, char *fmt, const char *spec, int fmtfl)
7287 {
7288     int base = fmtfl & FMTFLAG_basefield;
7289     char *p = fmt;
7290
7291     TRACE("(%p %p %p %d)\n", this, fmt, spec, fmtfl);
7292
7293     *p++ = '%';
7294     if(fmtfl & FMTFLAG_showpos)
7295         *p++ = '+';
7296     if(fmtfl & FMTFLAG_showbase)
7297         *p++ = '#';
7298
7299     *p++ = *spec++;
7300     if(*spec == 'l')
7301         *p++ = *spec++;
7302
7303     if(base == FMTFLAG_oct)
7304         *p++ = 'o';
7305     else if(base == FMTFLAG_hex)
7306         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'X' : 'x';
7307     else
7308         *p++ = *spec;
7309
7310     *p++ = '\0';
7311     return fmt;
7312 }
7313
7314 static ostreambuf_iterator_wchar* num_put__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
7315         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf,
7316         MSVCP_size_t count, numpunct_wchar *numpunct)
7317 {
7318     basic_string_char grouping_bstr;
7319     const char *grouping;
7320     char *p;
7321     wchar_t sep;
7322     int cur_group = 0, group_size = 0;
7323     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
7324     MSVCP_size_t i, pad;
7325
7326     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
7327
7328     /* Add separators to number */
7329     numpunct_wchar_grouping(numpunct, &grouping_bstr);
7330     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
7331     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
7332
7333     for(p=buf+count-1; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
7334         group_size++;
7335         if(group_size == grouping[cur_group]) {
7336             group_size = 0;
7337             if(grouping[cur_group+1])
7338                 cur_group++;
7339
7340             memmove(p+1, p, buf+count-p);
7341             *p = '\0'; /* mark thousands separator positions */
7342             count++;
7343         }
7344     }
7345     MSVCP_basic_string_char_dtor(&grouping_bstr);
7346
7347     /* Display number with padding */
7348     if(count >= base->wide)
7349         pad = 0;
7350     else
7351         pad = base->wide-count;
7352     base->wide = 0;
7353
7354     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
7355         num_put_wchar__Putc(this, &dest, dest, buf, 1);
7356         buf++;
7357     }else if((adjustfield & FMTFLAG_internal) && (buf[1]=='x' || buf[1]=='X')) {
7358         num_put_wchar__Putc(this, &dest, dest, buf, 2);
7359         buf += 2;
7360     }
7361     if(adjustfield != FMTFLAG_left) {
7362         num_put_wchar__Rep(this, ret, dest, fill, pad);
7363         pad = 0;
7364     }
7365
7366     for(i=0; i<count; i++) {
7367         if(!buf[i])
7368             num_put_wchar__Rep(this, &dest, dest, sep, 1);
7369         else
7370             num_put_wchar__Putc(this, &dest, dest, buf+i, 1);
7371     }
7372
7373     return num_put_wchar__Rep(this, ret, dest, fill, pad);
7374 }
7375
7376 /* ?_Iput@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WPADI@Z */
7377 /* ?_Iput@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WPEAD_K@Z */
7378 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
7379         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf, MSVCP_size_t count)
7380 {
7381     return num_put__Iput(this, ret, dest, base, fill, buf, count, numpunct_wchar_use_facet(base->loc));
7382 }
7383
7384 /* ?_Iput@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GPADI@Z */
7385 /* ?_Iput@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GPEAD_K@Z */
7386 ostreambuf_iterator_wchar* __cdecl num_put_short__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
7387         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf, MSVCP_size_t count)
7388 {
7389     return num_put__Iput(this, ret, dest, base, fill, buf, count, numpunct_short_use_facet(base->loc));
7390 }
7391
7392 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WJ@Z */
7393 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WJ@Z */
7394 #define call_num_put_wchar_do_put_long(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 28, ostreambuf_iterator_wchar*, \
7395         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, LONG), \
7396         (this, ret, dest, base, fill, v))
7397 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_long, 28)
7398 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
7399         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
7400 {
7401     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7402     char fmt[7]; /* strlen("%+#lld")+1 */
7403
7404     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7405
7406     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7407             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "ld", base->fmtfl), v));
7408 }
7409
7410 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GJ@Z */
7411 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GJ@Z */
7412 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_long, 28)
7413 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
7414         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
7415 {
7416     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7417     char fmt[7]; /* strlen("%+#lld")+1 */
7418
7419     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7420
7421     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7422             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "ld", base->fmtfl), v));
7423 }
7424
7425 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WJ@Z */
7426 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WJ@Z */
7427 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GJ@Z */
7428 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GJ@Z */
7429 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_long, 28)
7430 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
7431         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
7432 {
7433     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7434     return call_num_put_wchar_do_put_long(this, ret, dest, base, fill, v);
7435 }
7436
7437 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WK@Z */
7438 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WK@Z */
7439 #define call_num_put_wchar_do_put_ulong(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 24, ostreambuf_iterator_wchar*, \
7440         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, ULONG), \
7441         (this, ret, dest, base, fill, v))
7442 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_ulong, 28)
7443 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
7444         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
7445 {
7446     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7447     char fmt[7]; /* strlen("%+#lld")+1 */
7448
7449     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7450
7451     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7452             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lu", base->fmtfl), v));
7453 }
7454
7455 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GK@Z */
7456 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GK@Z */
7457 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_ulong, 28)
7458 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
7459         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
7460 {
7461     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7462     char fmt[7]; /* strlen("%+#lld")+1 */
7463
7464     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7465
7466     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7467             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lu", base->fmtfl), v));
7468 }
7469
7470 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WK@Z */
7471 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WK@Z */
7472 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GK@Z */
7473 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GK@Z */
7474 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ulong, 28)
7475 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
7476         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
7477 {
7478     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7479     return call_num_put_wchar_do_put_ulong(this, ret, dest, base, fill, v);
7480 }
7481
7482 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WN@Z */
7483 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WN@Z */
7484 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WO@Z */
7485 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WO@Z */
7486 #define call_num_put_wchar_do_put_double(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 12, ostreambuf_iterator_wchar*, \
7487         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, double), \
7488         (this, ret, dest, base, fill, v))
7489 #define call_num_put_wchar_do_put_ldouble(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 8, ostreambuf_iterator_wchar*, \
7490         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, double), \
7491         (this, ret, dest, base, fill, v))
7492 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_double, 32)
7493 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
7494         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7495 {
7496     char *tmp;
7497     char fmt[8]; /* strlen("%+#.*lg")+1 */
7498     int size;
7499     streamsize prec;
7500
7501     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7502
7503     num_put_wchar__Ffmt(this, fmt, '\0', base->fmtfl);
7504     prec = get_precision(base);
7505     size = _scprintf(fmt, prec, v);
7506
7507     /* TODO: don't use dynamic allocation */
7508     tmp = MSVCRT_operator_new(size*2);
7509     if(!tmp) {
7510         ERR("Out of memory\n");
7511         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7512     }
7513     num_put__fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, prec, v),
7514             numpunct_wchar_use_facet(base->loc));
7515     MSVCRT_operator_delete(tmp);
7516     return ret;
7517 }
7518
7519 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GN@Z */
7520 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GN@Z */
7521 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GO@Z */
7522 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GO@Z */
7523 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_double, 32)
7524 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
7525         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7526 {
7527     char *tmp;
7528     char fmt[8]; /* strlen("%+#.*lg")+1 */
7529     int size;
7530     streamsize prec;
7531
7532     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7533
7534     num_put_wchar__Ffmt(this, fmt, '\0', base->fmtfl);
7535     prec = get_precision(base);
7536     size = _scprintf(fmt, prec, v);
7537
7538     /* TODO: don't use dynamic allocation */
7539     tmp = MSVCRT_operator_new(size*2);
7540     if(!tmp) {
7541         ERR("Out of memory\n");
7542         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7543     }
7544     num_put__fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, prec, v),
7545             numpunct_short_use_facet(base->loc));
7546     MSVCRT_operator_delete(tmp);
7547     return ret;
7548 }
7549
7550 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WN@Z */
7551 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WN@Z */
7552 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GN@Z */
7553 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GN@Z */
7554 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_double, 32)
7555 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
7556         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7557 {
7558     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7559     return call_num_put_wchar_do_put_double(this, ret, dest, base, fill, v);
7560 }
7561
7562 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WO@Z */
7563 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WO@Z */
7564 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GO@Z */
7565 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GO@Z */
7566 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ldouble, 32)
7567 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ldouble(const num_put *this, ostreambuf_iterator_wchar *ret,
7568         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7569 {
7570     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7571     return call_num_put_wchar_do_put_ldouble(this, ret, dest, base, fill, v);
7572 }
7573
7574 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WPBX@Z */
7575 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WPEBX@Z */
7576 #define call_num_put_wchar_do_put_ptr(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 4, ostreambuf_iterator_wchar*, \
7577         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, const void*), \
7578         (this, ret, dest, base, fill, v))
7579 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_ptr, 28)
7580 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
7581         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
7582 {
7583     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
7584
7585     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7586
7587     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
7588 }
7589
7590 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GPBX@Z */
7591 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GPEBX@Z */
7592 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_ptr, 28)
7593 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
7594         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
7595 {
7596     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
7597
7598     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7599
7600     return num_put_short__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
7601 }
7602
7603 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WPBX@Z */
7604 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WPEBX@Z */
7605 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GPBX@Z */
7606 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GPEBX@Z */
7607 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ptr, 28)
7608 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
7609         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
7610 {
7611     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7612     return call_num_put_wchar_do_put_ptr(this, ret, dest, base, fill, v);
7613 }
7614
7615 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_J@Z */
7616 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_J@Z */
7617 #define call_num_put_wchar_do_put_int64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 20, ostreambuf_iterator_wchar*, \
7618         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, __int64), \
7619         (this, ret, dest, base, fill, v))
7620 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_int64, 32)
7621 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7622         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7623 {
7624     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7625     char fmt[7]; /* strlen("%+#lld")+1 */
7626
7627     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7628
7629     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7630             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lld", base->fmtfl), v));
7631 }
7632
7633 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_J@Z */
7634 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_J@Z */
7635 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_int64, 32)
7636 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7637         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7638 {
7639     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7640     char fmt[7]; /* strlen("%+#lld")+1 */
7641
7642     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7643
7644     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7645             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lld", base->fmtfl), v));
7646 }
7647
7648 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_J@Z */
7649 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_J@Z */
7650 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_J@Z */
7651 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_J@Z */
7652 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_int64, 32)
7653 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7654         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7655 {
7656     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7657     return call_num_put_wchar_do_put_int64(this, ret, dest, base, fill, v);
7658 }
7659
7660 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_K@Z */
7661 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_K@Z */
7662 #define call_num_put_wchar_do_put_uint64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 16, ostreambuf_iterator_wchar*, \
7663         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, unsigned __int64), \
7664         (this, ret, dest, base, fill, v))
7665 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_uint64, 32)
7666 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7667         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7668 {
7669     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7670     char fmt[7]; /* strlen("%+#lld")+1 */
7671
7672     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7673
7674     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7675             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "llu", base->fmtfl), v));
7676 }
7677
7678 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_K@Z */
7679 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_K@Z */
7680 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_uint64, 32)
7681 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7682         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7683 {
7684     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7685     char fmt[7]; /* strlen("%+#lld")+1 */
7686
7687     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7688
7689     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7690             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "llu", base->fmtfl), v));
7691 }
7692
7693 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_K@Z */
7694 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_K@Z */
7695 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_K@Z */
7696 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_K@Z */
7697 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_uint64, 32)
7698 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7699         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7700 {
7701     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7702     return call_num_put_wchar_do_put_uint64(this, ret, dest, base, fill, v);
7703 }
7704
7705 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_N@Z */
7706 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_N@Z */
7707 #define call_num_put_wchar_do_put_bool(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 32, ostreambuf_iterator_wchar*, \
7708         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, MSVCP_bool), \
7709         (this, ret, dest, base, fill, v))
7710 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_bool, 28)
7711 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7712         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7713 {
7714     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7715
7716     if(base->fmtfl & FMTFLAG_boolalpha) {
7717         numpunct_wchar *numpunct = numpunct_wchar_use_facet(base->loc);
7718         basic_string_wchar str;
7719         MSVCP_size_t pad, len;
7720
7721         if(v)
7722             numpunct_wchar_truename(numpunct, &str);
7723         else
7724             numpunct_wchar_falsename(numpunct, &str);
7725
7726         len = MSVCP_basic_string_wchar_length(&str);
7727         pad = (len>base->wide ? 0 : base->wide-len);
7728         base->wide = 0;
7729
7730         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
7731             num_put_wchar__Rep(this, &dest, dest, fill, pad);
7732             pad = 0;
7733         }
7734         num_put_wchar__Put(this, &dest, dest, MSVCP_basic_string_wchar_c_str(&str), len);
7735         MSVCP_basic_string_wchar_dtor(&str);
7736         return num_put_wchar__Rep(this, ret, dest, fill, pad);
7737     }
7738
7739     return num_put_wchar_put_long(this, ret, dest, base, fill, v);
7740 }
7741
7742 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_N@Z */
7743 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_N@Z */
7744 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_bool, 28)
7745 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7746         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7747 {
7748     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7749
7750     if(base->fmtfl & FMTFLAG_boolalpha) {
7751         numpunct_wchar *numpunct = numpunct_short_use_facet(base->loc);
7752         basic_string_wchar str;
7753         MSVCP_size_t pad, len;
7754
7755         if(v)
7756             numpunct_wchar_truename(numpunct, &str);
7757         else
7758             numpunct_wchar_falsename(numpunct, &str);
7759
7760         len = MSVCP_basic_string_wchar_length(&str);
7761         pad = (len>base->wide ? 0 : base->wide-len);
7762         base->wide = 0;
7763
7764         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
7765             num_put_wchar__Rep(this, &dest, dest, fill, pad);
7766             pad = 0;
7767         }
7768         num_put_wchar__Put(this, &dest, dest, MSVCP_basic_string_wchar_c_str(&str), len);
7769         MSVCP_basic_string_wchar_dtor(&str);
7770         return num_put_wchar__Rep(this, ret, dest, fill, pad);
7771     }
7772
7773     return num_put_wchar_put_long(this, ret, dest, base, fill, v);
7774 }
7775
7776 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_N@Z */
7777 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_N@Z */
7778 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_N@Z */
7779 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_N@Z */
7780 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_bool, 28)
7781 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7782         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7783 {
7784     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7785     return call_num_put_wchar_do_put_bool(this, ret, dest, base, fill, v);
7786 }
7787
7788 /* ??0_Locimp@locale@std@@AAE@_N@Z */
7789 /* ??0_Locimp@locale@std@@AEAA@_N@Z */
7790 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor_transparent, 8)
7791 locale__Locimp* __thiscall locale__Locimp_ctor_transparent(locale__Locimp *this, MSVCP_bool transparent)
7792 {
7793     TRACE("(%p %d)\n", this, transparent);
7794
7795     memset(this, 0, sizeof(locale__Locimp));
7796     locale_facet_ctor_refs(&this->facet, 1);
7797     this->transparent = transparent;
7798     MSVCP_basic_string_char_ctor_cstr(&this->name, "*");
7799     return this;
7800 }
7801
7802 /* ??_F_Locimp@locale@std@@QAEXXZ */
7803 /* ??_F_Locimp@locale@std@@QEAAXXZ */
7804 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor, 4)
7805 locale__Locimp* __thiscall locale__Locimp_ctor(locale__Locimp *this)
7806 {
7807     return locale__Locimp_ctor_transparent(this, FALSE);
7808 }
7809
7810 /* ??0_Locimp@locale@std@@AAE@ABV012@@Z */
7811 /* ??0_Locimp@locale@std@@AEAA@AEBV012@@Z */
7812 DEFINE_THISCALL_WRAPPER(locale__Locimp_copy_ctor, 8)
7813 locale__Locimp* __thiscall locale__Locimp_copy_ctor(locale__Locimp *this, const locale__Locimp *copy)
7814 {
7815     _Lockit lock;
7816     MSVCP_size_t i;
7817
7818     TRACE("(%p %p)\n", this, copy);
7819
7820     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7821     memcpy(this, copy, sizeof(locale__Locimp));
7822     locale_facet_ctor_refs(&this->facet, 1);
7823     if(copy->facetvec) {
7824         this->facetvec = MSVCRT_operator_new(copy->facet_cnt*sizeof(locale_facet*));
7825         if(!this->facetvec) {
7826             _Lockit_dtor(&lock);
7827             ERR("Out of memory\n");
7828             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7829             return NULL;
7830         }
7831         for(i=0; i<this->facet_cnt; i++)
7832         {
7833             this->facetvec[i] = copy->facetvec[i];
7834             if(this->facetvec[i])
7835                 locale_facet__Incref(this->facetvec[i]);
7836         }
7837     }
7838     MSVCP_basic_string_char_copy_ctor(&this->name, &copy->name);
7839     _Lockit_dtor(&lock);
7840     return this;
7841 }
7842
7843 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPAV123@ABV123@@Z */
7844 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPEAV123@AEBV123@@Z */
7845 locale__Locimp* __cdecl locale__Locimp__Locimp_ctor(locale__Locimp *this, const locale__Locimp *copy)
7846 {
7847     return locale__Locimp_copy_ctor(this, copy);
7848 }
7849
7850 /* ??1_Locimp@locale@std@@MAE@XZ */
7851 /* ??1_Locimp@locale@std@@MEAA@XZ */
7852 DEFINE_THISCALL_WRAPPER(locale__Locimp_dtor, 4)
7853 void __thiscall locale__Locimp_dtor(locale__Locimp *this)
7854 {
7855     MSVCP_size_t i;
7856
7857     TRACE("(%p)\n", this);
7858
7859     locale_facet_dtor(&this->facet);
7860     for(i=0; i<this->facet_cnt; i++)
7861         if(this->facetvec[i] && locale_facet__Decref(this->facetvec[i]))
7862             call_locale_facet_vector_dtor(this->facetvec[i], 1);
7863
7864     MSVCRT_operator_delete(this->facetvec);
7865     MSVCP_basic_string_char_dtor(&this->name);
7866 }
7867
7868 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPAV123@@Z */
7869 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPEAV123@@Z */
7870 void __cdecl locale__Locimp__Locimp_dtor(locale__Locimp *this)
7871 {
7872     locale__Locimp_dtor(this);
7873 }
7874
7875 DEFINE_THISCALL_WRAPPER(locale__Locimp_vector_dtor, 8)
7876 locale__Locimp* __thiscall locale__Locimp_vector_dtor(locale__Locimp *this, unsigned int flags)
7877 {
7878     TRACE("(%p %x)\n", this, flags);
7879     if(flags & 2) {
7880         /* we have an array, with the number of elements stored before the first object */
7881         INT_PTR i, *ptr = (INT_PTR *)this-1;
7882
7883         for(i=*ptr-1; i>=0; i--)
7884             locale__Locimp_dtor(this+i);
7885         MSVCRT_operator_delete(ptr);
7886     } else {
7887         locale__Locimp_dtor(this);
7888         if(flags & 1)
7889             MSVCRT_operator_delete(this);
7890     }
7891
7892     return this;
7893 }
7894
7895 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPAV123@PAVfacet@23@I@Z */
7896 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPEAV123@PEAVfacet@23@_K@Z */
7897 void __cdecl locale__Locimp__Locimp_Addfac(locale__Locimp *locimp, locale_facet *facet, MSVCP_size_t id)
7898 {
7899     _Lockit lock;
7900
7901     TRACE("(%p %p %lu)\n", locimp, facet, id);
7902
7903     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7904     if(id >= locimp->facet_cnt) {
7905         MSVCP_size_t new_size = id+1;
7906         locale_facet **new_facetvec;
7907
7908         if(new_size < locale_id__Id_cnt+1)
7909             new_size = locale_id__Id_cnt+1;
7910
7911         new_facetvec = MSVCRT_operator_new(sizeof(locale_facet*)*new_size);
7912         if(!new_facetvec) {
7913             _Lockit_dtor(&lock);
7914             ERR("Out of memory\n");
7915             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7916             return;
7917         }
7918
7919         memset(new_facetvec, 0, sizeof(locale_facet*)*new_size);
7920         memcpy(new_facetvec, locimp->facetvec, sizeof(locale_facet*)*locimp->facet_cnt);
7921         MSVCRT_operator_delete(locimp->facetvec);
7922         locimp->facetvec = new_facetvec;
7923         locimp->facet_cnt = new_size;
7924     }
7925
7926     if(locimp->facetvec[id] && locale_facet__Decref(locimp->facetvec[id]))
7927         call_locale_facet_vector_dtor(locimp->facetvec[id], 1);
7928
7929     locimp->facetvec[id] = facet;
7930     if(facet)
7931         locale_facet__Incref(facet);
7932     _Lockit_dtor(&lock);
7933 }
7934
7935 /* ?_Addfac@_Locimp@locale@std@@AAEXPAVfacet@23@I@Z */
7936 /* ?_Addfac@_Locimp@locale@std@@AEAAXPEAVfacet@23@_K@Z */
7937 DEFINE_THISCALL_WRAPPER(locale__Locimp__Addfac, 12)
7938 void __thiscall locale__Locimp__Addfac(locale__Locimp *this, locale_facet *facet, MSVCP_size_t id)
7939 {
7940     locale__Locimp__Locimp_Addfac(this, facet, id);
7941 }
7942
7943 /* ?_Clocptr_func@_Locimp@locale@std@@CAAAPAV123@XZ */
7944 /* ?_Clocptr_func@_Locimp@locale@std@@CAAEAPEAV123@XZ */
7945 locale__Locimp** __cdecl locale__Locimp__Clocptr_func(void)
7946 {
7947     FIXME("stub\n");
7948     return NULL;
7949 }
7950
7951 /* ?_Makeushloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
7952 /* ?_Makeushloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
7953 /* List of missing facets:
7954  * num_put, collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
7955  */
7956 void __cdecl locale__Locimp__Makeushloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
7957 {
7958     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
7959
7960     if(cat & (1<<(ctype_short__Getcat(NULL, NULL)-1))) {
7961         ctype_wchar *ctype;
7962
7963         if(loc) {
7964             ctype = ctype_short_use_facet(loc);
7965         }else {
7966             ctype = MSVCRT_operator_new(sizeof(ctype_wchar));
7967             if(!ctype) {
7968                 ERR("Out of memory\n");
7969                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7970             }
7971             ctype_short_ctor_locinfo(ctype, locinfo, 0);
7972         }
7973         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_short_id));
7974     }
7975
7976     if(cat & (1<<(num_get_short__Getcat(NULL, NULL)-1))) {
7977         num_get *numget;
7978
7979         if(loc) {
7980             numget = num_get_short_use_facet(loc);
7981         }else {
7982             numget = MSVCRT_operator_new(sizeof(num_get));
7983             if(!numget) {
7984                 ERR("Out of memory\n");
7985                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7986             }
7987             num_get_short_ctor_locinfo(numget, locinfo, 0);
7988         }
7989         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_short_id));
7990     }
7991
7992     if(cat & (1<<(num_put_short__Getcat(NULL, NULL)-1))) {
7993         num_put *numput;
7994
7995         if(loc) {
7996             numput = num_put_short_use_facet(loc);
7997         }else {
7998             numput = MSVCRT_operator_new(sizeof(num_put));
7999             if(!numput) {
8000                 ERR("Out of memory\n");
8001                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8002             }
8003             num_put_short_ctor_locinfo(numput, locinfo, 0);
8004         }
8005         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_short_id));
8006     }
8007
8008     if(cat & (1<<(numpunct_short__Getcat(NULL, NULL)-1))) {
8009         numpunct_wchar *numpunct;
8010
8011         if(loc) {
8012             numpunct = numpunct_short_use_facet(loc);
8013         }else {
8014             numpunct = MSVCRT_operator_new(sizeof(numpunct_wchar));
8015             if(!numpunct) {
8016                 ERR("Out of memory\n");
8017                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8018             }
8019             numpunct_short_ctor_locinfo(numpunct, locinfo, 0, FALSE);
8020         }
8021         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_short_id));
8022     }
8023
8024     if(cat & (1<<(codecvt_short__Getcat(NULL, NULL)-1))) {
8025         codecvt_wchar *codecvt;
8026
8027         if(loc) {
8028             codecvt = codecvt_short_use_facet(loc);
8029         }else {
8030             codecvt = MSVCRT_operator_new(sizeof(codecvt_wchar));
8031             if(!codecvt) {
8032                 ERR("Out of memory\n");
8033                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8034             }
8035             codecvt_short_ctor_locinfo(codecvt, locinfo, 0);
8036         }
8037         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_short_id));
8038     }
8039 }
8040
8041 /* ?_Makewloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
8042 /* ?_Makewloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
8043 /* List of missing facets:
8044  * collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
8045  */
8046 void __cdecl locale__Locimp__Makewloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
8047 {
8048     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
8049
8050     if(cat & (1<<(ctype_wchar__Getcat(NULL, NULL)-1))) {
8051         ctype_wchar *ctype;
8052
8053         if(loc) {
8054             ctype = ctype_wchar_use_facet(loc);
8055         }else {
8056             ctype = MSVCRT_operator_new(sizeof(ctype_wchar));
8057             if(!ctype) {
8058                 ERR("Out of memory\n");
8059                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8060             }
8061             ctype_wchar_ctor_locinfo(ctype, locinfo, 0);
8062         }
8063         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_wchar_id));
8064     }
8065
8066     if(cat & (1<<(num_get_wchar__Getcat(NULL, NULL)-1))) {
8067         num_get *numget;
8068
8069         if(loc) {
8070             numget = num_get_wchar_use_facet(loc);
8071         }else {
8072             numget = MSVCRT_operator_new(sizeof(num_get));
8073             if(!numget) {
8074                 ERR("Out of memory\n");
8075                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8076             }
8077             num_get_wchar_ctor_locinfo(numget, locinfo, 0);
8078         }
8079         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_wchar_id));
8080     }
8081
8082     if(cat & (1<<(num_put_wchar__Getcat(NULL, NULL)-1))) {
8083         num_put *numput;
8084
8085         if(loc) {
8086             numput = num_put_wchar_use_facet(loc);
8087         }else {
8088             numput = MSVCRT_operator_new(sizeof(num_put));
8089             if(!numput) {
8090                 ERR("Out of memory\n");
8091                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8092             }
8093             num_put_wchar_ctor_locinfo(numput, locinfo, 0);
8094         }
8095         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_wchar_id));
8096     }
8097
8098     if(cat & (1<<(numpunct_wchar__Getcat(NULL, NULL)-1))) {
8099         numpunct_wchar *numpunct;
8100
8101         if(loc) {
8102             numpunct = numpunct_wchar_use_facet(loc);
8103         }else {
8104             numpunct = MSVCRT_operator_new(sizeof(numpunct_wchar));
8105             if(!numpunct) {
8106                 ERR("Out of memory\n");
8107                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8108             }
8109             numpunct_wchar_ctor_locinfo(numpunct, locinfo, 0, FALSE);
8110         }
8111         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_wchar_id));
8112     }
8113
8114     if(cat & (1<<(codecvt_wchar__Getcat(NULL, NULL)-1))) {
8115         codecvt_wchar *codecvt;
8116
8117         if(loc) {
8118             codecvt = codecvt_wchar_use_facet(loc);
8119         }else {
8120             codecvt = MSVCRT_operator_new(sizeof(codecvt_wchar));
8121             if(!codecvt) {
8122                 ERR("Out of memory\n");
8123                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8124             }
8125             codecvt_wchar_ctor_locinfo(codecvt, locinfo, 0);
8126         }
8127         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_wchar_id));
8128     }
8129 }
8130
8131 /* ?_Makexloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
8132 /* ?_Makexloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
8133 /* List of missing facets:
8134  * collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
8135  */
8136 void __cdecl locale__Locimp__Makexloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
8137 {
8138     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
8139
8140     if(cat & (1<<(ctype_char__Getcat(NULL, NULL)-1))) {
8141         ctype_char *ctype;
8142
8143         if(loc) {
8144             ctype = ctype_char_use_facet(loc);
8145         }else {
8146             ctype = MSVCRT_operator_new(sizeof(ctype_char));
8147             if(!ctype) {
8148                 ERR("Out of memory\n");
8149                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8150             }
8151             ctype_char_ctor_locinfo(ctype, locinfo, 0);
8152         }
8153         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_char_id));
8154     }
8155
8156     if(cat & (1<<(num_get_char__Getcat(NULL, NULL)-1))) {
8157         num_get *numget;
8158
8159         if(loc) {
8160             numget = num_get_char_use_facet(loc);
8161         }else {
8162             numget = MSVCRT_operator_new(sizeof(num_get));
8163             if(!numget) {
8164                 ERR("Out of memory\n");
8165                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8166             }
8167             num_get_char_ctor_locinfo(numget, locinfo, 0);
8168         }
8169         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_char_id));
8170     }
8171
8172     if(cat & (1<<(num_put_char__Getcat(NULL, NULL)-1))) {
8173         num_put *numput;
8174
8175         if(loc) {
8176             numput = num_put_char_use_facet(loc);
8177         }else {
8178             numput = MSVCRT_operator_new(sizeof(num_put));
8179             if(!numput) {
8180                 ERR("Out of memory\n");
8181                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8182             }
8183             num_put_char_ctor_locinfo(numput, locinfo, 0);
8184         }
8185         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_char_id));
8186     }
8187
8188     if(cat & (1<<(numpunct_char__Getcat(NULL, NULL)-1))) {
8189         numpunct_char *numpunct;
8190
8191         if(loc) {
8192             numpunct = numpunct_char_use_facet(loc);
8193         }else {
8194             numpunct = MSVCRT_operator_new(sizeof(numpunct_char));
8195             if(!numpunct) {
8196                 ERR("Out of memory\n");
8197                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8198             }
8199             numpunct_char_ctor_locinfo(numpunct, locinfo, 0, FALSE);
8200         }
8201         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_char_id));
8202     }
8203
8204     if(cat & (1<<(codecvt_char__Getcat(NULL, NULL)-1))) {
8205         codecvt_char *codecvt;
8206
8207         if(loc) {
8208             codecvt = codecvt_char_use_facet(loc);
8209         }else {
8210             codecvt = MSVCRT_operator_new(sizeof(codecvt_char));
8211             if(!codecvt) {
8212                 ERR("Out of memory\n");
8213                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8214             }
8215             codecvt_char_ctor_locinfo(codecvt, locinfo, 0);
8216         }
8217         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_char_id));
8218     }
8219 }
8220
8221 /* ?_Makeloc@_Locimp@locale@std@@CAPAV123@ABV_Locinfo@3@HPAV123@PBV23@@Z */
8222 /* ?_Makeloc@_Locimp@locale@std@@CAPEAV123@AEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
8223 locale__Locimp* __cdecl locale__Locimp__Makeloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
8224 {
8225     TRACE("(%p %d %p %p)\n", locinfo, cat, locimp, loc);
8226
8227     locale__Locimp__Makexloc(locinfo, cat, locimp, loc);
8228     locale__Locimp__Makewloc(locinfo, cat, locimp, loc);
8229     locale__Locimp__Makeushloc(locinfo, cat, locimp, loc);
8230
8231     locimp->catmask |= cat;
8232     MSVCP_basic_string_char_copy_ctor(&locimp->name, &locinfo->newlocname);
8233     return locimp;
8234 }
8235
8236 /* ??_7_Locimp@locale@std@@6B@ */
8237 const vtable_ptr MSVCP_locale__Locimp_vtable[] = {
8238     (vtable_ptr)THISCALL_NAME(locale__Locimp_vector_dtor)
8239 };
8240
8241 /* ??0locale@std@@AAE@PAV_Locimp@01@@Z */
8242 /* ??0locale@std@@AEAA@PEAV_Locimp@01@@Z */
8243 DEFINE_THISCALL_WRAPPER(locale_ctor_locimp, 8)
8244 locale* __thiscall locale_ctor_locimp(locale *this, locale__Locimp *locimp)
8245 {
8246     TRACE("(%p %p)\n", this, locimp);
8247     /* Don't change locimp reference counter */
8248     this->ptr = locimp;
8249     return this;
8250 }
8251
8252 /* ?_Init@locale@std@@CAPAV_Locimp@12@XZ */
8253 /* ?_Init@locale@std@@CAPEAV_Locimp@12@XZ */
8254 locale__Locimp* __cdecl locale__Init(void)
8255 {
8256     _Lockit lock;
8257
8258     TRACE("\n");
8259
8260     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
8261     if(global_locale) {
8262         _Lockit_dtor(&lock);
8263         return global_locale;
8264     }
8265
8266     global_locale = MSVCRT_operator_new(sizeof(locale__Locimp));
8267     if(!global_locale) {
8268         _Lockit_dtor(&lock);
8269         ERR("Out of memory\n");
8270         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8271         return NULL;
8272     }
8273
8274     locale__Locimp_ctor(global_locale);
8275     global_locale->catmask = (1<<(LC_MAX+1))-1;
8276     MSVCP_basic_string_char_dtor(&global_locale->name);
8277     MSVCP_basic_string_char_ctor_cstr(&global_locale->name, "C");
8278
8279     locale__Locimp__Clocptr = global_locale;
8280     global_locale->facet.refs++;
8281     locale_ctor_locimp(&classic_locale, locale__Locimp__Clocptr);
8282     _Lockit_dtor(&lock);
8283
8284     return global_locale;
8285 }
8286
8287 /* ??0locale@std@@QAE@ABV01@0H@Z */
8288 /* ??0locale@std@@QEAA@AEBV01@0H@Z */
8289 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_locale, 16)
8290 locale* __thiscall locale_ctor_locale_locale(locale *this, const locale *loc, const locale *other, category cat)
8291 {
8292     _Locinfo locinfo;
8293
8294     TRACE("(%p %p %p %d)\n", this, loc, other, cat);
8295
8296     this->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
8297     if(!this->ptr) {
8298         ERR("Out of memory\n");
8299         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8300     }
8301     locale__Locimp_copy_ctor(this->ptr, loc->ptr);
8302
8303     _Locinfo_ctor_cat_cstr(&locinfo, loc->ptr->catmask, MSVCP_basic_string_char_c_str(&loc->ptr->name));
8304     _Locinfo__Addcats(&locinfo, cat & other->ptr->catmask, MSVCP_basic_string_char_c_str(&other->ptr->name));
8305     locale__Locimp__Makeloc(&locinfo, cat, this->ptr, other);
8306     _Locinfo_dtor(&locinfo);
8307
8308     return this;
8309 }
8310
8311 /* ??0locale@std@@QAE@ABV01@@Z */
8312 /* ??0locale@std@@QEAA@AEBV01@@Z */
8313 DEFINE_THISCALL_WRAPPER(locale_copy_ctor, 8)
8314 locale* __thiscall locale_copy_ctor(locale *this, const locale *copy)
8315 {
8316     TRACE("(%p %p)\n", this, copy);
8317     this->ptr = copy->ptr;
8318     locale_facet__Incref(&this->ptr->facet);
8319     return this;
8320 }
8321
8322 /* ??0locale@std@@QAE@ABV01@PBDH@Z */
8323 /* ??0locale@std@@QEAA@AEBV01@PEBDH@Z */
8324 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_cstr, 16)
8325 locale* __thiscall locale_ctor_locale_cstr(locale *this, const locale *loc, const char *locname, category cat)
8326 {
8327     FIXME("(%p %p %s %d) stub\n", this, loc, locname, cat);
8328     return NULL;
8329 }
8330
8331 /* ??0locale@std@@QAE@PBDH@Z */
8332 /* ??0locale@std@@QEAA@PEBDH@Z */
8333 DEFINE_THISCALL_WRAPPER(locale_ctor_cstr, 12)
8334 locale* __thiscall locale_ctor_cstr(locale *this, const char *locname, category cat)
8335 {
8336     _Locinfo locinfo;
8337
8338     TRACE("(%p %s %d)\n", this, locname, cat);
8339
8340     this->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
8341     if(!this->ptr) {
8342         ERR("Out of memory\n");
8343         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8344     }
8345     locale__Locimp_ctor(this->ptr);
8346
8347     locale__Init();
8348
8349     _Locinfo_ctor_cat_cstr(&locinfo, cat, locname);
8350     if(!memcmp(MSVCP_basic_string_char_c_str(&locinfo.newlocname), "*", 2)) {
8351         _Locinfo_dtor(&locinfo);
8352         MSVCRT_operator_delete(this->ptr);
8353         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
8354     }
8355
8356     locale__Locimp__Makeloc(&locinfo, cat, this->ptr, NULL);
8357     _Locinfo_dtor(&locinfo);
8358
8359     return this;
8360 }
8361
8362 /* ??0locale@std@@QAE@W4_Uninitialized@1@@Z */
8363 /* ??0locale@std@@QEAA@W4_Uninitialized@1@@Z */
8364 DEFINE_THISCALL_WRAPPER(locale_ctor_uninitialized, 8)
8365 locale* __thiscall locale_ctor_uninitialized(locale *this, int uninitialized)
8366 {
8367     TRACE("(%p)\n", this);
8368     this->ptr = NULL;
8369     return this;
8370 }
8371
8372 /* ??0locale@std@@QAE@XZ */
8373 /* ??0locale@std@@QEAA@XZ */
8374 DEFINE_THISCALL_WRAPPER(locale_ctor, 4)
8375 locale* __thiscall locale_ctor(locale *this)
8376 {
8377     TRACE("(%p)\n", this);
8378     this->ptr = locale__Init();
8379     locale_facet__Incref(&this->ptr->facet);
8380     return this;
8381 }
8382
8383 /* ??1locale@std@@QAE@XZ */
8384 /* ??1locale@std@@QEAA@XZ */
8385 DEFINE_THISCALL_WRAPPER(locale_dtor, 4)
8386 void __thiscall locale_dtor(locale *this)
8387 {
8388     TRACE("(%p)\n", this);
8389     if(this->ptr && locale_facet__Decref(&this->ptr->facet))
8390     {
8391         locale__Locimp_dtor(this->ptr);
8392         MSVCRT_operator_delete(this->ptr);
8393     }
8394 }
8395
8396 /* ??4locale@std@@QAEAAV01@ABV01@@Z */
8397 /* ??4locale@std@@QEAAAEAV01@AEBV01@@Z */
8398 DEFINE_THISCALL_WRAPPER(locale_operator_assign, 8)
8399 locale* __thiscall locale_operator_assign(locale *this, const locale *loc)
8400 {
8401     FIXME("(%p %p) stub\n", this, loc);
8402     return NULL;
8403 }
8404
8405 /* ??8locale@std@@QBE_NABV01@@Z */
8406 /* ??8locale@std@@QEBA_NAEBV01@@Z */
8407 DEFINE_THISCALL_WRAPPER(locale_operator_equal, 8)
8408 MSVCP_bool __thiscall locale_operator_equal(const locale *this, const locale *loc)
8409 {
8410     FIXME("(%p %p) stub\n", this, loc);
8411     return 0;
8412 }
8413
8414 /* ??9locale@std@@QBE_NABV01@@Z */
8415 /* ??9locale@std@@QEBA_NAEBV01@@Z */
8416 DEFINE_THISCALL_WRAPPER(locale_operator_not_equal, 8)
8417 MSVCP_bool __thiscall locale_operator_not_equal(const locale *this, locale const *loc)
8418 {
8419     FIXME("(%p %p) stub\n", this, loc);
8420     return 0;
8421 }
8422
8423 /* ?_Addfac@locale@std@@QAEAAV12@PAVfacet@12@II@Z */
8424 /* ?_Addfac@locale@std@@QEAAAEAV12@PEAVfacet@12@_K1@Z */
8425 DEFINE_THISCALL_WRAPPER(locale__Addfac, 16)
8426 locale* __thiscall locale__Addfac(locale *this, locale_facet *facet, MSVCP_size_t id, MSVCP_size_t catmask)
8427 {
8428     TRACE("(%p %p %lu %lu)\n", this, facet, id, catmask);
8429
8430     if(this->ptr->facet.refs > 1) {
8431         locale__Locimp *new_ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
8432         if(!new_ptr) {
8433             ERR("Out of memory\n");
8434             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8435             return NULL;
8436         }
8437         locale__Locimp_copy_ctor(new_ptr, this->ptr);
8438         locale_facet__Decref(&this->ptr->facet);
8439         this->ptr = new_ptr;
8440     }
8441
8442     locale__Locimp__Addfac(this->ptr, facet, id);
8443
8444     if(catmask) {
8445         MSVCP_basic_string_char_dtor(&this->ptr->name);
8446         MSVCP_basic_string_char_ctor_cstr(&this->ptr->name, "*");
8447     }
8448     return this;
8449 }
8450
8451 /* ?_Getfacet@locale@std@@QBEPBVfacet@12@I@Z */
8452 /* ?_Getfacet@locale@std@@QEBAPEBVfacet@12@_K@Z */
8453 DEFINE_THISCALL_WRAPPER(locale__Getfacet, 8)
8454 const locale_facet* __thiscall locale__Getfacet(const locale *this, MSVCP_size_t id)
8455 {
8456     locale_facet *fac;
8457
8458     TRACE("(%p %lu)\n", this, id);
8459
8460     fac = id < this->ptr->facet_cnt ? this->ptr->facetvec[id] : NULL;
8461     if(fac || !this->ptr->transparent)
8462         return fac;
8463
8464     return id < global_locale->facet_cnt ? global_locale->facetvec[id] : NULL;
8465 }
8466
8467 /* ?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ */
8468 /* ?_Getgloballocale@locale@std@@CAPEAV_Locimp@12@XZ */
8469 locale__Locimp* __cdecl locale__Getgloballocale(void)
8470 {
8471     TRACE("\n");
8472     return global_locale;
8473 }
8474
8475 /* ?_Setgloballocale@locale@std@@CAXPAX@Z */
8476 /* ?_Setgloballocale@locale@std@@CAXPEAX@Z */
8477 void __cdecl locale__Setgloballocale(void *locimp)
8478 {
8479     TRACE("(%p)\n", locimp);
8480     global_locale = locimp;
8481 }
8482
8483 /* ?classic@locale@std@@SAABV12@XZ */
8484 /* ?classic@locale@std@@SAAEBV12@XZ */
8485 const locale* __cdecl locale_classic(void)
8486 {
8487     TRACE("\n");
8488     locale__Init();
8489     return &classic_locale;
8490 }
8491
8492 /* ?empty@locale@std@@SA?AV12@XZ */
8493 locale* __cdecl locale_empty(locale *ret)
8494 {
8495     TRACE("\n");
8496
8497     locale__Init();
8498
8499     ret->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
8500     if(!ret->ptr) {
8501         ERR("Out of memory\n");
8502         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8503     }
8504     locale__Locimp_ctor_transparent(ret->ptr, TRUE);
8505     return ret;
8506 }
8507
8508 /* ?name@locale@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
8509 /* ?name@locale@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
8510 DEFINE_THISCALL_WRAPPER(locale_name, 8)
8511 basic_string_char* __thiscall locale_name(const locale *this, basic_string_char *ret)
8512 {
8513     TRACE( "(%p)\n", this);
8514     MSVCP_basic_string_char_copy_ctor(ret, &this->ptr->name);
8515     return ret;
8516 }
8517
8518 /* ?global@locale@std@@SA?AV12@ABV12@@Z */
8519 /* ?global@locale@std@@SA?AV12@AEBV12@@Z */
8520 locale* __cdecl locale_global(locale *ret, const locale *loc)
8521 {
8522     _Lockit lock;
8523     int i;
8524
8525     TRACE("(%p %p)\n", loc, ret);
8526
8527     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
8528     locale_ctor(ret);
8529
8530     if(loc->ptr != global_locale) {
8531         locale_facet__Decref(&global_locale->facet);
8532         global_locale = loc->ptr;
8533         locale_facet__Incref(&global_locale->facet);
8534
8535         for(i=LC_ALL+1; i<=LC_MAX; i++) {
8536             if((global_locale->catmask & (1<<(i-1))) == 0)
8537                 continue;
8538             setlocale(i, MSVCP_basic_string_char_c_str(&global_locale->name));
8539         }
8540     }
8541     _Lockit_dtor(&lock);
8542     return ret;
8543 }
8544
8545 /* wctrans */
8546 wctrans_t __cdecl wctrans(const char *property)
8547 {
8548     static const char str_tolower[] = "tolower";
8549     static const char str_toupper[] = "toupper";
8550
8551     if(!strcmp(property, str_tolower))
8552         return 2;
8553     if(!strcmp(property, str_toupper))
8554         return 1;
8555     return 0;
8556 }
8557
8558 /* towctrans */
8559 wint_t __cdecl towctrans(wint_t c, wctrans_t category)
8560 {
8561     if(category == 1)
8562         return towupper(c);
8563     return towlower(c);
8564 }
8565
8566 DEFINE_RTTI_DATA0(locale_facet, 0, ".?AVfacet@locale@std@@")
8567 DEFINE_RTTI_DATA1(collate_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@D@std@@")
8568 DEFINE_RTTI_DATA1(collate_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@_W@std@@")
8569 DEFINE_RTTI_DATA1(collate_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@G@std@@")
8570 DEFINE_RTTI_DATA1(ctype_base, 0, &locale_facet_rtti_base_descriptor, ".?AUctype_base@std@@")
8571 DEFINE_RTTI_DATA2(ctype_char, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@D@std@@")
8572 DEFINE_RTTI_DATA2(ctype_wchar, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@_W@std@@")
8573 DEFINE_RTTI_DATA2(ctype_short, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@G@std@@")
8574 DEFINE_RTTI_DATA1(codecvt_base, 0, &locale_facet_rtti_base_descriptor, ".?AVcodecvt_base@std@@")
8575 DEFINE_RTTI_DATA2(codecvt_char, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@DDH@std@@")
8576 DEFINE_RTTI_DATA2(codecvt_wchar, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@_WDH@std@@")
8577 DEFINE_RTTI_DATA2(codecvt_short, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@GDH@std@@")
8578 DEFINE_RTTI_DATA1(numpunct_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@D@std@@")
8579 DEFINE_RTTI_DATA1(numpunct_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@_W@std@@")
8580 DEFINE_RTTI_DATA1(numpunct_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@G@std@@")
8581 DEFINE_RTTI_DATA1(num_get_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@")
8582 DEFINE_RTTI_DATA1(num_get_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@")
8583 DEFINE_RTTI_DATA1(num_get_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@")
8584 DEFINE_RTTI_DATA1(num_put_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@")
8585 DEFINE_RTTI_DATA1(num_put_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@")
8586 DEFINE_RTTI_DATA1(num_put_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@")
8587
8588 #ifndef __GNUC__
8589 void __asm_dummy_vtables(void) {
8590 #endif
8591     __ASM_VTABLE(locale_facet,
8592             VTABLE_ADD_FUNC(locale_facet_vector_dtor));
8593     __ASM_VTABLE(collate_char,
8594             VTABLE_ADD_FUNC(collate_char_vector_dtor)
8595             VTABLE_ADD_FUNC(collate_char_do_compare)
8596             VTABLE_ADD_FUNC(collate_char_do_transform)
8597             VTABLE_ADD_FUNC(collate_char_do_hash));
8598     __ASM_VTABLE(collate_wchar,
8599             VTABLE_ADD_FUNC(collate_wchar_vector_dtor)
8600             VTABLE_ADD_FUNC(collate_wchar_do_compare)
8601             VTABLE_ADD_FUNC(collate_wchar_do_transform)
8602             VTABLE_ADD_FUNC(collate_wchar_do_hash));
8603     __ASM_VTABLE(collate_short,
8604             VTABLE_ADD_FUNC(collate_wchar_vector_dtor)
8605             VTABLE_ADD_FUNC(collate_wchar_do_compare)
8606             VTABLE_ADD_FUNC(collate_wchar_do_transform)
8607             VTABLE_ADD_FUNC(collate_wchar_do_hash));
8608     __ASM_VTABLE(ctype_base,
8609             VTABLE_ADD_FUNC(ctype_base_vector_dtor));
8610     __ASM_VTABLE(ctype_char,
8611             VTABLE_ADD_FUNC(ctype_char_vector_dtor)
8612             VTABLE_ADD_FUNC(ctype_char_do_tolower)
8613             VTABLE_ADD_FUNC(ctype_char_do_tolower_ch)
8614             VTABLE_ADD_FUNC(ctype_char_do_toupper)
8615             VTABLE_ADD_FUNC(ctype_char_do_toupper_ch)
8616             VTABLE_ADD_FUNC(ctype_char_do_widen)
8617             VTABLE_ADD_FUNC(ctype_char_do_widen_ch)
8618             VTABLE_ADD_FUNC(ctype_char__Do_widen_s)
8619             VTABLE_ADD_FUNC(ctype_char_do_narrow)
8620             VTABLE_ADD_FUNC(ctype_char_do_narrow_ch)
8621             VTABLE_ADD_FUNC(ctype_char__Do_narrow_s));
8622     __ASM_VTABLE(ctype_wchar,
8623             VTABLE_ADD_FUNC(ctype_wchar_vector_dtor)
8624             VTABLE_ADD_FUNC(ctype_wchar_do_is)
8625             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
8626             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
8627             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
8628             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
8629             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
8630             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
8631             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
8632             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
8633             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
8634             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
8635             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
8636             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
8637             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
8638     __ASM_VTABLE(ctype_short,
8639             VTABLE_ADD_FUNC(ctype_wchar_vector_dtor)
8640             VTABLE_ADD_FUNC(ctype_wchar_do_is)
8641             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
8642             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
8643             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
8644             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
8645             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
8646             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
8647             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
8648             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
8649             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
8650             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
8651             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
8652             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
8653             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
8654     __ASM_VTABLE(codecvt_base,
8655             VTABLE_ADD_FUNC(codecvt_base_vector_dtor)
8656             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
8657             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
8658             VTABLE_ADD_FUNC(codecvt_base_do_encoding));
8659     __ASM_VTABLE(codecvt_char,
8660             VTABLE_ADD_FUNC(codecvt_char_vector_dtor)
8661             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
8662             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
8663             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8664             VTABLE_ADD_FUNC(codecvt_char_do_in)
8665             VTABLE_ADD_FUNC(codecvt_char_do_out)
8666             VTABLE_ADD_FUNC(codecvt_char_do_unshift)
8667             VTABLE_ADD_FUNC(codecvt_char_do_length));
8668     __ASM_VTABLE(codecvt_wchar,
8669             VTABLE_ADD_FUNC(codecvt_wchar_vector_dtor)
8670             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
8671             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
8672             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8673             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
8674             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
8675             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
8676             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
8677     __ASM_VTABLE(codecvt_short,
8678             VTABLE_ADD_FUNC(codecvt_wchar_vector_dtor)
8679             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
8680             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
8681             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8682             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
8683             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
8684             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
8685             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
8686     __ASM_VTABLE(numpunct_char,
8687             VTABLE_ADD_FUNC(numpunct_char_vector_dtor)
8688             VTABLE_ADD_FUNC(numpunct_char_do_decimal_point)
8689             VTABLE_ADD_FUNC(numpunct_char_do_thousands_sep)
8690             VTABLE_ADD_FUNC(numpunct_char_do_grouping)
8691             VTABLE_ADD_FUNC(numpunct_char_do_falsename)
8692             VTABLE_ADD_FUNC(numpunct_char_do_truename));
8693     __ASM_VTABLE(numpunct_wchar,
8694             VTABLE_ADD_FUNC(numpunct_wchar_vector_dtor)
8695             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
8696             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
8697             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
8698             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
8699             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
8700     __ASM_VTABLE(numpunct_short,
8701             VTABLE_ADD_FUNC(numpunct_wchar_vector_dtor)
8702             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
8703             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
8704             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
8705             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
8706             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
8707     __ASM_VTABLE(num_get_char,
8708             VTABLE_ADD_FUNC(num_get_char_vector_dtor)
8709             VTABLE_ADD_FUNC(num_get_char_do_get_void)
8710             VTABLE_ADD_FUNC(num_get_char_do_get_double)
8711             VTABLE_ADD_FUNC(num_get_char_do_get_double)
8712             VTABLE_ADD_FUNC(num_get_char_do_get_float)
8713             VTABLE_ADD_FUNC(num_get_char_do_get_uint64)
8714             VTABLE_ADD_FUNC(num_get_char_do_get_int64)
8715             VTABLE_ADD_FUNC(num_get_char_do_get_ulong)
8716             VTABLE_ADD_FUNC(num_get_char_do_get_long)
8717             VTABLE_ADD_FUNC(num_get_char_do_get_uint)
8718             VTABLE_ADD_FUNC(num_get_char_do_get_ushort)
8719             VTABLE_ADD_FUNC(num_get_char_do_get_bool));
8720     __ASM_VTABLE(num_get_short,
8721             VTABLE_ADD_FUNC(num_get_wchar_vector_dtor)
8722             VTABLE_ADD_FUNC(num_get_short_do_get_void)
8723             VTABLE_ADD_FUNC(num_get_short_do_get_double)
8724             VTABLE_ADD_FUNC(num_get_short_do_get_double)
8725             VTABLE_ADD_FUNC(num_get_short_do_get_float)
8726             VTABLE_ADD_FUNC(num_get_short_do_get_uint64)
8727             VTABLE_ADD_FUNC(num_get_short_do_get_int64)
8728             VTABLE_ADD_FUNC(num_get_short_do_get_ulong)
8729             VTABLE_ADD_FUNC(num_get_short_do_get_long)
8730             VTABLE_ADD_FUNC(num_get_short_do_get_uint)
8731             VTABLE_ADD_FUNC(num_get_short_do_get_ushort)
8732             VTABLE_ADD_FUNC(num_get_short_do_get_bool));
8733     __ASM_VTABLE(num_get_wchar,
8734             VTABLE_ADD_FUNC(num_get_wchar_vector_dtor)
8735             VTABLE_ADD_FUNC(num_get_wchar_do_get_void)
8736             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
8737             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
8738             VTABLE_ADD_FUNC(num_get_wchar_do_get_float)
8739             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint64)
8740             VTABLE_ADD_FUNC(num_get_wchar_do_get_int64)
8741             VTABLE_ADD_FUNC(num_get_wchar_do_get_ulong)
8742             VTABLE_ADD_FUNC(num_get_wchar_do_get_long)
8743             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint)
8744             VTABLE_ADD_FUNC(num_get_wchar_do_get_ushort)
8745             VTABLE_ADD_FUNC(num_get_wchar_do_get_bool));
8746     __ASM_VTABLE(num_put_char,
8747             VTABLE_ADD_FUNC(num_put_char_vector_dtor)
8748             VTABLE_ADD_FUNC(num_put_char_do_put_ptr)
8749             VTABLE_ADD_FUNC(num_put_char_do_put_double)
8750             VTABLE_ADD_FUNC(num_put_char_do_put_double)
8751             VTABLE_ADD_FUNC(num_put_char_do_put_uint64)
8752             VTABLE_ADD_FUNC(num_put_char_do_put_int64)
8753             VTABLE_ADD_FUNC(num_put_char_do_put_ulong)
8754             VTABLE_ADD_FUNC(num_put_char_do_put_long)
8755             VTABLE_ADD_FUNC(num_put_char_do_put_bool));
8756     __ASM_VTABLE(num_put_wchar,
8757             VTABLE_ADD_FUNC(num_put_wchar_vector_dtor)
8758             VTABLE_ADD_FUNC(num_put_wchar_do_put_ptr)
8759             VTABLE_ADD_FUNC(num_put_wchar_do_put_double)
8760             VTABLE_ADD_FUNC(num_put_wchar_do_put_double)
8761             VTABLE_ADD_FUNC(num_put_wchar_do_put_uint64)
8762             VTABLE_ADD_FUNC(num_put_wchar_do_put_int64)
8763             VTABLE_ADD_FUNC(num_put_wchar_do_put_ulong)
8764             VTABLE_ADD_FUNC(num_put_wchar_do_put_long)
8765             VTABLE_ADD_FUNC(num_put_wchar_do_put_bool));
8766     __ASM_VTABLE(num_put_short,
8767             VTABLE_ADD_FUNC(num_put_wchar_vector_dtor)
8768             VTABLE_ADD_FUNC(num_put_short_do_put_ptr)
8769             VTABLE_ADD_FUNC(num_put_short_do_put_double)
8770             VTABLE_ADD_FUNC(num_put_short_do_put_double)
8771             VTABLE_ADD_FUNC(num_put_short_do_put_uint64)
8772             VTABLE_ADD_FUNC(num_put_short_do_put_int64)
8773             VTABLE_ADD_FUNC(num_put_short_do_put_ulong)
8774             VTABLE_ADD_FUNC(num_put_short_do_put_long)
8775             VTABLE_ADD_FUNC(num_put_short_do_put_bool));
8776 #ifndef __GNUC__
8777 }
8778 #endif
8779
8780 void init_locale(void *base)
8781 {
8782 #ifdef __x86_64__
8783     init_locale_facet_rtti(base);
8784     init_collate_char_rtti(base);
8785     init_collate_wchar_rtti(base);
8786     init_collate_short_rtti(base);
8787     init_ctype_base_rtti(base);
8788     init_ctype_char_rtti(base);
8789     init_ctype_wchar_rtti(base);
8790     init_ctype_short_rtti(base);
8791     init_codecvt_base_rtti(base);
8792     init_codecvt_char_rtti(base);
8793     init_codecvt_wchar_rtti(base);
8794     init_codecvt_short_rtti(base);
8795     init_numpunct_char_rtti(base);
8796     init_numpunct_wchar_rtti(base);
8797     init_numpunct_short_rtti(base);
8798     init_num_get_char_rtti(base);
8799     init_num_get_wchar_rtti(base);
8800     init_num_get_short_rtti(base);
8801     init_num_put_char_rtti(base);
8802     init_num_put_wchar_rtti(base);
8803     init_num_put_short_rtti(base);
8804 #endif
8805 }
8806
8807 void free_locale(void)
8808 {
8809     facets_elem *iter, *safe;
8810
8811     if(global_locale) {
8812         locale__Locimp_dtor(global_locale);
8813         locale_dtor(&classic_locale);
8814     }
8815
8816     LIST_FOR_EACH_ENTRY_SAFE(iter, safe, &lazy_facets, facets_elem, entry) {
8817         list_remove(&iter->entry);
8818         if(locale_facet__Decref(iter->fac))
8819             call_locale_facet_vector_dtor(iter->fac, 1);
8820         MSVCRT_operator_delete(iter);
8821     }
8822 }