msvcp90: Fixed num_get<short>::vftable.
[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
30 #include "wine/list.h"
31
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winnls.h"
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
38
39 char* __cdecl _Getdays(void);
40 char* __cdecl _Getmonths(void);
41 void* __cdecl _Gettnames(void);
42 unsigned int __cdecl ___lc_codepage_func(void);
43 LCID* __cdecl ___lc_handle_func(void);
44 const locale_facet* __thiscall locale__Getfacet(const locale*, MSVCP_size_t);
45
46 typedef int category;
47
48 typedef struct {
49     MSVCP_size_t id;
50 } locale_id;
51
52 typedef struct _locale__Locimp {
53     locale_facet facet;
54     locale_facet **facetvec;
55     MSVCP_size_t facet_cnt;
56     category catmask;
57     MSVCP_bool transparent;
58     basic_string_char name;
59 } locale__Locimp;
60
61 typedef struct {
62     void *timeptr;
63 } _Timevec;
64
65 typedef struct {
66     _Lockit lock;
67     basic_string_char days;
68     basic_string_char months;
69     basic_string_char oldlocname;
70     basic_string_char newlocname;
71 } _Locinfo;
72
73 typedef struct {
74     LCID handle;
75     unsigned page;
76 } _Collvec;
77
78 typedef struct {
79     locale_facet facet;
80     _Collvec coll;
81 } collate;
82
83 typedef struct {
84     locale_facet facet;
85     const char *grouping;
86     char dp;
87     char sep;
88     const char *false_name;
89     const char *true_name;
90 } numpunct_char;
91
92 typedef struct {
93     locale_facet facet;
94     const char *grouping;
95     wchar_t dp;
96     wchar_t sep;
97     const wchar_t *false_name;
98     const wchar_t *true_name;
99 } numpunct_wchar;
100
101 /* ?_Id_cnt@id@locale@std@@0HA */
102 int locale_id__Id_cnt = 0;
103
104 static locale__Locimp *global_locale;
105 static locale classic_locale;
106
107 /* ?_Clocptr@_Locimp@locale@std@@0PAV123@A */
108 /* ?_Clocptr@_Locimp@locale@std@@0PEAV123@EA */
109 locale__Locimp *locale__Locimp__Clocptr = NULL;
110
111 static char istreambuf_iterator_char_val(istreambuf_iterator_char *this)
112 {
113     if(this->strbuf && !this->got) {
114         int c = basic_streambuf_char_sgetc(this->strbuf);
115         if(c == EOF)
116             this->strbuf = NULL;
117         else
118             this->val = c;
119     }
120
121     this->got = TRUE;
122     return this->val;
123 }
124
125 static wchar_t istreambuf_iterator_wchar_val(istreambuf_iterator_wchar *this)
126 {
127     if(this->strbuf && !this->got) {
128         unsigned short c = basic_streambuf_wchar_sgetc(this->strbuf);
129         if(c == WEOF)
130             this->strbuf = NULL;
131         else
132             this->val = c;
133     }
134
135     this->got = TRUE;
136     return this->val;
137 }
138
139 static void istreambuf_iterator_char_inc(istreambuf_iterator_char *this)
140 {
141     if(!this->strbuf || basic_streambuf_char_sbumpc(this->strbuf)==EOF) {
142         this->strbuf = NULL;
143         this->got = TRUE;
144     }else {
145         this->got = FALSE;
146         istreambuf_iterator_char_val(this);
147     }
148 }
149
150 static void istreambuf_iterator_wchar_inc(istreambuf_iterator_wchar *this)
151 {
152     if(!this->strbuf || basic_streambuf_wchar_sbumpc(this->strbuf)==WEOF) {
153         this->strbuf = NULL;
154         this->got = TRUE;
155     }else {
156         this->got = FALSE;
157         istreambuf_iterator_wchar_val(this);
158     }
159 }
160
161 static void ostreambuf_iterator_char_put(ostreambuf_iterator_char *this, char ch)
162 {
163     if(this->failed || basic_streambuf_char_sputc(this->strbuf, ch)==EOF)
164         this->failed = TRUE;
165 }
166
167 static void ostreambuf_iterator_wchar_put(ostreambuf_iterator_wchar *this, wchar_t ch)
168 {
169     if(this->failed || basic_streambuf_wchar_sputc(this->strbuf, ch)==WEOF)
170         this->failed = TRUE;
171 }
172
173 /* ??1facet@locale@std@@UAE@XZ */
174 /* ??1facet@locale@std@@UEAA@XZ */
175 DEFINE_THISCALL_WRAPPER(locale_facet_dtor, 4)
176 void __thiscall locale_facet_dtor(locale_facet *this)
177 {
178     TRACE("(%p)\n", this);
179 }
180
181 DEFINE_THISCALL_WRAPPER(MSVCP_locale_facet_vector_dtor, 8)
182 #define call_locale_facet_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0, \
183         locale_facet*, (locale_facet*, unsigned int), (this, flags))
184 locale_facet* __thiscall MSVCP_locale_facet_vector_dtor(locale_facet *this, unsigned int flags)
185 {
186     TRACE("(%p %x)\n", this, flags);
187     if(flags & 2) {
188         /* we have an array, with the number of elements stored before the first object */
189         int i, *ptr = (int *)this-1;
190
191         for(i=*ptr-1; i>=0; i--)
192             locale_facet_dtor(this+i);
193         MSVCRT_operator_delete(ptr);
194     } else {
195         locale_facet_dtor(this);
196         if(flags & 1)
197             MSVCRT_operator_delete(this);
198     }
199
200     return this;
201 }
202
203 typedef struct
204 {
205     locale_facet *fac;
206     struct list entry;
207 } facets_elem;
208 static struct list lazy_facets = LIST_INIT(lazy_facets);
209
210 /* Not exported from msvcp90 */
211 /* ?facet_Register@facet@locale@std@@CAXPAV123@@Z */
212 /* ?facet_Register@facet@locale@std@@CAXPEAV123@@Z */
213 void __cdecl locale_facet_register(locale_facet *add)
214 {
215     facets_elem *head = MSVCRT_operator_new(sizeof(*head));
216     if(!head) {
217         ERR("Out of memory\n");
218         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
219     }
220
221     head->fac = add;
222     list_add_head(&lazy_facets, &head->entry);
223 }
224
225 /* Not exported from msvcp90 */
226 /* ?_Register@facet@locale@std@@QAEXXZ */
227 /* ?_Register@facet@locale@std@@QEAAXXZ */
228 DEFINE_THISCALL_WRAPPER(locale_facet__Register, 4)
229 void __thiscall locale_facet__Register(locale_facet *this)
230 {
231     TRACE("(%p)\n", this);
232     locale_facet_register(this);
233 }
234
235 /* Not exported from msvcp90 */
236 /* ??_7facet@locale@std@@6B@ */
237 extern const vtable_ptr MSVCP_locale_facet_vtable;
238
239 /* ??0id@locale@std@@QAE@I@Z */
240 /* ??0id@locale@std@@QEAA@_K@Z */
241 DEFINE_THISCALL_WRAPPER(locale_id_ctor_id, 8)
242 locale_id* __thiscall locale_id_ctor_id(locale_id *this, MSVCP_size_t id)
243 {
244     TRACE("(%p %lu)\n", this, id);
245
246     this->id = id;
247     return this;
248 }
249
250 /* ??_Fid@locale@std@@QAEXXZ */
251 /* ??_Fid@locale@std@@QEAAXXZ */
252 DEFINE_THISCALL_WRAPPER(locale_id_ctor, 4)
253 locale_id* __thiscall locale_id_ctor(locale_id *this)
254 {
255     TRACE("(%p)\n", this);
256
257     this->id = 0;
258     return this;
259 }
260
261 /* ??Bid@locale@std@@QAEIXZ */
262 /* ??Bid@locale@std@@QEAA_KXZ */
263 DEFINE_THISCALL_WRAPPER(locale_id_operator_size_t, 4)
264 MSVCP_size_t __thiscall locale_id_operator_size_t(locale_id *this)
265 {
266     _Lockit lock;
267
268     TRACE("(%p)\n", this);
269
270     if(!this->id) {
271         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
272         this->id = ++locale_id__Id_cnt;
273         _Lockit_dtor(&lock);
274     }
275
276     return this->id;
277 }
278
279 /* ?_Id_cnt_func@id@locale@std@@CAAAHXZ */
280 /* ?_Id_cnt_func@id@locale@std@@CAAEAHXZ */
281 int* __cdecl locale_id__Id_cnt_func(void)
282 {
283     TRACE("\n");
284     return &locale_id__Id_cnt;
285 }
286
287 /* ??_Ffacet@locale@std@@QAEXXZ */
288 /* ??_Ffacet@locale@std@@QEAAXXZ */
289 DEFINE_THISCALL_WRAPPER(locale_facet_ctor, 4)
290 locale_facet* __thiscall locale_facet_ctor(locale_facet *this)
291 {
292     TRACE("(%p)\n", this);
293     this->vtable = &MSVCP_locale_facet_vtable;
294     this->refs = 0;
295     return this;
296 }
297
298 /* ??0facet@locale@std@@IAE@I@Z */
299 /* ??0facet@locale@std@@IEAA@_K@Z */
300 DEFINE_THISCALL_WRAPPER(locale_facet_ctor_refs, 8)
301 locale_facet* __thiscall locale_facet_ctor_refs(locale_facet *this, MSVCP_size_t refs)
302 {
303     TRACE("(%p %lu)\n", this, refs);
304     this->vtable = &MSVCP_locale_facet_vtable;
305     this->refs = refs;
306     return this;
307 }
308
309 /* ?_Incref@facet@locale@std@@QAEXXZ */
310 /* ?_Incref@facet@locale@std@@QEAAXXZ */
311 DEFINE_THISCALL_WRAPPER(locale_facet__Incref, 4)
312 void __thiscall locale_facet__Incref(locale_facet *this)
313 {
314     _Lockit lock;
315
316     TRACE("(%p)\n", this);
317
318     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
319     this->refs++;
320     _Lockit_dtor(&lock);
321 }
322
323 /* ?_Decref@facet@locale@std@@QAEPAV123@XZ */
324 /* ?_Decref@facet@locale@std@@QEAAPEAV123@XZ */
325 DEFINE_THISCALL_WRAPPER(locale_facet__Decref, 4)
326 locale_facet* __thiscall locale_facet__Decref(locale_facet *this)
327 {
328     _Lockit lock;
329     locale_facet *ret;
330
331     TRACE("(%p)\n", this);
332
333     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
334     if(this->refs)
335         this->refs--;
336
337     ret = this->refs ? NULL : this;
338     _Lockit_dtor(&lock);
339
340     return ret;
341 }
342
343 /* ?_Getcat@facet@locale@std@@SAIPAPBV123@PBV23@@Z */
344 /* ?_Getcat@facet@locale@std@@SA_KPEAPEBV123@PEBV23@@Z */
345 MSVCP_size_t __cdecl locale_facet__Getcat(const locale_facet **facet, const locale *loc)
346 {
347     TRACE("(%p %p)\n", facet, loc);
348     return -1;
349 }
350
351 /* ??0_Timevec@std@@QAE@ABV01@@Z */
352 /* ??0_Timevec@std@@QEAA@AEBV01@@Z */
353 /* This copy constructor modifies copied object */
354 DEFINE_THISCALL_WRAPPER(_Timevec_copy_ctor, 8)
355 _Timevec* __thiscall _Timevec_copy_ctor(_Timevec *this, _Timevec *copy)
356 {
357     TRACE("(%p %p)\n", this, copy);
358     this->timeptr = copy->timeptr;
359     copy->timeptr = NULL;
360     return this;
361 }
362
363 /* ??0_Timevec@std@@QAE@PAX@Z */
364 /* ??0_Timevec@std@@QEAA@PEAX@Z */
365 DEFINE_THISCALL_WRAPPER(_Timevec_ctor_timeptr, 8)
366 _Timevec* __thiscall _Timevec_ctor_timeptr(_Timevec *this, void *timeptr)
367 {
368     TRACE("(%p %p)\n", this, timeptr);
369     this->timeptr = timeptr;
370     return this;
371 }
372
373 /* ??_F_Timevec@std@@QAEXXZ */
374 /* ??_F_Timevec@std@@QEAAXXZ */
375 DEFINE_THISCALL_WRAPPER(_Timevec_ctor, 4)
376 _Timevec* __thiscall _Timevec_ctor(_Timevec *this)
377 {
378     TRACE("(%p)\n", this);
379     this->timeptr = NULL;
380     return this;
381 }
382
383 /* ??1_Timevec@std@@QAE@XZ */
384 /* ??1_Timevec@std@@QEAA@XZ */
385 DEFINE_THISCALL_WRAPPER(_Timevec_dtor, 4)
386 void __thiscall _Timevec_dtor(_Timevec *this)
387 {
388     TRACE("(%p)\n", this);
389     free(this->timeptr);
390 }
391
392 /* ??4_Timevec@std@@QAEAAV01@ABV01@@Z */
393 /* ??4_Timevec@std@@QEAAAEAV01@AEBV01@@Z */
394 DEFINE_THISCALL_WRAPPER(_Timevec_op_assign, 8)
395 _Timevec* __thiscall _Timevec_op_assign(_Timevec *this, _Timevec *right)
396 {
397     TRACE("(%p %p)\n", this, right);
398     this->timeptr = right->timeptr;
399     right->timeptr = NULL;
400     return this;
401 }
402
403 /* ?_Getptr@_Timevec@std@@QBEPAXXZ */
404 /* ?_Getptr@_Timevec@std@@QEBAPEAXXZ */
405 DEFINE_THISCALL_WRAPPER(_Timevec__Getptr, 4)
406 void* __thiscall _Timevec__Getptr(_Timevec *this)
407 {
408     TRACE("(%p)\n", this);
409     return this->timeptr;
410 }
411
412 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@HPBD@Z */
413 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@HPEBD@Z */
414 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cat_cstr(_Locinfo *locinfo, int category, const char *locstr)
415 {
416     const char *locale = NULL;
417
418     /* This function is probably modifying more global objects */
419     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
420
421     if(!locstr)
422         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
423
424     _Lockit_ctor_locktype(&locinfo->lock, _LOCK_LOCALE);
425     MSVCP_basic_string_char_ctor_cstr(&locinfo->days, "");
426     MSVCP_basic_string_char_ctor_cstr(&locinfo->months, "");
427     MSVCP_basic_string_char_ctor_cstr(&locinfo->oldlocname, setlocale(LC_ALL, NULL));
428
429     if(category)
430         locale = setlocale(LC_ALL, locstr);
431     else
432         locale = setlocale(LC_ALL, NULL);
433
434     if(locale)
435         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
436     else
437         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
438
439     return locinfo;
440 }
441
442 /* ??0_Locinfo@std@@QAE@HPBD@Z */
443 /* ??0_Locinfo@std@@QEAA@HPEBD@Z */
444 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cat_cstr, 12)
445 _Locinfo* __thiscall _Locinfo_ctor_cat_cstr(_Locinfo *this, int category, const char *locstr)
446 {
447     return _Locinfo__Locinfo_ctor_cat_cstr(this, category, locstr);
448 }
449
450 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
451 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
452 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_bstr(_Locinfo *locinfo, const basic_string_char *locstr)
453 {
454     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
455 }
456
457 /* ??0_Locinfo@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
458 /* ??0_Locinfo@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
459 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_bstr, 8)
460 _Locinfo* __thiscall _Locinfo_ctor_bstr(_Locinfo *this, const basic_string_char *locstr)
461 {
462     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
463 }
464
465 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@PBD@Z */
466 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@PEBD@Z */
467 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cstr(_Locinfo *locinfo, const char *locstr)
468 {
469     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, locstr);
470 }
471
472 /* ??0_Locinfo@std@@QAE@PBD@Z */
473 /* ??0_Locinfo@std@@QEAA@PEBD@Z */
474 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cstr, 8)
475 _Locinfo* __thiscall _Locinfo_ctor_cstr(_Locinfo *this, const char *locstr)
476 {
477     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, locstr);
478 }
479
480 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z */
481 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPEAV12@@Z */
482 void __cdecl _Locinfo__Locinfo_dtor(_Locinfo *locinfo)
483 {
484     TRACE("(%p)\n", locinfo);
485
486     setlocale(LC_ALL, MSVCP_basic_string_char_c_str(&locinfo->oldlocname));
487     MSVCP_basic_string_char_dtor(&locinfo->days);
488     MSVCP_basic_string_char_dtor(&locinfo->months);
489     MSVCP_basic_string_char_dtor(&locinfo->oldlocname);
490     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
491     _Lockit_dtor(&locinfo->lock);
492 }
493
494 /* ??_F_Locinfo@std@@QAEXXZ */
495 /* ??_F_Locinfo@std@@QEAAXXZ */
496 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor, 4)
497 _Locinfo* __thiscall _Locinfo_ctor(_Locinfo *this)
498 {
499     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, "C");
500 }
501
502 /* ??1_Locinfo@std@@QAE@XZ */
503 /* ??1_Locinfo@std@@QEAA@XZ */
504 DEFINE_THISCALL_WRAPPER(_Locinfo_dtor, 4)
505 void __thiscall _Locinfo_dtor(_Locinfo *this)
506 {
507     _Locinfo__Locinfo_dtor(this);
508 }
509
510 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAAV12@PAV12@HPBD@Z */
511 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAEAV12@PEAV12@HPEBD@Z */
512 _Locinfo* __cdecl _Locinfo__Locinfo_Addcats(_Locinfo *locinfo, int category, const char *locstr)
513 {
514     const char *locale = NULL;
515
516     /* This function is probably modifying more global objects */
517     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
518     if(!locstr)
519         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
520
521     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
522
523     if(category)
524         locale = setlocale(LC_ALL, locstr);
525     else
526         locale = setlocale(LC_ALL, NULL);
527
528     if(locale)
529         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
530     else
531         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
532
533     return locinfo;
534 }
535
536 /* ?_Addcats@_Locinfo@std@@QAEAAV12@HPBD@Z */
537 /* ?_Addcats@_Locinfo@std@@QEAAAEAV12@HPEBD@Z */
538 DEFINE_THISCALL_WRAPPER(_Locinfo__Addcats, 12)
539 _Locinfo* __thiscall _Locinfo__Addcats(_Locinfo *this, int category, const char *locstr)
540 {
541     return _Locinfo__Locinfo_Addcats(this, category, locstr);
542 }
543
544 /* _Getcoll */
545 ULONGLONG __cdecl _Getcoll(void)
546 {
547     union {
548         _Collvec collvec;
549         ULONGLONG ull;
550     } ret;
551     _locale_t locale = _get_current_locale();
552
553     TRACE("\n");
554
555     ret.collvec.page = locale->locinfo->lc_collate_cp;
556     ret.collvec.handle = locale->locinfo->lc_handle[LC_COLLATE];
557     _free_locale(locale);
558     return ret.ull;
559 }
560
561 /* ?_Getcoll@_Locinfo@std@@QBE?AU_Collvec@@XZ */
562 /* ?_Getcoll@_Locinfo@std@@QEBA?AU_Collvec@@XZ */
563 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcoll, 8)
564 _Collvec* __thiscall _Locinfo__Getcoll(const _Locinfo *this, _Collvec *ret)
565 {
566     ULONGLONG ull = _Getcoll();
567     memcpy(ret, &ull, sizeof(ull));
568     return ret;
569 }
570
571 /* _Getctype */
572 _Ctypevec* __cdecl _Getctype(_Ctypevec *ret)
573 {
574     _locale_t locale = _get_current_locale();
575     short *table;
576
577     TRACE("\n");
578
579     ret->page = locale->locinfo->lc_codepage;
580     ret->handle = locale->locinfo->lc_handle[LC_COLLATE];
581     ret->delfl = TRUE;
582     table = malloc(sizeof(short[256]));
583     if(!table) {
584         _free_locale(locale);
585         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
586     }
587     memcpy(table, locale->locinfo->pctype, sizeof(short[256]));
588     ret->table = table;
589     _free_locale(locale);
590     return ret;
591 }
592
593 /* ?_Getctype@_Locinfo@std@@QBE?AU_Ctypevec@@XZ */
594 /* ?_Getctype@_Locinfo@std@@QEBA?AU_Ctypevec@@XZ */
595 DEFINE_THISCALL_WRAPPER(_Locinfo__Getctype, 8)
596 _Ctypevec* __thiscall _Locinfo__Getctype(const _Locinfo *this, _Ctypevec *ret)
597 {
598     return _Getctype(ret);
599 }
600
601 /* _Getcvt */
602 ULONGLONG __cdecl _Getcvt(void)
603 {
604     _locale_t locale = _get_current_locale();
605     union {
606         _Cvtvec cvtvec;
607         ULONGLONG ull;
608     } ret;
609
610     TRACE("\n");
611
612     ret.cvtvec.page = locale->locinfo->lc_codepage;
613     ret.cvtvec.handle = locale->locinfo->lc_handle[LC_CTYPE];
614     _free_locale(locale);
615     return ret.ull;
616 }
617
618 /* ?_Getcvt@_Locinfo@std@@QBE?AU_Cvtvec@@XZ */
619 /* ?_Getcvt@_Locinfo@std@@QEBA?AU_Cvtvec@@XZ */
620 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcvt, 8)
621 _Cvtvec* __thiscall _Locinfo__Getcvt(const _Locinfo *this, _Cvtvec *ret)
622 {
623     ULONGLONG ull = _Getcvt();
624     memcpy(ret, &ull, sizeof(ull));
625     return ret;
626 }
627
628 /* ?_Getdateorder@_Locinfo@std@@QBEHXZ */
629 /* ?_Getdateorder@_Locinfo@std@@QEBAHXZ */
630 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdateorder, 4)
631 int __thiscall _Locinfo__Getdateorder(const _Locinfo *this)
632 {
633     FIXME("(%p) stub\n", this);
634     return 0;
635 }
636
637 /* ?_Getdays@_Locinfo@std@@QBEPBDXZ */
638 /* ?_Getdays@_Locinfo@std@@QEBAPEBDXZ */
639 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdays, 4)
640 const char* __thiscall _Locinfo__Getdays(_Locinfo *this)
641 {
642     char *days = _Getdays();
643
644     TRACE("(%p)\n", this);
645
646     if(days) {
647         MSVCP_basic_string_char_dtor(&this->days);
648         MSVCP_basic_string_char_ctor_cstr(&this->days, days);
649         free(days);
650     }
651
652     return this->days.size ? MSVCP_basic_string_char_c_str(&this->days) :
653         ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
654 }
655
656 /* ?_Getmonths@_Locinfo@std@@QBEPBDXZ */
657 /* ?_Getmonths@_Locinfo@std@@QEBAPEBDXZ */
658 DEFINE_THISCALL_WRAPPER(_Locinfo__Getmonths, 4)
659 const char* __thiscall _Locinfo__Getmonths(_Locinfo *this)
660 {
661     char *months = _Getmonths();
662
663     TRACE("(%p)\n", this);
664
665     if(months) {
666         MSVCP_basic_string_char_dtor(&this->months);
667         MSVCP_basic_string_char_ctor_cstr(&this->months, months);
668         free(months);
669     }
670
671     return this->months.size ? MSVCP_basic_string_char_c_str(&this->months) :
672         ":Jan:January:Feb:February:Mar:March:Apr:April:May:May:Jun:June:Jul:July"
673         ":Aug:August:Sep:September:Oct:October:Nov:November:Dec:December";
674 }
675
676 /* ?_Getfalse@_Locinfo@std@@QBEPBDXZ */
677 /* ?_Getfalse@_Locinfo@std@@QEBAPEBDXZ */
678 DEFINE_THISCALL_WRAPPER(_Locinfo__Getfalse, 4)
679 const char* __thiscall _Locinfo__Getfalse(const _Locinfo *this)
680 {
681     TRACE("(%p)\n", this);
682     return "false";
683 }
684
685 /* ?_Gettrue@_Locinfo@std@@QBEPBDXZ */
686 /* ?_Gettrue@_Locinfo@std@@QEBAPEBDXZ */
687 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettrue, 4)
688 const char* __thiscall _Locinfo__Gettrue(const _Locinfo *this)
689 {
690     TRACE("(%p)\n", this);
691     return "true";
692 }
693
694 /* ?_Getlconv@_Locinfo@std@@QBEPBUlconv@@XZ */
695 /* ?_Getlconv@_Locinfo@std@@QEBAPEBUlconv@@XZ */
696 DEFINE_THISCALL_WRAPPER(_Locinfo__Getlconv, 4)
697 const struct lconv* __thiscall _Locinfo__Getlconv(const _Locinfo *this)
698 {
699     TRACE("(%p)\n", this);
700     return localeconv();
701 }
702
703 /* ?_Getname@_Locinfo@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
704 /* ?_Getname@_Locinfo@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
705 DEFINE_THISCALL_WRAPPER(_Locinfo__Getname, 8)
706 basic_string_char* __thiscall _Locinfo__Getname(const _Locinfo *this, basic_string_char *ret)
707 {
708     TRACE("(%p)\n", this);
709
710     MSVCP_basic_string_char_copy_ctor(ret, &this->newlocname);
711     return ret;
712 }
713
714 /* ?_Gettnames@_Locinfo@std@@QBE?AV_Timevec@2@XZ */
715 /* ?_Gettnames@_Locinfo@std@@QEBA?AV_Timevec@2@XZ */
716 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettnames, 8)
717 _Timevec*__thiscall _Locinfo__Gettnames(const _Locinfo *this, _Timevec *ret)
718 {
719     TRACE("(%p)\n", this);
720
721     _Timevec_ctor_timeptr(ret, _Gettnames());
722     return ret;
723 }
724
725 /* ?id@?$collate@D@std@@2V0locale@2@A */
726 locale_id collate_char_id = {0};
727
728 /* ??_7?$collate@D@std@@6B@ */
729 extern const vtable_ptr MSVCP_collate_char_vtable;
730
731 /* ?_Init@?$collate@D@std@@IAEXABV_Locinfo@2@@Z */
732 /* ?_Init@?$collate@D@std@@IEAAXAEBV_Locinfo@2@@Z */
733 DEFINE_THISCALL_WRAPPER(collate_char__Init, 8)
734 void __thiscall collate_char__Init(collate *this, const _Locinfo *locinfo)
735 {
736     TRACE("(%p %p)\n", this, locinfo);
737     _Locinfo__Getcoll(locinfo, &this->coll);
738 }
739
740 /* ??0?$collate@D@std@@IAE@PBDI@Z */
741 /* ??0?$collate@D@std@@IEAA@PEBD_K@Z */
742 DEFINE_THISCALL_WRAPPER(collate_char_ctor_name, 12)
743 collate* __thiscall collate_char_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
744 {
745     _Locinfo locinfo;
746
747     TRACE("(%p %s %lu)\n", this, name, refs);
748
749     locale_facet_ctor_refs(&this->facet, refs);
750     this->facet.vtable = &MSVCP_collate_char_vtable;
751
752     _Locinfo_ctor_cstr(&locinfo, name);
753     collate_char__Init(this, &locinfo);
754     _Locinfo_dtor(&locinfo);
755     return this;
756 }
757
758 /* ??0?$collate@D@std@@QAE@ABV_Locinfo@1@I@Z */
759 /* ??0?$collate@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
760 DEFINE_THISCALL_WRAPPER(collate_char_ctor_locinfo, 12)
761 collate* __thiscall collate_char_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
762 {
763     TRACE("(%p %p %lu)\n", this, locinfo, refs);
764
765     locale_facet_ctor_refs(&this->facet, refs);
766     this->facet.vtable = &MSVCP_collate_char_vtable;
767     collate_char__Init(this, locinfo);
768     return this;
769 }
770
771 /* ??0?$collate@D@std@@QAE@I@Z */
772 /* ??0?$collate@D@std@@QEAA@_K@Z */
773 DEFINE_THISCALL_WRAPPER(collate_char_ctor_refs, 8)
774 collate* __thiscall collate_char_ctor_refs(collate *this, MSVCP_size_t refs)
775 {
776     return collate_char_ctor_name(this, "C", refs);
777 }
778
779 /* ??1?$collate@D@std@@MAE@XZ */
780 /* ??1?$collate@D@std@@MEAA@XZ */
781 DEFINE_THISCALL_WRAPPER(collate_char_dtor, 4)
782 void __thiscall collate_char_dtor(collate *this)
783 {
784     TRACE("(%p)\n", this);
785 }
786
787 DEFINE_THISCALL_WRAPPER(MSVCP_collate_char_vector_dtor, 8)
788 collate* __thiscall MSVCP_collate_char_vector_dtor(collate *this, unsigned int flags)
789 {
790     TRACE("(%p %x)\n", this, flags);
791     if(flags & 2) {
792         /* we have an array, with the number of elements stored before the first object */
793         int i, *ptr = (int *)this-1;
794
795         for(i=*ptr-1; i>=0; i--)
796             collate_char_dtor(this+i);
797         MSVCRT_operator_delete(ptr);
798     } else {
799         collate_char_dtor(this);
800         if(flags & 1)
801             MSVCRT_operator_delete(this);
802     }
803
804     return this;
805 }
806
807 /* ??_F?$collate@D@std@@QAEXXZ */
808 /* ??_F?$collate@D@std@@QEAAXXZ */
809 DEFINE_THISCALL_WRAPPER(collate_char_ctor, 4)
810 collate* __thiscall collate_char_ctor(collate *this)
811 {
812     return collate_char_ctor_name(this, "C", 0);
813 }
814
815 /* ?_Getcat@?$collate@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
816 /* ?_Getcat@?$collate@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
817 MSVCP_size_t __cdecl collate_char__Getcat(const locale_facet **facet, const locale *loc)
818 {
819     TRACE("(%p %p)\n", facet, loc);
820
821     if(facet && !*facet) {
822         *facet = MSVCRT_operator_new(sizeof(collate));
823         if(!*facet) {
824             ERR("Out of memory\n");
825             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
826             return 0;
827         }
828         collate_char_ctor_name((collate*)*facet,
829                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
830     }
831
832     return LC_COLLATE;
833 }
834
835 /* _Strcoll */
836 int __cdecl _Strcoll(const char *first1, const char *last1, const char *first2,
837         const char *last2, const _Collvec *coll)
838 {
839     LCID lcid;
840
841     TRACE("(%s %s)\n", debugstr_an(first1, last1-first1), debugstr_an(first2, last2-first2));
842
843     if(coll)
844         lcid = coll->handle;
845     else
846         lcid = ___lc_handle_func()[LC_COLLATE];
847     return CompareStringA(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
848 }
849
850 /* ?do_compare@?$collate@D@std@@MBEHPBD000@Z */
851 /* ?do_compare@?$collate@D@std@@MEBAHPEBD000@Z */
852 DEFINE_THISCALL_WRAPPER(collate_char_do_compare, 20)
853 #define call_collate_char_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
854         (const collate*, const char*, const char*, const char*, const char*), \
855         (this, first1, last1, first2, last2))
856 int __thiscall collate_char_do_compare(const collate *this, const char *first1,
857         const char *last1, const char *first2, const char *last2)
858 {
859     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
860     return _Strcoll(first1, last1, first2, last2, &this->coll);
861 }
862
863 /* ?compare@?$collate@D@std@@QBEHPBD000@Z */
864 /* ?compare@?$collate@D@std@@QEBAHPEBD000@Z */
865 DEFINE_THISCALL_WRAPPER(collate_char_compare, 20)
866 int __thiscall collate_char_compare(const collate *this, const char *first1,
867         const char *last1, const char *first2, const char *last2)
868 {
869     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
870     return call_collate_char_do_compare(this, first1, last1, first2, last2);
871 }
872
873 /* ?do_hash@?$collate@D@std@@MBEJPBD0@Z */
874 /* ?do_hash@?$collate@D@std@@MEBAJPEBD0@Z */
875 DEFINE_THISCALL_WRAPPER(collate_char_do_hash, 12)
876 #define call_collate_char_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
877         (const collate*, const char*, const char*), (this, first, last))
878 LONG __thiscall collate_char_do_hash(const collate *this,
879         const char *first, const char *last)
880 {
881     ULONG ret = 0;
882
883     TRACE("(%p %p %p)\n", this, first, last);
884
885     for(; first<last; first++)
886         ret = (ret<<8 | ret>>24) + *first;
887     return ret;
888 }
889
890 /* ?hash@?$collate@D@std@@QBEJPBD0@Z */
891 /* ?hash@?$collate@D@std@@QEBAJPEBD0@Z */
892 DEFINE_THISCALL_WRAPPER(collate_char_hash, 12)
893 LONG __thiscall collate_char_hash(const collate *this,
894         const char *first, const char *last)
895 {
896     TRACE("(%p %p %p)\n", this, first, last);
897     return call_collate_char_do_hash(this, first, last);
898 }
899
900 /* ?do_transform@?$collate@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
901 /* ?do_transform@?$collate@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
902 DEFINE_THISCALL_WRAPPER(collate_char_do_transform, 16)
903 basic_string_char* __thiscall collate_char_do_transform(const collate *this,
904         basic_string_char *ret, const char *first, const char *last)
905 {
906     FIXME("(%p %p %p) stub\n", this, first, last);
907     return ret;
908 }
909
910 /* ?transform@?$collate@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
911 /* ?transform@?$collate@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
912 DEFINE_THISCALL_WRAPPER(collate_char_transform, 16)
913 basic_string_char* __thiscall collate_char_transform(const collate *this,
914         basic_string_char *ret, const char *first, const char *last)
915 {
916     FIXME("(%p %p %p) stub\n", this, first, last);
917     return ret;
918 }
919
920 /* ?id@?$collate@_W@std@@2V0locale@2@A */
921 locale_id collate_wchar_id = {0};
922 /* ?id@?$collate@G@std@@2V0locale@2@A */
923 locale_id collate_short_id = {0};
924
925 /* ??_7?$collate@_W@std@@6B@ */
926 extern const vtable_ptr MSVCP_collate_wchar_vtable;
927 /* ??_7?$collate@G@std@@6B@ */
928 extern const vtable_ptr MSVCP_collate_short_vtable;
929
930 /* ?_Init@?$collate@_W@std@@IAEXABV_Locinfo@2@@Z */
931 /* ?_Init@?$collate@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
932 /* ?_Init@?$collate@G@std@@IAEXABV_Locinfo@2@@Z */
933 /* ?_Init@?$collate@G@std@@IEAAXAEBV_Locinfo@2@@Z */
934 DEFINE_THISCALL_WRAPPER(collate_wchar__Init, 8)
935 void __thiscall collate_wchar__Init(collate *this, const _Locinfo *locinfo)
936 {
937     TRACE("(%p %p)\n", this, locinfo);
938     _Locinfo__Getcoll(locinfo, &this->coll);
939 }
940
941 /* ??0?$collate@_W@std@@IAE@PBDI@Z */
942 /* ??0?$collate@_W@std@@IEAA@PEBD_K@Z */
943 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_name, 12)
944 collate* __thiscall collate_wchar_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
945 {
946     _Locinfo locinfo;
947
948     TRACE("(%p %s %lu)\n", this, name, refs);
949
950     locale_facet_ctor_refs(&this->facet, refs);
951     this->facet.vtable = &MSVCP_collate_wchar_vtable;
952
953     _Locinfo_ctor_cstr(&locinfo, name);
954     collate_wchar__Init(this, &locinfo);
955     _Locinfo_dtor(&locinfo);
956     return this;
957 }
958
959 /* ??0?$collate@G@std@@IAE@PBDI@Z */
960 /* ??0?$collate@G@std@@IEAA@PEBD_K@Z */
961 DEFINE_THISCALL_WRAPPER(collate_short_ctor_name, 12)
962 collate* __thiscall collate_short_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
963 {
964     collate *ret = collate_wchar_ctor_name(this, name, refs);
965     ret->facet.vtable = &MSVCP_collate_short_vtable;
966     return ret;
967 }
968
969 /* ??0?$collate@_W@std@@QAE@ABV_Locinfo@1@I@Z */
970 /* ??0?$collate@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
971 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_locinfo, 12)
972 collate* __thiscall collate_wchar_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
973 {
974     TRACE("(%p %p %lu)\n", this, locinfo, refs);
975
976     locale_facet_ctor_refs(&this->facet, refs);
977     this->facet.vtable = &MSVCP_collate_wchar_vtable;
978     collate_wchar__Init(this, locinfo);
979     return this;
980 }
981
982 /* ??0?$collate@G@std@@QAE@ABV_Locinfo@1@I@Z */
983 /* ??0?$collate@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
984 DEFINE_THISCALL_WRAPPER(collate_short_ctor_locinfo, 12)
985 collate* __thiscall collate_short_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
986 {
987     collate *ret = collate_wchar_ctor_locinfo(this, locinfo, refs);
988     ret->facet.vtable = &MSVCP_collate_short_vtable;
989     return ret;
990 }
991
992 /* ??0?$collate@_W@std@@QAE@I@Z */
993 /* ??0?$collate@_W@std@@QEAA@_K@Z */
994 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_refs, 8)
995 collate* __thiscall collate_wchar_ctor_refs(collate *this, MSVCP_size_t refs)
996 {
997     return collate_wchar_ctor_name(this, "C", refs);
998 }
999
1000 /* ??0?$collate@G@std@@QAE@I@Z */
1001 /* ??0?$collate@G@std@@QEAA@_K@Z */
1002 DEFINE_THISCALL_WRAPPER(collate_short_ctor_refs, 8)
1003 collate* __thiscall collate_short_ctor_refs(collate *this, MSVCP_size_t refs)
1004 {
1005     collate *ret = collate_wchar_ctor_refs(this, refs);
1006     ret->facet.vtable = &MSVCP_collate_short_vtable;
1007     return ret;
1008 }
1009
1010 /* ??1?$collate@_W@std@@MAE@XZ */
1011 /* ??1?$collate@_W@std@@MEAA@XZ */
1012 /* ??1?$collate@G@std@@MAE@XZ */
1013 /* ??1?$collate@G@std@@MEAA@XZ */
1014 DEFINE_THISCALL_WRAPPER(collate_wchar_dtor, 4)
1015 void __thiscall collate_wchar_dtor(collate *this)
1016 {
1017     TRACE("(%p)\n", this);
1018 }
1019
1020 DEFINE_THISCALL_WRAPPER(MSVCP_collate_wchar_vector_dtor, 8)
1021 collate* __thiscall MSVCP_collate_wchar_vector_dtor(collate *this, unsigned int flags)
1022 {
1023     TRACE("(%p %x)\n", this, flags);
1024     if(flags & 2) {
1025         /* we have an array, with the number of elements stored before the first object */
1026         int i, *ptr = (int *)this-1;
1027
1028         for(i=*ptr-1; i>=0; i--)
1029             collate_wchar_dtor(this+i);
1030         MSVCRT_operator_delete(ptr);
1031     } else {
1032         collate_wchar_dtor(this);
1033         if(flags & 1)
1034             MSVCRT_operator_delete(this);
1035     }
1036
1037     return this;
1038 }
1039
1040 DEFINE_THISCALL_WRAPPER(MSVCP_collate_short_vector_dtor, 8)
1041 collate* __thiscall MSVCP_collate_short_vector_dtor(collate *this, unsigned int flags)
1042 {
1043     return MSVCP_collate_wchar_vector_dtor(this, flags);
1044 }
1045
1046 /* ??_F?$collate@_W@std@@QAEXXZ */
1047 /* ??_F?$collate@_W@std@@QEAAXXZ */
1048 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor, 4)
1049 collate* __thiscall collate_wchar_ctor(collate *this)
1050 {
1051     return collate_wchar_ctor_name(this, "C", 0);
1052 }
1053
1054 /* ??_F?$collate@G@std@@QAEXXZ */
1055 /* ??_F?$collate@G@std@@QEAAXXZ */
1056 DEFINE_THISCALL_WRAPPER(collate_short_ctor, 4)
1057 collate* __thiscall collate_short_ctor(collate *this)
1058 {
1059     collate *ret = collate_wchar_ctor(this);
1060     ret->facet.vtable = &MSVCP_collate_short_vtable;
1061     return ret;
1062 }
1063
1064 /* ?_Getcat@?$collate@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1065 /* ?_Getcat@?$collate@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1066 MSVCP_size_t __cdecl collate_wchar__Getcat(const locale_facet **facet, const locale *loc)
1067 {
1068     TRACE("(%p %p)\n", facet, loc);
1069
1070     if(facet && !*facet) {
1071         *facet = MSVCRT_operator_new(sizeof(collate));
1072         if(!*facet) {
1073             ERR("Out of memory\n");
1074             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1075             return 0;
1076         }
1077         collate_wchar_ctor_name((collate*)*facet,
1078                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
1079     }
1080
1081     return LC_COLLATE;
1082 }
1083
1084 /* ?_Getcat@?$collate@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1085 /* ?_Getcat@?$collate@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1086 MSVCP_size_t __cdecl collate_short__Getcat(const locale_facet **facet, const locale *loc)
1087 {
1088     if(facet && !*facet) {
1089         collate_wchar__Getcat(facet, loc);
1090         (*(locale_facet**)facet)->vtable = &MSVCP_collate_short_vtable;
1091     }
1092
1093     return LC_COLLATE;
1094 }
1095
1096 /* _Wcscoll */
1097 int __cdecl _Wcscoll(const wchar_t *first1, const wchar_t *last1, const wchar_t *first2,
1098         const wchar_t *last2, const _Collvec *coll)
1099 {
1100     LCID lcid;
1101
1102     TRACE("(%s %s)\n", debugstr_wn(first1, last1-first1), debugstr_wn(first2, last2-first2));
1103
1104     if(coll)
1105         lcid = coll->handle;
1106     else
1107         lcid = ___lc_handle_func()[LC_COLLATE];
1108     return CompareStringW(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
1109 }
1110
1111 /* ?do_compare@?$collate@_W@std@@MBEHPB_W000@Z */
1112 /* ?do_compare@?$collate@_W@std@@MEBAHPEB_W000@Z */
1113 /* ?do_compare@?$collate@G@std@@MBEHPBG000@Z */
1114 /* ?do_compare@?$collate@G@std@@MEBAHPEBG000@Z */
1115 DEFINE_THISCALL_WRAPPER(collate_wchar_do_compare, 20)
1116 #define call_collate_wchar_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
1117         (const collate*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*), \
1118         (this, first1, last1, first2, last2))
1119 int __thiscall collate_wchar_do_compare(const collate *this, const wchar_t *first1,
1120         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1121 {
1122     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1123     return _Wcscoll(first1, last1, first2, last2, &this->coll);
1124 }
1125
1126 /* ?compare@?$collate@_W@std@@QBEHPB_W000@Z */
1127 /* ?compare@?$collate@_W@std@@QEBAHPEB_W000@Z */
1128 /* ?compare@?$collate@G@std@@QBEHPBG000@Z */
1129 /* ?compare@?$collate@G@std@@QEBAHPEBG000@Z */
1130 DEFINE_THISCALL_WRAPPER(collate_wchar_compare, 20)
1131 int __thiscall collate_wchar_compare(const collate *this, const wchar_t *first1,
1132         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1133 {
1134     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1135     return call_collate_wchar_do_compare(this, first1, last1, first2, last2);
1136 }
1137
1138 /* ?do_hash@?$collate@_W@std@@MBEJPB_W0@Z */
1139 /* ?do_hash@?$collate@_W@std@@MEBAJPEB_W0@Z */
1140 /* ?do_hash@?$collate@G@std@@MBEJPBG0@Z */
1141 /* ?do_hash@?$collate@G@std@@MEBAJPEBG0@Z */
1142 DEFINE_THISCALL_WRAPPER(collate_wchar_do_hash, 12)
1143 #define call_collate_wchar_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
1144         (const collate*, const wchar_t*, const wchar_t*), (this, first, last))
1145 LONG __thiscall collate_wchar_do_hash(const collate *this,
1146         const wchar_t *first, const wchar_t *last)
1147 {
1148     ULONG ret = 0;
1149
1150     TRACE("(%p %p %p)\n", this, first, last);
1151
1152     for(; first<last; first++)
1153         ret = (ret<<8 | ret>>24) + *first;
1154     return ret;
1155 }
1156
1157 /* ?hash@?$collate@_W@std@@QBEJPB_W0@Z */
1158 /* ?hash@?$collate@_W@std@@QEBAJPEB_W0@Z */
1159 /* ?hash@?$collate@G@std@@QBEJPBG0@Z */
1160 /* ?hash@?$collate@G@std@@QEBAJPEBG0@Z */
1161 DEFINE_THISCALL_WRAPPER(collate_wchar_hash, 12)
1162 LONG __thiscall collate_wchar_hash(const collate *this,
1163         const wchar_t *first, const wchar_t *last)
1164 {
1165     TRACE("(%p %p %p)\n", this, first, last);
1166     return call_collate_wchar_do_hash(this, first, last);
1167 }
1168
1169 /* ?do_transform@?$collate@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1170 /* ?do_transform@?$collate@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1171 /* ?do_transform@?$collate@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1172 /* ?do_transform@?$collate@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1173 DEFINE_THISCALL_WRAPPER(collate_wchar_do_transform, 16)
1174 basic_string_wchar* __thiscall collate_wchar_do_transform(const collate *this,
1175         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1176 {
1177     FIXME("(%p %p %p) stub\n", this, first, last);
1178     return ret;
1179 }
1180
1181 /* ?transform@?$collate@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1182 /* ?transform@?$collate@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1183 /* ?transform@?$collate@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1184 /* ?transform@?$collate@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1185 DEFINE_THISCALL_WRAPPER(collate_wchar_transform, 16)
1186 basic_string_wchar* __thiscall collate_wchar_transform(const collate *this,
1187         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1188 {
1189     FIXME("(%p %p %p) stub\n", this, first, last);
1190     return ret;
1191 }
1192
1193 /* ??_7ctype_base@std@@6B@ */
1194 extern const vtable_ptr MSVCP_ctype_base_vtable;
1195
1196 /* ??0ctype_base@std@@QAE@I@Z */
1197 /* ??0ctype_base@std@@QEAA@_K@Z */
1198 DEFINE_THISCALL_WRAPPER(ctype_base_ctor_refs, 8)
1199 ctype_base* __thiscall ctype_base_ctor_refs(ctype_base *this, MSVCP_size_t refs)
1200 {
1201     TRACE("(%p %lu)\n", this, refs);
1202     locale_facet_ctor_refs(&this->facet, refs);
1203     this->facet.vtable = &MSVCP_ctype_base_vtable;
1204     return this;
1205 }
1206
1207 /* ??_Fctype_base@std@@QAEXXZ */
1208 /* ??_Fctype_base@std@@QEAAXXZ */
1209 DEFINE_THISCALL_WRAPPER(ctype_base_ctor, 4)
1210 ctype_base* __thiscall ctype_base_ctor(ctype_base *this)
1211 {
1212     TRACE("(%p)\n", this);
1213     locale_facet_ctor_refs(&this->facet, 0);
1214     this->facet.vtable = &MSVCP_ctype_base_vtable;
1215     return this;
1216 }
1217
1218 /* ??1ctype_base@std@@UAE@XZ */
1219 /* ??1ctype_base@std@@UEAA@XZ */
1220 DEFINE_THISCALL_WRAPPER(ctype_base_dtor, 4)
1221 void __thiscall ctype_base_dtor(ctype_base *this)
1222 {
1223     TRACE("(%p)\n", this);
1224 }
1225
1226 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_base_vector_dtor, 8)
1227 ctype_base* __thiscall MSVCP_ctype_base_vector_dtor(ctype_base *this, unsigned int flags)
1228 {
1229     TRACE("(%p %x)\n", this, flags);
1230     if(flags & 2) {
1231         /* we have an array, with the number of elements stored before the first object */
1232         int i, *ptr = (int *)this-1;
1233
1234         for(i=*ptr-1; i>=0; i--)
1235             ctype_base_dtor(this+i);
1236         MSVCRT_operator_delete(ptr);
1237     } else {
1238         ctype_base_dtor(this);
1239         if(flags & 1)
1240             MSVCRT_operator_delete(this);
1241     }
1242
1243     return this;
1244 }
1245
1246 /* ?_Xran@ctype_base@std@@KAXXZ */
1247 void __cdecl ctype_base__Xran(void)
1248 {
1249     throw_exception(EXCEPTION_OUT_OF_RANGE, "out of range in ctype<T>");
1250 }
1251
1252 /* ?id@?$ctype@D@std@@2V0locale@2@A */
1253 locale_id ctype_char_id = {0};
1254 /* ?table_size@?$ctype@D@std@@2IB */
1255 /* ?table_size@?$ctype@D@std@@2_KB */
1256 MSVCP_size_t ctype_char_table_size = 256;
1257
1258 /* ??_7?$ctype@D@std@@6B@ */
1259 extern const vtable_ptr MSVCP_ctype_char_vtable;
1260
1261 /* ?_Id_func@?$ctype@D@std@@SAAAVid@locale@2@XZ */
1262 /* ?_Id_func@?$ctype@D@std@@SAAEAVid@locale@2@XZ */
1263 locale_id* __cdecl ctype_char__Id_func(void)
1264 {
1265     TRACE("()\n");
1266     return &ctype_char_id;
1267 }
1268
1269 /* ?_Init@?$ctype@D@std@@IAEXABV_Locinfo@2@@Z */
1270 /* ?_Init@?$ctype@D@std@@IEAAXAEBV_Locinfo@2@@Z */
1271 DEFINE_THISCALL_WRAPPER(ctype_char__Init, 8)
1272 void __thiscall ctype_char__Init(ctype_char *this, const _Locinfo *locinfo)
1273 {
1274     TRACE("(%p %p)\n", this, locinfo);
1275     _Locinfo__Getctype(locinfo, &this->ctype);
1276 }
1277
1278 /* ?_Tidy@?$ctype@D@std@@IAEXXZ */
1279 /* ?_Tidy@?$ctype@D@std@@IEAAXXZ */
1280 DEFINE_THISCALL_WRAPPER(ctype_char__Tidy, 4)
1281 void __thiscall ctype_char__Tidy(ctype_char *this)
1282 {
1283     TRACE("(%p)\n", this);
1284
1285     if(this->ctype.delfl)
1286         free((short*)this->ctype.table);
1287 }
1288
1289 /* ?classic_table@?$ctype@D@std@@KAPBFXZ */
1290 /* ?classic_table@?$ctype@D@std@@KAPEBFXZ */
1291 const short* __cdecl ctype_char_classic_table(void)
1292 {
1293     TRACE("()\n");
1294     return &((short*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_ctype"))[1];
1295 }
1296
1297 /* ??0?$ctype@D@std@@QAE@ABV_Locinfo@1@I@Z */
1298 /* ??0?$ctype@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1299 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_locinfo, 12)
1300 ctype_char* __thiscall ctype_char_ctor_locinfo(ctype_char *this,
1301         const _Locinfo *locinfo, MSVCP_size_t refs)
1302 {
1303     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1304     ctype_base_ctor_refs(&this->base, refs);
1305     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1306     ctype_char__Init(this, locinfo);
1307     return this;
1308 }
1309
1310 /* ??0?$ctype@D@std@@QAE@PBF_NI@Z */
1311 /* ??0?$ctype@D@std@@QEAA@PEBF_N_K@Z */
1312 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_table, 16)
1313 ctype_char* __thiscall ctype_char_ctor_table(ctype_char *this,
1314         const short *table, MSVCP_bool delete, MSVCP_size_t refs)
1315 {
1316     _Locinfo locinfo;
1317
1318     TRACE("(%p %p %d %lu)\n", this, table, delete, refs);
1319
1320     ctype_base_ctor_refs(&this->base, refs);
1321     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1322
1323     _Locinfo_ctor(&locinfo);
1324     ctype_char__Init(this, &locinfo);
1325     _Locinfo_dtor(&locinfo);
1326
1327     if(table) {
1328         ctype_char__Tidy(this);
1329         this->ctype.table = table;
1330         this->ctype.delfl = delete;
1331     }
1332     return this;
1333 }
1334
1335 /* ??_F?$ctype@D@std@@QAEXXZ */
1336 /* ??_F?$ctype@D@std@@QEAAXXZ */
1337 DEFINE_THISCALL_WRAPPER(ctype_char_ctor, 4)
1338 ctype_char* __thiscall ctype_char_ctor(ctype_char *this)
1339 {
1340     return ctype_char_ctor_table(this, NULL, FALSE, 0);
1341 }
1342
1343 /* ??1?$ctype@D@std@@MAE@XZ */
1344 /* ??1?$ctype@D@std@@MEAA@XZ */
1345 DEFINE_THISCALL_WRAPPER(ctype_char_dtor, 4)
1346 void __thiscall ctype_char_dtor(ctype_char *this)
1347 {
1348     TRACE("(%p)\n", this);
1349     ctype_char__Tidy(this);
1350 }
1351
1352 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_char_vector_dtor, 8)
1353 ctype_char* __thiscall MSVCP_ctype_char_vector_dtor(ctype_char *this, unsigned int flags)
1354 {
1355     TRACE("(%p %x)\n", this, flags);
1356     if(flags & 2) {
1357         /* we have an array, with the number of elements stored before the first object */
1358         int i, *ptr = (int *)this-1;
1359
1360         for(i=*ptr-1; i>=0; i--)
1361             ctype_char_dtor(this+i);
1362         MSVCRT_operator_delete(ptr);
1363     } else {
1364         ctype_char_dtor(this);
1365         if(flags & 1)
1366             MSVCRT_operator_delete(this);
1367     }
1368
1369     return this;
1370 }
1371
1372 /* ?do_narrow@?$ctype@D@std@@MBEDDD@Z */
1373 /* ?do_narrow@?$ctype@D@std@@MEBADDD@Z */
1374 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow_ch, 12)
1375 #define call_ctype_char_do_narrow_ch(this, ch, unused) CALL_VTBL_FUNC(this, 36, \
1376         char, (const ctype_char*, char, char), (this, ch, unused))
1377 char __thiscall ctype_char_do_narrow_ch(const ctype_char *this, char ch, char unused)
1378 {
1379     TRACE("(%p %c %c)\n", this, ch, unused);
1380     return ch;
1381 }
1382
1383 /* ?do_narrow@?$ctype@D@std@@MBEPBDPBD0DPAD@Z */
1384 /* ?do_narrow@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD@Z */
1385 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow, 20)
1386 #define call_ctype_char_do_narrow(this, first, last, unused, dest) CALL_VTBL_FUNC(this, 32, \
1387         const char*, (const ctype_char*, const char*, const char*, char, char*), \
1388         (this, first, last, unused, dest))
1389 const char* __thiscall ctype_char_do_narrow(const ctype_char *this,
1390         const char *first, const char *last, char unused, char *dest)
1391 {
1392     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1393     memcpy(dest, first, last-first);
1394     return last;
1395 }
1396
1397 /* ?_Do_narrow_s@?$ctype@D@std@@MBEPBDPBD0DPADI@Z */
1398 /* ?_Do_narrow_s@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD_K@Z */
1399 DEFINE_THISCALL_WRAPPER(ctype_char__Do_narrow_s, 24)
1400 #define call_ctype_char__Do_narrow_s(this, first, last, unused, dest, size) CALL_VTBL_FUNC(this, 40, \
1401         const char*, (const ctype_char*, const char*, const char*, char, char*, MSVCP_size_t), \
1402         (this, first, last, unused, dest, size))
1403 const char* __thiscall ctype_char__Do_narrow_s(const ctype_char *this, const char *first,
1404         const char *last, char unused, char *dest, MSVCP_size_t size)
1405 {
1406     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1407     memcpy_s(dest, size, first, last-first);
1408     return last;
1409 }
1410
1411 /* ?narrow@?$ctype@D@std@@QBEDDD@Z */
1412 /* ?narrow@?$ctype@D@std@@QEBADDD@Z */
1413 DEFINE_THISCALL_WRAPPER(ctype_char_narrow_ch, 12)
1414 char __thiscall ctype_char_narrow_ch(const ctype_char *this, char ch, char dflt)
1415 {
1416     TRACE("(%p %c %c)\n", this, ch, dflt);
1417     return call_ctype_char_do_narrow_ch(this, ch, dflt);
1418 }
1419
1420 /* ?narrow@?$ctype@D@std@@QBEPBDPBD0DPAD@Z */
1421 /* ?narrow@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD@Z */
1422 DEFINE_THISCALL_WRAPPER(ctype_char_narrow, 20)
1423 const char* __thiscall ctype_char_narrow(const ctype_char *this,
1424         const char *first, const char *last, char dflt, char *dest)
1425 {
1426     TRACE("(%p %p %p %c %p)\n", this, first, last, dflt, dest);
1427     return call_ctype_char_do_narrow(this, first, last, dflt, dest);
1428 }
1429
1430 /* ?_Narrow_s@?$ctype@D@std@@QBEPBDPBD0DPADI@Z */
1431 /* ?_Narrow_s@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD_K@Z */
1432 DEFINE_THISCALL_WRAPPER(ctype_char__Narrow_s, 24)
1433 const char* __thiscall ctype_char__Narrow_s(const ctype_char *this, const char *first,
1434         const char *last, char dflt, char *dest, MSVCP_size_t size)
1435 {
1436     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1437     return call_ctype_char__Do_narrow_s(this, first, last, dflt, dest, size);
1438 }
1439
1440 /* ?do_widen@?$ctype@D@std@@MBEDD@Z */
1441 /* ?do_widen@?$ctype@D@std@@MEBADD@Z */
1442 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen_ch, 8)
1443 #define call_ctype_char_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
1444         char, (const ctype_char*, char), (this, ch))
1445 char __thiscall ctype_char_do_widen_ch(const ctype_char *this, char ch)
1446 {
1447     TRACE("(%p %c)\n", this, ch);
1448     return ch;
1449 }
1450
1451 /* ?do_widen@?$ctype@D@std@@MBEPBDPBD0PAD@Z */
1452 /* ?do_widen@?$ctype@D@std@@MEBAPEBDPEBD0PEAD@Z */
1453 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen, 16)
1454 #define call_ctype_char_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 20, \
1455         const char*, (const ctype_char*, const char*, const char*, char*), \
1456         (this, first, last, dest))
1457 const char* __thiscall ctype_char_do_widen(const ctype_char *this,
1458         const char *first, const char *last, char *dest)
1459 {
1460     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1461     memcpy(dest, first, last-first);
1462     return last;
1463 }
1464
1465 /* ?_Do_widen_s@?$ctype@D@std@@MBEPBDPBD0PADI@Z */
1466 /* ?_Do_widen_s@?$ctype@D@std@@MEBAPEBDPEBD0PEAD_K@Z */
1467 DEFINE_THISCALL_WRAPPER(ctype_char__Do_widen_s, 20)
1468 #define call_ctype_char__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 28, \
1469         const char*, (const ctype_char*, const char*, const char*, char*, MSVCP_size_t), \
1470         (this, first, last, dest, size))
1471 const char* __thiscall ctype_char__Do_widen_s(const ctype_char *this,
1472         const char *first, const char *last, char *dest, MSVCP_size_t size)
1473 {
1474     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1475     memcpy_s(dest, size, first, last-first);
1476     return last;
1477 }
1478
1479 /* ?widen@?$ctype@D@std@@QBEDD@Z */
1480 /* ?widen@?$ctype@D@std@@QEBADD@Z */
1481 DEFINE_THISCALL_WRAPPER(ctype_char_widen_ch, 8)
1482 char __thiscall ctype_char_widen_ch(const ctype_char *this, char ch)
1483 {
1484     TRACE("(%p %c)\n", this, ch);
1485     return call_ctype_char_do_widen_ch(this, ch);
1486 }
1487
1488 /* ?widen@?$ctype@D@std@@QBEPBDPBD0PAD@Z */
1489 /* ?widen@?$ctype@D@std@@QEBAPEBDPEBD0PEAD@Z */
1490 DEFINE_THISCALL_WRAPPER(ctype_char_widen, 16)
1491 const char* __thiscall ctype_char_widen(const ctype_char *this,
1492         const char *first, const char *last, char *dest)
1493 {
1494     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1495     return call_ctype_char_do_widen(this, first, last, dest);
1496 }
1497
1498 /* ?_Widen_s@?$ctype@D@std@@QBEPBDPBD0PADI@Z */
1499 /* ?_Widen_s@?$ctype@D@std@@QEBAPEBDPEBD0PEAD_K@Z */
1500 DEFINE_THISCALL_WRAPPER(ctype_char__Widen_s, 20)
1501 const char* __thiscall ctype_char__Widen_s(const ctype_char *this,
1502         const char *first, const char *last, char *dest, MSVCP_size_t size)
1503 {
1504     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1505     return call_ctype_char__Do_widen_s(this, first, last, dest, size);
1506 }
1507
1508 /* ?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1509 /* ?_Getcat@?$ctype@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1510 MSVCP_size_t __cdecl ctype_char__Getcat(const locale_facet **facet, const locale *loc)
1511 {
1512     TRACE("(%p %p)\n", facet, loc);
1513
1514     if(facet && !*facet) {
1515         _Locinfo locinfo;
1516
1517         *facet = MSVCRT_operator_new(sizeof(ctype_char));
1518         if(!*facet) {
1519             ERR("Out of memory\n");
1520             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1521             return 0;
1522         }
1523
1524         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
1525         ctype_char_ctor_locinfo((ctype_char*)*facet, &locinfo, 0);
1526         _Locinfo_dtor(&locinfo);
1527     }
1528
1529     return LC_CTYPE;
1530 }
1531
1532 ctype_char* ctype_char_use_facet(const locale *loc)
1533 {
1534     static ctype_char *obj = NULL;
1535
1536     _Lockit lock;
1537     const locale_facet *fac;
1538
1539     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
1540     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_char_id));
1541     if(fac) {
1542         _Lockit_dtor(&lock);
1543         return (ctype_char*)fac;
1544     }
1545
1546     if(obj) {
1547         _Lockit_dtor(&lock);
1548         return obj;
1549     }
1550
1551     ctype_char__Getcat(&fac, loc);
1552     obj = (ctype_char*)fac;
1553     locale_facet__Incref(&obj->base.facet);
1554     locale_facet_register(&obj->base.facet);
1555     _Lockit_dtor(&lock);
1556
1557     return obj;
1558 }
1559
1560 /* _Tolower */
1561 int __cdecl _Tolower(int ch, const _Ctypevec *ctype)
1562 {
1563     unsigned int cp;
1564
1565     TRACE("%d %p\n", ch, ctype);
1566
1567     if(ctype)
1568         cp = ctype->page;
1569     else
1570         cp = ___lc_codepage_func();
1571
1572     /* Don't convert to unicode in case of C locale */
1573     if(!cp) {
1574         if(ch>='A' && ch<='Z')
1575             ch = ch-'A'+'a';
1576         return ch;
1577     } else {
1578         WCHAR wide, lower;
1579         char str[2];
1580         int size;
1581
1582         if(ch > 255) {
1583             str[0] = (ch>>8) & 255;
1584             str[1] = ch & 255;
1585             size = 2;
1586         } else {
1587             str[0] = ch & 255;
1588             size = 1;
1589         }
1590
1591         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1592             return ch;
1593
1594         lower = tolowerW(wide);
1595         if(lower == wide)
1596             return ch;
1597
1598         WideCharToMultiByte(cp, 0, &lower, 1, str, 2, NULL, NULL);
1599
1600         return str[0] + (str[1]<<8);
1601     }
1602 }
1603
1604 /* ?do_tolower@?$ctype@D@std@@MBEDD@Z */
1605 /* ?do_tolower@?$ctype@D@std@@MEBADD@Z */
1606 #define call_ctype_char_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 8, \
1607         char, (const ctype_char*, char), (this, ch))
1608 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower_ch, 8)
1609 char __thiscall ctype_char_do_tolower_ch(const ctype_char *this, char ch)
1610 {
1611     TRACE("(%p %c)\n", this, ch);
1612     return _Tolower(ch, &this->ctype);
1613 }
1614
1615 /* ?do_tolower@?$ctype@D@std@@MBEPBDPADPBD@Z */
1616 /* ?do_tolower@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1617 #define call_ctype_char_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 4, \
1618         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1619 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower, 12)
1620 const char* __thiscall ctype_char_do_tolower(const ctype_char *this, char *first, const char *last)
1621 {
1622     TRACE("(%p %p %p)\n", this, first, last);
1623     for(; first<last; first++)
1624         *first = _Tolower(*first, &this->ctype);
1625     return last;
1626 }
1627
1628 /* ?tolower@?$ctype@D@std@@QBEDD@Z */
1629 /* ?tolower@?$ctype@D@std@@QEBADD@Z */
1630 DEFINE_THISCALL_WRAPPER(ctype_char_tolower_ch, 8)
1631 char __thiscall ctype_char_tolower_ch(const ctype_char *this, char ch)
1632 {
1633     TRACE("(%p %c)\n", this, ch);
1634     return call_ctype_char_do_tolower_ch(this, ch);
1635 }
1636
1637 /* ?tolower@?$ctype@D@std@@QBEPBDPADPBD@Z */
1638 /* ?tolower@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1639 DEFINE_THISCALL_WRAPPER(ctype_char_tolower, 12)
1640 const char* __thiscall ctype_char_tolower(const ctype_char *this, char *first, const char *last)
1641 {
1642     TRACE("(%p %p %p)\n", this, first, last);
1643     return call_ctype_char_do_tolower(this, first, last);
1644 }
1645
1646 /* _Toupper */
1647 int __cdecl _Toupper(int ch, const _Ctypevec *ctype)
1648 {
1649     unsigned int cp;
1650
1651     TRACE("%d %p\n", ch, ctype);
1652
1653     if(ctype)
1654         cp = ctype->page;
1655     else
1656         cp = ___lc_codepage_func();
1657
1658     /* Don't convert to unicode in case of C locale */
1659     if(!cp) {
1660         if(ch>='a' && ch<='z')
1661             ch = ch-'a'+'A';
1662         return ch;
1663     } else {
1664         WCHAR wide, upper;
1665         char str[2];
1666         int size;
1667
1668         if(ch > 255) {
1669             str[0] = (ch>>8) & 255;
1670             str[1] = ch & 255;
1671             size = 2;
1672         } else {
1673             str[0] = ch & 255;
1674             size = 1;
1675         }
1676
1677         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1678             return ch;
1679
1680         upper = toupperW(wide);
1681         if(upper == wide)
1682             return ch;
1683
1684         WideCharToMultiByte(cp, 0, &upper, 1, str, 2, NULL, NULL);
1685
1686         return str[0] + (str[1]<<8);
1687     }
1688 }
1689
1690 /* ?do_toupper@?$ctype@D@std@@MBEDD@Z */
1691 /* ?do_toupper@?$ctype@D@std@@MEBADD@Z */
1692 #define call_ctype_char_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 16, \
1693         char, (const ctype_char*, char), (this, ch))
1694 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper_ch, 8)
1695 char __thiscall ctype_char_do_toupper_ch(const ctype_char *this, char ch)
1696 {
1697     TRACE("(%p %c)\n", this, ch);
1698     return _Toupper(ch, &this->ctype);
1699 }
1700
1701 /* ?do_toupper@?$ctype@D@std@@MBEPBDPADPBD@Z */
1702 /* ?do_toupper@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1703 #define call_ctype_char_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 12, \
1704         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1705 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper, 12)
1706 const char* __thiscall ctype_char_do_toupper(const ctype_char *this,
1707         char *first, const char *last)
1708 {
1709     TRACE("(%p %p %p)\n", this, first, last);
1710     for(; first<last; first++)
1711         *first = _Toupper(*first, &this->ctype);
1712     return last;
1713 }
1714
1715 /* ?toupper@?$ctype@D@std@@QBEDD@Z */
1716 /* ?toupper@?$ctype@D@std@@QEBADD@Z */
1717 DEFINE_THISCALL_WRAPPER(ctype_char_toupper_ch, 8)
1718 char __thiscall ctype_char_toupper_ch(const ctype_char *this, char ch)
1719 {
1720     TRACE("(%p %c)\n", this, ch);
1721     return call_ctype_char_do_toupper_ch(this, ch);
1722 }
1723
1724 /* ?toupper@?$ctype@D@std@@QBEPBDPADPBD@Z */
1725 /* ?toupper@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1726 DEFINE_THISCALL_WRAPPER(ctype_char_toupper, 12)
1727 const char* __thiscall ctype_char_toupper(const ctype_char *this, char *first, const char *last)
1728 {
1729     TRACE("(%p %p %p)\n", this, first, last);
1730     return call_ctype_char_do_toupper(this, first, last);
1731 }
1732
1733 /* ?is@?$ctype@D@std@@QBE_NFD@Z */
1734 /* ?is@?$ctype@D@std@@QEBA_NFD@Z */
1735 DEFINE_THISCALL_WRAPPER(ctype_char_is_ch, 12)
1736 MSVCP_bool __thiscall ctype_char_is_ch(const ctype_char *this, short mask, char ch)
1737 {
1738     TRACE("(%p %x %c)\n", this, mask, ch);
1739     return (this->ctype.table[(unsigned char)ch] & mask) != 0;
1740 }
1741
1742 /* ?is@?$ctype@D@std@@QBEPBDPBD0PAF@Z */
1743 /* ?is@?$ctype@D@std@@QEBAPEBDPEBD0PEAF@Z */
1744 DEFINE_THISCALL_WRAPPER(ctype_char_is, 16)
1745 const char* __thiscall ctype_char_is(const ctype_char *this, const char *first, const char *last, short *dest)
1746 {
1747     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1748     for(; first<last; first++)
1749         *dest++ = this->ctype.table[(unsigned char)*first];
1750     return last;
1751 }
1752
1753 /* ?scan_is@?$ctype@D@std@@QBEPBDFPBD0@Z */
1754 /* ?scan_is@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1755 DEFINE_THISCALL_WRAPPER(ctype_char_scan_is, 16)
1756 const char* __thiscall ctype_char_scan_is(const ctype_char *this, short mask, const char *first, const char *last)
1757 {
1758     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1759     for(; first<last; first++)
1760         if(!ctype_char_is_ch(this, mask, *first))
1761             break;
1762     return first;
1763 }
1764
1765 /* ?scan_not@?$ctype@D@std@@QBEPBDFPBD0@Z */
1766 /* ?scan_not@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1767 DEFINE_THISCALL_WRAPPER(ctype_char_scan_not, 16)
1768 const char* __thiscall ctype_char_scan_not(const ctype_char *this, short mask, const char *first, const char *last)
1769 {
1770     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1771     for(; first<last; first++)
1772         if(ctype_char_is_ch(this, mask, *first))
1773             break;
1774     return first;
1775 }
1776
1777 /* ?table@?$ctype@D@std@@IBEPBFXZ */
1778 /* ?table@?$ctype@D@std@@IEBAPEBFXZ */
1779 DEFINE_THISCALL_WRAPPER(ctype_char_table, 4)
1780 const short* __thiscall ctype_char_table(const ctype_char *this)
1781 {
1782     TRACE("(%p)\n", this);
1783     return this->ctype.table;
1784 }
1785
1786 /* ?id@?$ctype@_W@std@@2V0locale@2@A */
1787 locale_id ctype_wchar_id = {0};
1788 /* ?id@?$ctype@G@std@@2V0locale@2@A */
1789 locale_id ctype_short_id = {0};
1790
1791 /* ??_7?$ctype@_W@std@@6B@ */
1792 extern const vtable_ptr MSVCP_ctype_wchar_vtable;
1793 /* ??_7?$ctype@G@std@@6B@ */
1794 extern const vtable_ptr MSVCP_ctype_short_vtable;
1795
1796 /* ?_Id_func@?$ctype@_W@std@@SAAAVid@locale@2@XZ */
1797 /* ?_Id_func@?$ctype@_W@std@@SAAEAVid@locale@2@XZ */
1798 locale_id* __cdecl ctype_wchar__Id_func(void)
1799 {
1800     TRACE("()\n");
1801     return &ctype_wchar_id;
1802 }
1803
1804 /* ?_Id_func@?$ctype@G@std@@SAAAVid@locale@2@XZ */
1805 /* ?_Id_func@?$ctype@G@std@@SAAEAVid@locale@2@XZ */
1806 locale_id* __cdecl ctype_short__Id_func(void)
1807 {
1808     TRACE("()\n");
1809     return &ctype_short_id;
1810 }
1811
1812 /* ?_Init@?$ctype@_W@std@@IAEXABV_Locinfo@2@@Z */
1813 /* ?_Init@?$ctype@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
1814 /* ?_Init@?$ctype@G@std@@IAEXABV_Locinfo@2@@Z */
1815 /* ?_Init@?$ctype@G@std@@IEAAXAEBV_Locinfo@2@@Z */
1816 DEFINE_THISCALL_WRAPPER(ctype_wchar__Init, 8)
1817 void __thiscall ctype_wchar__Init(ctype_wchar *this, const _Locinfo *locinfo)
1818 {
1819     TRACE("(%p %p)\n", this, locinfo);
1820     _Locinfo__Getctype(locinfo, &this->ctype);
1821     _Locinfo__Getcvt(locinfo, &this->cvt);
1822 }
1823
1824 /* ??0?$ctype@_W@std@@QAE@ABV_Locinfo@1@I@Z */
1825 /* ??0?$ctype@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1826 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_locinfo, 12)
1827 ctype_wchar* __thiscall ctype_wchar_ctor_locinfo(ctype_wchar *this,
1828         const _Locinfo *locinfo, MSVCP_size_t refs)
1829 {
1830     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1831     ctype_base_ctor_refs(&this->base, refs);
1832     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1833     ctype_wchar__Init(this, locinfo);
1834     return this;
1835 }
1836
1837 /* ??0?$ctype@G@std@@QAE@ABV_Locinfo@1@I@Z */
1838 /* ??0?$ctype@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1839 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_locinfo, 12)
1840 ctype_wchar* __thiscall ctype_short_ctor_locinfo(ctype_wchar *this,
1841         const _Locinfo *locinfo, MSVCP_size_t refs)
1842 {
1843     ctype_wchar *ret = ctype_wchar_ctor_locinfo(this, locinfo, refs);
1844     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1845     return ret;
1846 }
1847
1848 /* ??0?$ctype@_W@std@@QAE@I@Z */
1849 /* ??0?$ctype@_W@std@@QEAA@_K@Z */
1850 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_refs, 8)
1851 ctype_wchar* __thiscall ctype_wchar_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1852 {
1853     _Locinfo locinfo;
1854
1855     TRACE("(%p %lu)\n", this, refs);
1856
1857     ctype_base_ctor_refs(&this->base, refs);
1858     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1859
1860     _Locinfo_ctor(&locinfo);
1861     ctype_wchar__Init(this, &locinfo);
1862     _Locinfo_dtor(&locinfo);
1863     return this;
1864 }
1865
1866 /* ??0?$ctype@G@std@@QAE@I@Z */
1867 /* ??0?$ctype@G@std@@QEAA@_K@Z */
1868 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_refs, 8)
1869 ctype_wchar* __thiscall ctype_short_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1870 {
1871     ctype_wchar *ret = ctype_wchar_ctor_refs(this, refs);
1872     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1873     return ret;
1874 }
1875
1876 /* ??0?$ctype@G@std@@IAE@PBDI@Z */
1877 /* ??0?$ctype@G@std@@IEAA@PEBD_K@Z */
1878 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_name, 12)
1879 ctype_wchar* __thiscall ctype_short_ctor_name(ctype_wchar *this,
1880     const char *name, MSVCP_size_t refs)
1881 {
1882     _Locinfo locinfo;
1883
1884     TRACE("(%p %s %lu)\n", this, debugstr_a(name), refs);
1885
1886     ctype_base_ctor_refs(&this->base, refs);
1887     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1888
1889     _Locinfo_ctor_cstr(&locinfo, name);
1890     ctype_wchar__Init(this, &locinfo);
1891     _Locinfo_dtor(&locinfo);
1892     return this;
1893 }
1894
1895 /* ??_F?$ctype@_W@std@@QAEXXZ */
1896 /* ??_F?$ctype@_W@std@@QEAAXXZ */
1897 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor, 4)
1898 ctype_wchar* __thiscall ctype_wchar_ctor(ctype_wchar *this)
1899 {
1900     TRACE("(%p)\n", this);
1901     return ctype_short_ctor_refs(this, 0);
1902 }
1903
1904 /* ??_F?$ctype@G@std@@QAEXXZ */
1905 /* ??_F?$ctype@G@std@@QEAAXXZ */
1906 DEFINE_THISCALL_WRAPPER(ctype_short_ctor, 4)
1907 ctype_wchar* __thiscall ctype_short_ctor(ctype_wchar *this)
1908 {
1909     ctype_wchar *ret = ctype_wchar_ctor(this);
1910     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1911     return ret;
1912 }
1913
1914 /* ??1?$ctype@_W@std@@MAE@XZ */
1915 /* ??1?$ctype@_W@std@@MEAA@XZ */
1916 /* ??1?$ctype@G@std@@MAE@XZ */
1917 /* ??1?$ctype@G@std@@MEAA@XZ */
1918 DEFINE_THISCALL_WRAPPER(ctype_wchar_dtor, 4)
1919 void __thiscall ctype_wchar_dtor(ctype_wchar *this)
1920 {
1921     TRACE("(%p)\n", this);
1922     if(this->ctype.delfl)
1923         free((void*)this->ctype.table);
1924 }
1925
1926 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_wchar_vector_dtor, 8)
1927 ctype_wchar* __thiscall MSVCP_ctype_wchar_vector_dtor(ctype_wchar *this, unsigned int flags)
1928 {
1929     TRACE("(%p %x)\n", this, flags);
1930     if(flags & 2) {
1931         /* we have an array, with the number of elements stored before the first object */
1932         int i, *ptr = (int *)this-1;
1933
1934         for(i=*ptr-1; i>=0; i--)
1935             ctype_wchar_dtor(this+i);
1936         MSVCRT_operator_delete(ptr);
1937     } else {
1938         ctype_wchar_dtor(this);
1939         if(flags & 1)
1940             MSVCRT_operator_delete(this);
1941     }
1942
1943     return this;
1944 }
1945
1946 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_short_vector_dtor, 8)
1947 ctype_wchar* __thiscall MSVCP_ctype_short_vector_dtor(ctype_wchar *this, unsigned int flags)
1948 {
1949     return MSVCP_ctype_wchar_vector_dtor(this, flags);
1950 }
1951
1952 /* _Wcrtomb */
1953 int __cdecl _Wcrtomb(char *s, wchar_t wch, int *state, const _Cvtvec *cvt)
1954 {
1955     int cp, size;
1956     BOOL def;
1957
1958     TRACE("%p %d %p %p\n", s, wch, state, cvt);
1959
1960     if(cvt)
1961         cp = cvt->page;
1962     else
1963         cp = ___lc_codepage_func();
1964
1965     if(!cp) {
1966         if(wch > 255) {
1967            *_errno() = EILSEQ;
1968            return -1;
1969         }
1970
1971         *s = wch & 255;
1972         return 1;
1973     }
1974
1975     size = WideCharToMultiByte(cp, 0, &wch, 1, s, MB_LEN_MAX, NULL, &def);
1976     if(!size || def) {
1977         *_errno() = EILSEQ;
1978         return -1;
1979     }
1980
1981     return size;
1982 }
1983
1984 /* ?_Donarrow@?$ctype@_W@std@@IBED_WD@Z */
1985 /* ?_Donarrow@?$ctype@_W@std@@IEBAD_WD@Z */
1986 /* ?_Donarrow@?$ctype@G@std@@IBEDGD@Z */
1987 /* ?_Donarrow@?$ctype@G@std@@IEBADGD@Z */
1988 DEFINE_THISCALL_WRAPPER(ctype_wchar__Donarrow, 12)
1989 char __thiscall ctype_wchar__Donarrow(const ctype_wchar *this, wchar_t ch, char dflt)
1990 {
1991     char buf[MB_LEN_MAX];
1992
1993     TRACE("(%p %d %d)\n", this, ch, dflt);
1994
1995     return _Wcrtomb(buf, ch, NULL, &this->cvt)==1 ? buf[0] : dflt;
1996 }
1997
1998 /* ?do_narrow@?$ctype@_W@std@@MBED_WD@Z */
1999 /* ?do_narrow@?$ctype@_W@std@@MEBAD_WD@Z */
2000 /* ?do_narrow@?$ctype@G@std@@MBEDGD@Z */
2001 /* ?do_narrow@?$ctype@G@std@@MEBADGD@Z */
2002 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow_ch, 12)
2003 #define call_ctype_wchar_do_narrow_ch(this, ch, dflt) CALL_VTBL_FUNC(this, 52, \
2004         char, (const ctype_wchar*, wchar_t, char), (this, ch, dflt))
2005 char __thiscall ctype_wchar_do_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
2006 {
2007     return ctype_wchar__Donarrow(this, ch, dflt);
2008 }
2009
2010 /* ?do_narrow@?$ctype@_W@std@@MBEPB_WPB_W0DPAD@Z */
2011 /* ?do_narrow@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD@Z */
2012 /* ?do_narrow@?$ctype@G@std@@MBEPBGPBG0DPAD@Z */
2013 /* ?do_narrow@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD@Z */
2014 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow, 20)
2015 #define call_ctype_wchar_do_narrow(this, first, last, dflt, dest) CALL_VTBL_FUNC(this, 48, \
2016         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*), \
2017         (this, first, last, dflt, dest))
2018 const wchar_t* __thiscall ctype_wchar_do_narrow(const ctype_wchar *this,
2019         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
2020 {
2021     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
2022     for(; first<last; first++)
2023         *dest++ = ctype_wchar__Donarrow(this, *first, dflt);
2024     return last;
2025 }
2026
2027 /* ?_Do_narrow_s@?$ctype@_W@std@@MBEPB_WPB_W0DPADI@Z */
2028 /* ?_Do_narrow_s@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD_K@Z */
2029 /* ?_Do_narrow_s@?$ctype@G@std@@MBEPBGPBG0DPADI@Z */
2030 /* ?_Do_narrow_s@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD_K@Z */
2031 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_narrow_s, 24)
2032 #define call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size) CALL_VTBL_FUNC(this, 56, \
2033         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*, MSVCP_size_t), \
2034         (this, first, last, dflt, dest, size))
2035 const wchar_t* __thiscall ctype_wchar__Do_narrow_s(const ctype_wchar *this,
2036         const wchar_t *first, const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
2037 {
2038     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
2039     /* This function converts all multi-byte characters to dflt,
2040      * thanks to it result size is known before converting */
2041     if(last-first > size)
2042         ctype_base__Xran();
2043     return ctype_wchar_do_narrow(this, first, last, dflt, dest);
2044 }
2045
2046 /* ?narrow@?$ctype@_W@std@@QBED_WD@Z */
2047 /* ?narrow@?$ctype@_W@std@@QEBAD_WD@Z */
2048 /* ?narrow@?$ctype@G@std@@QBEDGD@Z */
2049 /* ?narrow@?$ctype@G@std@@QEBADGD@Z */
2050 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow_ch, 12)
2051 char __thiscall ctype_wchar_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
2052 {
2053     TRACE("(%p %d %d)\n", this, ch, dflt);
2054     return call_ctype_wchar_do_narrow_ch(this, ch, dflt);
2055 }
2056
2057 /* ?narrow@?$ctype@_W@std@@QBEPB_WPB_W0DPAD@Z */
2058 /* ?narrow@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD@Z */
2059 /* ?narrow@?$ctype@G@std@@QBEPBGPBG0DPAD@Z */
2060 /* ?narrow@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD@Z */
2061 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow, 20)
2062 const wchar_t* __thiscall ctype_wchar_narrow(const ctype_wchar *this,
2063         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
2064 {
2065     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
2066     return call_ctype_wchar_do_narrow(this, first, last, dflt, dest);
2067 }
2068
2069 /* ?_Narrow_s@?$ctype@_W@std@@QBEPB_WPB_W0DPADI@Z */
2070 /* ?_Narrow_s@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD_K@Z */
2071 /* ?_Narrow_s@?$ctype@G@std@@QBEPBGPBG0DPADI@Z */
2072 /* ?_Narrow_s@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD_K@Z */
2073 DEFINE_THISCALL_WRAPPER(ctype_wchar__Narrow_s, 24)
2074 const wchar_t* __thiscall ctype_wchar__Narrow_s(const ctype_wchar *this, const wchar_t *first,
2075         const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
2076 {
2077     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
2078     return call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size);
2079 }
2080
2081 /* _Mbrtowc */
2082 int __cdecl _Mbrtowc(wchar_t *out, const char *in, MSVCP_size_t len, int *state, const _Cvtvec *cvt)
2083 {
2084     int i, cp;
2085     CPINFO cp_info;
2086     BOOL is_lead;
2087
2088     TRACE("(%p %p %lu %p %p)\n", out, in, len, state, cvt);
2089
2090     if(!len)
2091         return 0;
2092
2093     if(cvt)
2094         cp = cvt->page;
2095     else
2096         cp = ___lc_codepage_func();
2097
2098     if(!cp) {
2099         if(out)
2100             *out = (unsigned char)*in;
2101
2102         *state = 0;
2103         return *in ? 1 : 0;
2104     }
2105
2106     if(*state) {
2107         ((char*)state)[1] = *in;
2108
2109         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, (char*)state, 2, out, out ? 1 : 0)) {
2110             *state = 0;
2111             *_errno() = EILSEQ;
2112             return -1;
2113         }
2114
2115         *state = 0;
2116         return 2;
2117     }
2118
2119     GetCPInfo(cp, &cp_info);
2120     is_lead = FALSE;
2121     for(i=0; i<MAX_LEADBYTES; i+=2) {
2122         if(!cp_info.LeadByte[i+1])
2123             break;
2124         if((unsigned char)*in>=cp_info.LeadByte[i] && (unsigned char)*in<=cp_info.LeadByte[i+1]) {
2125             is_lead = TRUE;
2126             break;
2127         }
2128     }
2129
2130     if(is_lead) {
2131         if(len == 1) {
2132             *state = (unsigned char)*in;
2133             return -2;
2134         }
2135
2136         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 2, out, out ? 1 : 0)) {
2137             *_errno() = EILSEQ;
2138             return -1;
2139         }
2140         return 2;
2141     }
2142
2143     if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 1, out, out ? 1 : 0)) {
2144         *_errno() = EILSEQ;
2145         return -1;
2146     }
2147     return 1;
2148 }
2149
2150 /* ?_Dowiden@?$ctype@_W@std@@IBE_WD@Z */
2151 /* ?_Dowiden@?$ctype@_W@std@@IEBA_WD@Z */
2152 /* ?_Dowiden@?$ctype@G@std@@IBEGD@Z */
2153 /* ?_Dowiden@?$ctype@G@std@@IEBAGD@Z */
2154 DEFINE_THISCALL_WRAPPER(ctype_wchar__Dowiden, 8)
2155 wchar_t __thiscall ctype_wchar__Dowiden(const ctype_wchar *this, char ch)
2156 {
2157     wchar_t ret;
2158     int state = 0;
2159     TRACE("(%p %d)\n", this, ch);
2160     return _Mbrtowc(&ret, &ch, 1, &state, &this->cvt)<0 ? WEOF : ret;
2161 }
2162
2163 /* ?do_widen@?$ctype@_W@std@@MBE_WD@Z */
2164 /* ?do_widen@?$ctype@_W@std@@MEBA_WD@Z */
2165 /* ?do_widen@?$ctype@G@std@@MBEGD@Z */
2166 /* ?do_widen@?$ctype@G@std@@MEBAGD@Z */
2167 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen_ch, 8)
2168 #define call_ctype_wchar_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 40, \
2169         wchar_t, (const ctype_wchar*, char), (this, ch))
2170 wchar_t __thiscall ctype_wchar_do_widen_ch(const ctype_wchar *this, char ch)
2171 {
2172     return ctype_wchar__Dowiden(this, ch);
2173 }
2174
2175 /* ?do_widen@?$ctype@_W@std@@MBEPBDPBD0PA_W@Z */
2176 /* ?do_widen@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W@Z */
2177 /* ?do_widen@?$ctype@G@std@@MBEPBDPBD0PAG@Z */
2178 /* ?do_widen@?$ctype@G@std@@MEBAPEBDPEBD0PEAG@Z */
2179 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen, 16)
2180 #define call_ctype_wchar_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 36, \
2181         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*), \
2182         (this, first, last, dest))
2183 const char* __thiscall ctype_wchar_do_widen(const ctype_wchar *this,
2184         const char *first, const char *last, wchar_t *dest)
2185 {
2186     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2187     for(; first<last; first++)
2188         *dest++ = ctype_wchar__Dowiden(this, *first);
2189     return last;
2190 }
2191
2192 /* ?_Do_widen_s@?$ctype@_W@std@@MBEPBDPBD0PA_WI@Z */
2193 /* ?_Do_widen_s@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W_K@Z */
2194 /* ?_Do_widen_s@?$ctype@G@std@@MBEPBDPBD0PAGI@Z */
2195 /* ?_Do_widen_s@?$ctype@G@std@@MEBAPEBDPEBD0PEAG_K@Z */
2196 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_widen_s, 20)
2197 #define call_ctype_wchar__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 44, \
2198         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*, MSVCP_size_t), \
2199         (this, first, last, dest, size))
2200 const char* __thiscall ctype_wchar__Do_widen_s(const ctype_wchar *this,
2201         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2202 {
2203     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2204     /* This function converts all multi-byte characters to WEOF,
2205      * thanks to it result size is known before converting */
2206     if(size < last-first)
2207         ctype_base__Xran();
2208     return ctype_wchar_do_widen(this, first, last, dest);
2209 }
2210
2211 /* ?widen@?$ctype@_W@std@@QBE_WD@Z */
2212 /* ?widen@?$ctype@_W@std@@QEBA_WD@Z */
2213 /* ?widen@?$ctype@G@std@@QBEGD@Z */
2214 /* ?widen@?$ctype@G@std@@QEBAGD@Z */
2215 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen_ch, 8)
2216 wchar_t __thiscall ctype_wchar_widen_ch(const ctype_wchar *this, char ch)
2217 {
2218     TRACE("(%p %d)\n", this, ch);
2219     return call_ctype_wchar_do_widen_ch(this, ch);
2220 }
2221
2222 /* ?widen@?$ctype@_W@std@@QBEPBDPBD0PA_W@Z */
2223 /* ?widen@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W@Z */
2224 /* ?widen@?$ctype@G@std@@QBEPBDPBD0PAG@Z */
2225 /* ?widen@?$ctype@G@std@@QEBAPEBDPEBD0PEAG@Z */
2226 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen, 16)
2227 const char* __thiscall ctype_wchar_widen(const ctype_wchar *this,
2228         const char *first, const char *last, wchar_t *dest)
2229 {
2230     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2231     return call_ctype_wchar_do_widen(this, first, last, dest);
2232 }
2233
2234 /* ?_Widen_s@?$ctype@_W@std@@QBEPBDPBD0PA_WI@Z */
2235 /* ?_Widen_s@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W_K@Z */
2236 /* ?_Widen_s@?$ctype@G@std@@QBEPBDPBD0PAGI@Z */
2237 /* ?_Widen_s@?$ctype@G@std@@QEBAPEBDPEBD0PEAG_K@Z */
2238 DEFINE_THISCALL_WRAPPER(ctype_wchar__Widen_s, 20)
2239 const char* __thiscall ctype_wchar__Widen_s(const ctype_wchar *this,
2240         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2241 {
2242     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2243     return call_ctype_wchar__Do_widen_s(this, first, last, dest, size);
2244 }
2245
2246 /* ?_Getcat@?$ctype@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2247 /* ?_Getcat@?$ctype@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2248 MSVCP_size_t __cdecl ctype_wchar__Getcat(const locale_facet **facet, const locale *loc)
2249 {
2250     TRACE("(%p %p)\n", facet, loc);
2251
2252     if(facet && !*facet) {
2253         _Locinfo locinfo;
2254
2255         *facet = MSVCRT_operator_new(sizeof(ctype_wchar));
2256         if(!*facet) {
2257             ERR("Out of memory\n");
2258             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2259             return 0;
2260         }
2261
2262         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
2263         ctype_wchar_ctor_locinfo((ctype_wchar*)*facet, &locinfo, 0);
2264         _Locinfo_dtor(&locinfo);
2265     }
2266
2267     return LC_CTYPE;
2268 }
2269
2270 /* ?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2271 /* ?_Getcat@?$ctype@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2272 MSVCP_size_t __cdecl ctype_short__Getcat(const locale_facet **facet, const locale *loc)
2273 {
2274     if(facet && !*facet) {
2275         ctype_wchar__Getcat(facet, loc);
2276         (*(locale_facet**)facet)->vtable = &MSVCP_ctype_short_vtable;
2277     }
2278
2279     return LC_CTYPE;
2280 }
2281
2282 /* _Towlower */
2283 wchar_t __cdecl _Towlower(wchar_t ch, const _Ctypevec *ctype)
2284 {
2285     TRACE("(%d %p)\n", ch, ctype);
2286     return tolowerW(ch);
2287 }
2288
2289 ctype_wchar* ctype_wchar_use_facet(const locale *loc)
2290 {
2291     static ctype_wchar *obj = NULL;
2292
2293     _Lockit lock;
2294     const locale_facet *fac;
2295
2296     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2297     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_wchar_id));
2298     if(fac) {
2299         _Lockit_dtor(&lock);
2300         return (ctype_wchar*)fac;
2301     }
2302
2303     if(obj) {
2304         _Lockit_dtor(&lock);
2305         return obj;
2306     }
2307
2308     ctype_wchar__Getcat(&fac, loc);
2309     obj = (ctype_wchar*)fac;
2310     locale_facet__Incref(&obj->base.facet);
2311     locale_facet_register(&obj->base.facet);
2312     _Lockit_dtor(&lock);
2313
2314     return obj;
2315 }
2316
2317 static ctype_wchar* ctype_short_use_facet(const locale *loc)
2318 {
2319     static ctype_wchar *obj = NULL;
2320
2321     _Lockit lock;
2322     const locale_facet *fac;
2323
2324     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2325     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_short_id));
2326     if(fac) {
2327         _Lockit_dtor(&lock);
2328         return (ctype_wchar*)fac;
2329     }
2330
2331     if(obj) {
2332         _Lockit_dtor(&lock);
2333         return obj;
2334     }
2335
2336     ctype_short__Getcat(&fac, loc);
2337     obj = (ctype_wchar*)fac;
2338     locale_facet__Incref(&obj->base.facet);
2339     locale_facet_register(&obj->base.facet);
2340     _Lockit_dtor(&lock);
2341
2342     return obj;
2343 }
2344
2345 /* ?do_tolower@?$ctype@_W@std@@MBE_W_W@Z */
2346 /* ?do_tolower@?$ctype@_W@std@@MEBA_W_W@Z */
2347 /* ?do_tolower@?$ctype@G@std@@MBEGG@Z */
2348 /* ?do_tolower@?$ctype@G@std@@MEBAGG@Z */
2349 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower_ch, 8)
2350 #define call_ctype_wchar_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
2351         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2352 wchar_t __thiscall ctype_wchar_do_tolower_ch(const ctype_wchar *this, wchar_t ch)
2353 {
2354     return _Towlower(ch, &this->ctype);
2355 }
2356
2357 /* ?do_tolower@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2358 /* ?do_tolower@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2359 /* ?do_tolower@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2360 /* ?do_tolower@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2361 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower, 12)
2362 #define call_ctype_wchar_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 20, \
2363         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2364         (this, first, last))
2365 const wchar_t* __thiscall ctype_wchar_do_tolower(const ctype_wchar *this,
2366         wchar_t *first, const wchar_t *last)
2367 {
2368     TRACE("(%p %p %p)\n", this, first, last);
2369     for(; first<last; first++)
2370         *first = _Towlower(*first, &this->ctype);
2371     return last;
2372 }
2373
2374 /* ?tolower@?$ctype@_W@std@@QBE_W_W@Z */
2375 /* ?tolower@?$ctype@_W@std@@QEBA_W_W@Z */
2376 /* ?tolower@?$ctype@G@std@@QBEGG@Z */
2377 /* ?tolower@?$ctype@G@std@@QEBAGG@Z */
2378 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower_ch, 8)
2379 wchar_t __thiscall ctype_wchar_tolower_ch(const ctype_wchar *this, wchar_t ch)
2380 {
2381     TRACE("(%p %d)\n", this, ch);
2382     return call_ctype_wchar_do_tolower_ch(this, ch);
2383 }
2384
2385 /* ?tolower@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2386 /* ?tolower@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2387 /* ?tolower@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2388 /* ?tolower@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2389 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower, 12)
2390 const wchar_t* __thiscall ctype_wchar_tolower(const ctype_wchar *this,
2391         wchar_t *first, const wchar_t *last)
2392 {
2393     TRACE("(%p %p %p)\n", this, first, last);
2394     return call_ctype_wchar_do_tolower(this, first, last);
2395 }
2396
2397 /* _Towupper */
2398 wchar_t __cdecl _Towupper(wchar_t ch, const _Ctypevec *ctype)
2399 {
2400     TRACE("(%d %p)\n", ch, ctype);
2401     return toupperW(ch);
2402 }
2403
2404 /* ?do_toupper@?$ctype@_W@std@@MBE_W_W@Z */
2405 /* ?do_toupper@?$ctype@_W@std@@MEBA_W_W@Z */
2406 /* ?do_toupper@?$ctype@G@std@@MBEGG@Z */
2407 /* ?do_toupper@?$ctype@G@std@@MEBAGG@Z */
2408 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper_ch, 8)
2409 #define call_ctype_wchar_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 32, \
2410         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2411 wchar_t __thiscall ctype_wchar_do_toupper_ch(const ctype_wchar *this, wchar_t ch)
2412 {
2413     return _Towupper(ch, &this->ctype);
2414 }
2415
2416 /* ?do_toupper@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2417 /* ?do_toupper@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2418 /* ?do_toupper@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2419 /* ?do_toupper@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2420 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper, 12)
2421 #define call_ctype_wchar_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 28, \
2422         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2423         (this, first, last))
2424 const wchar_t* __thiscall ctype_wchar_do_toupper(const ctype_wchar *this,
2425         wchar_t *first, const wchar_t *last)
2426 {
2427     TRACE("(%p %p %p)\n", this, first, last);
2428     for(; first<last; first++)
2429         *first = _Towupper(*first, &this->ctype);
2430     return last;
2431 }
2432
2433 /* ?toupper@?$ctype@_W@std@@QBE_W_W@Z */
2434 /* ?toupper@?$ctype@_W@std@@QEBA_W_W@Z */
2435 /* ?toupper@?$ctype@G@std@@QBEGG@Z */
2436 /* ?toupper@?$ctype@G@std@@QEBAGG@Z */
2437 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper_ch, 8)
2438 wchar_t __thiscall ctype_wchar_toupper_ch(const ctype_wchar *this, wchar_t ch)
2439 {
2440     TRACE("(%p %d)\n", this, ch);
2441     return call_ctype_wchar_do_toupper_ch(this, ch);
2442 }
2443
2444 /* ?toupper@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2445 /* ?toupper@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2446 /* ?toupper@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2447 /* ?toupper@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2448 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper, 12)
2449 const wchar_t* __thiscall ctype_wchar_toupper(const ctype_wchar *this,
2450         wchar_t *first, const wchar_t *last)
2451 {
2452     TRACE("(%p %p %p)\n", this, first, last);
2453     return call_ctype_wchar_do_toupper(this, first, last);
2454 }
2455
2456 /* _Getwctypes */
2457 const wchar_t* __cdecl _Getwctypes(const wchar_t *first, const wchar_t *last,
2458         short *mask, const _Ctypevec *ctype)
2459 {
2460     TRACE("(%p %p %p %p)\n", first, last, mask, ctype);
2461     GetStringTypeW(CT_CTYPE1, first, last-first, (WORD*)mask);
2462     return last;
2463 }
2464
2465 /* _Getwctype */
2466 short __cdecl _Getwctype(wchar_t ch, const _Ctypevec *ctype)
2467 {
2468     short mask = 0;
2469     _Getwctypes(&ch, &ch+1, &mask, ctype);
2470     return mask;
2471 }
2472
2473 /* ?do_is@?$ctype@_W@std@@MBE_NF_W@Z */
2474 /* ?do_is@?$ctype@_W@std@@MEBA_NF_W@Z */
2475 /* ?do_is@?$ctype@G@std@@MBE_NFG@Z */
2476 /* ?do_is@?$ctype@G@std@@MEBA_NFG@Z */
2477 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is_ch, 12)
2478 #define call_ctype_wchar_do_is_ch(this, mask, ch) CALL_VTBL_FUNC(this, 8, \
2479         MSVCP_bool, (const ctype_wchar*, short, wchar_t), (this, mask, ch))
2480 MSVCP_bool __thiscall ctype_wchar_do_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2481 {
2482     TRACE("(%p %x %d)\n", this, mask, ch);
2483     return (_Getwctype(ch, &this->ctype) & mask) != 0;
2484 }
2485
2486 /* ?do_is@?$ctype@_W@std@@MBEPB_WPB_W0PAF@Z */
2487 /* ?do_is@?$ctype@_W@std@@MEBAPEB_WPEB_W0PEAF@Z */
2488 /* ?do_is@?$ctype@G@std@@MBEPBGPBG0PAF@Z */
2489 /* ?do_is@?$ctype@G@std@@MEBAPEBGPEBG0PEAF@Z */
2490 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is, 16)
2491 #define call_ctype_wchar_do_is(this, first, last, dest) CALL_VTBL_FUNC(this, 4, \
2492         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, short*), \
2493         (this, first, last, dest))
2494 const wchar_t* __thiscall ctype_wchar_do_is(const ctype_wchar *this,
2495         const wchar_t *first, const wchar_t *last, short *dest)
2496 {
2497     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2498     return _Getwctypes(first, last, dest, &this->ctype);
2499 }
2500
2501 /* ?is@?$ctype@_W@std@@QBE_NF_W@Z */
2502 /* ?is@?$ctype@_W@std@@QEBA_NF_W@Z */
2503 /* ?is@?$ctype@G@std@@QBE_NFG@Z */
2504 /* ?is@?$ctype@G@std@@QEBA_NFG@Z */
2505 DEFINE_THISCALL_WRAPPER(ctype_wchar_is_ch, 12)
2506 MSVCP_bool __thiscall ctype_wchar_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2507 {
2508     TRACE("(%p %x %d)\n", this, mask, ch);
2509     return call_ctype_wchar_do_is_ch(this, mask, ch);
2510 }
2511
2512 /* ?is@?$ctype@_W@std@@QBEPB_WPB_W0PAF@Z */
2513 /* ?is@?$ctype@_W@std@@QEBAPEB_WPEB_W0PEAF@Z */
2514 /* ?is@?$ctype@G@std@@QBEPBGPBG0PAF@Z */
2515 /* ?is@?$ctype@G@std@@QEBAPEBGPEBG0PEAF@Z */
2516 DEFINE_THISCALL_WRAPPER(ctype_wchar_is, 16)
2517 const wchar_t* __thiscall ctype_wchar_is(const ctype_wchar *this,
2518         const wchar_t *first, const wchar_t *last, short *dest)
2519 {
2520     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2521     return call_ctype_wchar_do_is(this, first, last, dest);
2522 }
2523
2524 /* ?do_scan_is@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2525 /* ?do_scan_is@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2526 /* ?do_scan_is@?$ctype@G@std@@MBEPBGFPBG0@Z */
2527 /* ?do_scan_is@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2528 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_is, 16)
2529 #define call_ctype_wchar_do_scan_is(this, mask, first, last) CALL_VTBL_FUNC(this, 12, \
2530         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2531         (this, mask, first, last))
2532 const wchar_t* __thiscall ctype_wchar_do_scan_is(const ctype_wchar *this,
2533         short mask, const wchar_t *first, const wchar_t *last)
2534 {
2535     TRACE("(%p %d %p %p)\n", this, mask, first, last);
2536     for(; first<last; first++)
2537         if(!ctype_wchar_is_ch(this, mask, *first))
2538             break;
2539     return first;
2540 }
2541
2542 /* ?scan_is@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2543 /* ?scan_is@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2544 /* ?scan_is@?$ctype@G@std@@QBEPBGFPBG0@Z */
2545 /* ?scan_is@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2546 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_is, 16)
2547 const wchar_t* __thiscall ctype_wchar_scan_is(const ctype_wchar *this,
2548         short mask, const wchar_t *first, const wchar_t *last)
2549 {
2550     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2551     return call_ctype_wchar_do_scan_is(this, mask, first, last);
2552 }
2553
2554 /* ?do_scan_not@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2555 /* ?do_scan_not@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2556 /* ?do_scan_not@?$ctype@G@std@@MBEPBGFPBG0@Z */
2557 /* ?do_scan_not@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2558 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_not, 16)
2559 #define call_ctype_wchar_do_scan_not(this, mask, first, last) CALL_VTBL_FUNC(this, 16, \
2560         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2561         (this, mask, first, last))
2562 const wchar_t* __thiscall ctype_wchar_do_scan_not(const ctype_wchar *this,
2563         short mask, const wchar_t *first, const wchar_t *last)
2564 {
2565     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2566     for(; first<last; first++)
2567         if(ctype_wchar_is_ch(this, mask, *first))
2568             break;
2569     return first;
2570 }
2571
2572 /* ?scan_not@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2573 /* ?scan_not@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2574 /* ?scan_not@?$ctype@G@std@@QBEPBGFPBG0@Z */
2575 /* ?scan_not@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2576 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_not, 16)
2577 const wchar_t* __thiscall ctype_wchar_scan_not(const ctype_wchar *this,
2578         short mask, const wchar_t *first, const wchar_t *last)
2579 {
2580     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2581     return call_ctype_wchar_do_scan_not(this, mask, first, last);
2582 }
2583
2584 /* ??_7codecvt_base@std@@6B@ */
2585 extern const vtable_ptr MSVCP_codecvt_base_vtable;
2586
2587 /* ??0codecvt_base@std@@QAE@I@Z */
2588 /* ??0codecvt_base@std@@QEAA@_K@Z */
2589 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor_refs, 8)
2590 codecvt_base* __thiscall codecvt_base_ctor_refs(codecvt_base *this, MSVCP_size_t refs)
2591 {
2592     TRACE("(%p %lu)\n", this, refs);
2593     locale_facet_ctor_refs(&this->facet, refs);
2594     this->facet.vtable = &MSVCP_codecvt_base_vtable;
2595     return this;
2596 }
2597
2598 /* ??_Fcodecvt_base@std@@QAEXXZ */
2599 /* ??_Fcodecvt_base@std@@QEAAXXZ */
2600 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor, 4)
2601 codecvt_base* __thiscall codecvt_base_ctor(codecvt_base *this)
2602 {
2603     return codecvt_base_ctor_refs(this, 0);
2604 }
2605
2606 /* ??1codecvt_base@std@@UAE@XZ */
2607 /* ??1codecvt_base@std@@UEAA@XZ */
2608 DEFINE_THISCALL_WRAPPER(codecvt_base_dtor, 4)
2609 void __thiscall codecvt_base_dtor(codecvt_base *this)
2610 {
2611     TRACE("(%p)\n", this);
2612     locale_facet_dtor(&this->facet);
2613 }
2614
2615 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_base_vector_dtor, 8)
2616 codecvt_base* __thiscall MSVCP_codecvt_base_vector_dtor(codecvt_base *this, unsigned int flags)
2617 {
2618     TRACE("(%p %x)\n", this, flags);
2619     if(flags & 2) {
2620         /* we have an array, with the number of elements stored before the first object */
2621         int i, *ptr = (int *)this-1;
2622
2623         for(i=*ptr-1; i>=0; i--)
2624             codecvt_base_dtor(this+i);
2625         MSVCRT_operator_delete(ptr);
2626     } else {
2627         codecvt_base_dtor(this);
2628         if(flags & 1)
2629             MSVCRT_operator_delete(this);
2630     }
2631
2632     return this;
2633 }
2634
2635 /* ?do_always_noconv@codecvt_base@std@@MBE_NXZ */
2636 /* ?do_always_noconv@codecvt_base@std@@MEBA_NXZ */
2637 #define call_codecvt_base_do_always_noconv(this) CALL_VTBL_FUNC(this, 4, \
2638         MSVCP_bool, (const codecvt_base*), (this))
2639 DEFINE_THISCALL_WRAPPER(codecvt_base_do_always_noconv, 4)
2640 MSVCP_bool __thiscall codecvt_base_do_always_noconv(const codecvt_base *this)
2641 {
2642     TRACE("(%p)\n", this);
2643     return TRUE;
2644 }
2645
2646 /* ?always_noconv@codecvt_base@std@@QBE_NXZ */
2647 /* ?always_noconv@codecvt_base@std@@QEBA_NXZ */
2648 DEFINE_THISCALL_WRAPPER(codecvt_base_always_noconv, 4)
2649 MSVCP_bool __thiscall codecvt_base_always_noconv(const codecvt_base *this)
2650 {
2651     TRACE("(%p)\n", this);
2652     return call_codecvt_base_do_always_noconv(this);
2653 }
2654
2655 /* ?do_max_length@codecvt_base@std@@MBEHXZ */
2656 /* ?do_max_length@codecvt_base@std@@MEBAHXZ */
2657 #define call_codecvt_base_do_max_length(this) CALL_VTBL_FUNC(this, 8, \
2658         int, (const codecvt_base*), (this))
2659 DEFINE_THISCALL_WRAPPER(codecvt_base_do_max_length, 4)
2660 int __thiscall codecvt_base_do_max_length(const codecvt_base *this)
2661 {
2662     TRACE("(%p)\n", this);
2663     return 1;
2664 }
2665
2666 /* ?max_length@codecvt_base@std@@QBEHXZ */
2667 /* ?max_length@codecvt_base@std@@QEBAHXZ */
2668 DEFINE_THISCALL_WRAPPER(codecvt_base_max_length, 4)
2669 int __thiscall codecvt_base_max_length(const codecvt_base *this)
2670 {
2671     TRACE("(%p)\n", this);
2672     return call_codecvt_base_do_max_length(this);
2673 }
2674
2675 /* ?do_encoding@codecvt_base@std@@MBEHXZ */
2676 /* ?do_encoding@codecvt_base@std@@MEBAHXZ */
2677 #define call_codecvt_base_do_encoding(this) CALL_VTBL_FUNC(this, 12, \
2678         int, (const codecvt_base*), (this))
2679 DEFINE_THISCALL_WRAPPER(codecvt_base_do_encoding, 4)
2680 int __thiscall codecvt_base_do_encoding(const codecvt_base *this)
2681 {
2682     TRACE("(%p)\n", this);
2683     return 1;
2684 }
2685
2686 /* ?encoding@codecvt_base@std@@QBEHXZ */
2687 /* ?encoding@codecvt_base@std@@QEBAHXZ */
2688 DEFINE_THISCALL_WRAPPER(codecvt_base_encoding, 4)
2689 int __thiscall codecvt_base_encoding(const codecvt_base *this)
2690 {
2691     TRACE("(%p)\n", this);
2692     return call_codecvt_base_do_encoding(this);
2693 }
2694
2695 /* ?id@?$codecvt@DDH@std@@2V0locale@2@A */
2696 locale_id codecvt_char_id = {0};
2697
2698 /* ??_7?$codecvt@DDH@std@@6B@ */
2699 extern const vtable_ptr MSVCP_codecvt_char_vtable;
2700
2701 /* ?_Init@?$codecvt@DDH@std@@IAEXABV_Locinfo@2@@Z */
2702 /* ?_Init@?$codecvt@DDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2703 DEFINE_THISCALL_WRAPPER(codecvt_char__Init, 8)
2704 void __thiscall codecvt_char__Init(codecvt_char *this, const _Locinfo *locinfo)
2705 {
2706     TRACE("(%p %p)\n", this, locinfo);
2707 }
2708
2709 /* ??0?$codecvt@DDH@std@@QAE@ABV_Locinfo@1@I@Z */
2710 /* ??0?$codecvt@DDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2711 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_locinfo, 12)
2712 codecvt_char* __thiscall codecvt_char_ctor_locinfo(codecvt_char *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2713 {
2714     TRACE("(%p %p %lu)\n", this, locinfo, refs);
2715     codecvt_base_ctor_refs(&this->base, refs);
2716     this->base.facet.vtable = &MSVCP_codecvt_char_vtable;
2717     return this;
2718 }
2719
2720 /* ??0?$codecvt@DDH@std@@QAE@I@Z */
2721 /* ??0?$codecvt@DDH@std@@QEAA@_K@Z */
2722 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_refs, 8)
2723 codecvt_char* __thiscall codecvt_char_ctor_refs(codecvt_char *this, MSVCP_size_t refs)
2724 {
2725     return codecvt_char_ctor_locinfo(this, NULL, refs);
2726 }
2727
2728 /* ??_F?$codecvt@DDH@std@@QAEXXZ */
2729 /* ??_F?$codecvt@DDH@std@@QEAAXXZ */
2730 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor, 4)
2731 codecvt_char* __thiscall codecvt_char_ctor(codecvt_char *this)
2732 {
2733     return codecvt_char_ctor_locinfo(this, NULL, 0);
2734 }
2735
2736 /* ??1?$codecvt@DDH@std@@MAE@XZ */
2737 /* ??1?$codecvt@DDH@std@@MEAA@XZ */
2738 DEFINE_THISCALL_WRAPPER(codecvt_char_dtor, 4)
2739 void __thiscall codecvt_char_dtor(codecvt_char *this)
2740 {
2741     TRACE("(%p)\n", this);
2742     codecvt_base_dtor(&this->base);
2743 }
2744
2745 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_char_vector_dtor, 8)
2746 codecvt_char* __thiscall MSVCP_codecvt_char_vector_dtor(codecvt_char *this, unsigned int flags)
2747 {
2748     TRACE("(%p %x)\n", this, flags);
2749     if(flags & 2) {
2750         /* we have an array, with the number of elements stored before the first object */
2751         int i, *ptr = (int *)this-1;
2752
2753         for(i=*ptr-1; i>=0; i--)
2754             codecvt_char_dtor(this+i);
2755         MSVCRT_operator_delete(ptr);
2756     } else {
2757         codecvt_char_dtor(this);
2758         if(flags & 1)
2759             MSVCRT_operator_delete(this);
2760     }
2761
2762     return this;
2763 }
2764
2765 /* ?_Getcat@?$codecvt@DDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2766 /* ?_Getcat@?$codecvt@DDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2767 MSVCP_size_t __cdecl codecvt_char__Getcat(const locale_facet **facet, const locale *loc)
2768 {
2769     TRACE("(%p %p)\n", facet, loc);
2770
2771     if(facet && !*facet) {
2772         *facet = MSVCRT_operator_new(sizeof(codecvt_char));
2773         if(!*facet) {
2774             ERR("Out of memory\n");
2775             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2776             return 0;
2777         }
2778         codecvt_char_ctor((codecvt_char*)*facet);
2779     }
2780
2781     return LC_CTYPE;
2782 }
2783
2784 codecvt_char* codecvt_char_use_facet(const locale *loc)
2785 {
2786     static codecvt_char *obj = NULL;
2787
2788     _Lockit lock;
2789     const locale_facet *fac;
2790
2791     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2792     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_char_id));
2793     if(fac) {
2794         _Lockit_dtor(&lock);
2795         return (codecvt_char*)fac;
2796     }
2797
2798     if(obj) {
2799         _Lockit_dtor(&lock);
2800         return obj;
2801     }
2802
2803     codecvt_char__Getcat(&fac, loc);
2804     obj = (codecvt_char*)fac;
2805     locale_facet__Incref(&obj->base.facet);
2806     locale_facet_register(&obj->base.facet);
2807     _Lockit_dtor(&lock);
2808
2809     return obj;
2810 }
2811
2812 /* ?do_in@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2813 /* ?do_in@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2814 #define call_codecvt_char_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
2815     CALL_VTBL_FUNC(this, 16, int, \
2816             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2817             (this, state, from, from_end, from_next, to, to_end, to_next))
2818 DEFINE_THISCALL_WRAPPER(codecvt_char_do_in, 32)
2819 int __thiscall codecvt_char_do_in(const codecvt_char *this, int *state,
2820         const char *from, const char *from_end, const char **from_next,
2821         char *to, char *to_end, char **to_next)
2822 {
2823     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2824             from_next, to, to_end, to_next);
2825     *from_next = from;
2826     *to_next = to;
2827     return CODECVT_noconv;
2828 }
2829
2830 /* ?in@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2831 /* ?in@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2832 DEFINE_THISCALL_WRAPPER(codecvt_char_in, 32)
2833 int __thiscall codecvt_char_in(const codecvt_char *this, int *state,
2834         const char *from, const char *from_end, const char **from_next,
2835         char *to, char *to_end, char **to_next)
2836 {
2837     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2838             from_next, to, to_end, to_next);
2839     return call_codecvt_char_do_in(this, state, from, from_end, from_next,
2840             to, to_end, to_next);
2841 }
2842
2843 /* ?do_out@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2844 /* ?do_out@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2845 #define call_codecvt_char_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
2846     CALL_VTBL_FUNC(this, 20, int, \
2847             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2848             (this, state, from, from_end, from_next, to, to_end, to_next))
2849 DEFINE_THISCALL_WRAPPER(codecvt_char_do_out, 32)
2850 int __thiscall codecvt_char_do_out(const codecvt_char *this, int *state,
2851         const char *from, const char *from_end, const char **from_next,
2852         char *to, char *to_end, char **to_next)
2853 {
2854     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2855             from_end, from_next, to, to_end, to_next);
2856     *from_next = from;
2857     *to_next = to;
2858     return CODECVT_noconv;
2859 }
2860
2861 /* ?out@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2862 /* ?out@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2863 DEFINE_THISCALL_WRAPPER(codecvt_char_out, 32)
2864 int __thiscall codecvt_char_out(const codecvt_char *this, int *state,
2865         const char *from, const char *from_end, const char **from_next,
2866         char *to, char *to_end, char **to_next)
2867 {
2868     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2869             from_next, to, to_end, to_next);
2870     return call_codecvt_char_do_out(this, state, from, from_end, from_next,
2871             to, to_end, to_next);
2872 }
2873
2874 /* ?do_unshift@?$codecvt@DDH@std@@MBEHAAHPAD1AAPAD@Z */
2875 /* ?do_unshift@?$codecvt@DDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
2876 #define call_codecvt_char_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
2877         int, (const codecvt_char*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
2878 DEFINE_THISCALL_WRAPPER(codecvt_char_do_unshift, 20)
2879 int __thiscall codecvt_char_do_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     *to_next = to;
2884     return CODECVT_noconv;
2885 }
2886
2887 /* ?unshift@?$codecvt@DDH@std@@QBEHAAHPAD1AAPAD@Z */
2888 /* ?unshift@?$codecvt@DDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
2889 DEFINE_THISCALL_WRAPPER(codecvt_char_unshift, 20)
2890 int __thiscall codecvt_char_unshift(const codecvt_char *this,
2891         int *state, char *to, char *to_end, char **to_next)
2892 {
2893     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2894     return call_codecvt_char_do_unshift(this, state, to, to_end, to_next);
2895 }
2896
2897 /* ?do_length@?$codecvt@DDH@std@@MBEHABHPBD1I@Z */
2898 /* ?do_length@?$codecvt@DDH@std@@MEBAHAEBHPEBD1_K@Z */
2899 #define call_codecvt_char_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
2900         int, (const codecvt_char*, const int*, const char*, const char*, MSVCP_size_t), \
2901         (this, state, from, from_end, max))
2902 DEFINE_THISCALL_WRAPPER(codecvt_char_do_length, 20)
2903 int __thiscall codecvt_char_do_length(const codecvt_char *this, const int *state,
2904         const char *from, const char *from_end, MSVCP_size_t max)
2905 {
2906     TRACE("(%p %p %p %p %lu)\n", this, state, from, from_end, max);
2907     return (from_end-from > max ? max : from_end-from);
2908 }
2909
2910 /* ?length@?$codecvt@DDH@std@@QBEHABHPBD1I@Z */
2911 /* ?length@?$codecvt@DDH@std@@QEBAHAEBHPEBD1_K@Z */
2912 DEFINE_THISCALL_WRAPPER(codecvt_char_length, 20)
2913 int __thiscall codecvt_char_length(const codecvt_char *this, const int *state,
2914         const char *from, const char *from_end, MSVCP_size_t max)
2915 {
2916     TRACE("(%p %p %p %p %lu)\n", this, state, from, from_end, max);
2917     return call_codecvt_char_do_length(this, state, from, from_end, max);
2918 }
2919
2920 /* ?id@?$codecvt@_WDH@std@@2V0locale@2@A */
2921 locale_id codecvt_wchar_id = {0};
2922 /* ?id@?$codecvt@GDH@std@@2V0locale@2@A */
2923 locale_id codecvt_short_id = {0};
2924
2925 /* ??_7?$codecvt@_WDH@std@@6B@ */
2926 extern const vtable_ptr MSVCP_codecvt_wchar_vtable;
2927 /* ??_7?$codecvt@GDH@std@@6B@ */
2928 extern const vtable_ptr MSVCP_codecvt_short_vtable;
2929
2930 /* ?_Init@?$codecvt@GDH@std@@IAEXABV_Locinfo@2@@Z */
2931 /* ?_Init@?$codecvt@GDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2932 /* ?_Init@?$codecvt@_WDH@std@@IAEXABV_Locinfo@2@@Z */
2933 /* ?_Init@?$codecvt@_WDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2934 DEFINE_THISCALL_WRAPPER(codecvt_wchar__Init, 8)
2935 void __thiscall codecvt_wchar__Init(codecvt_wchar *this, const _Locinfo *locinfo)
2936 {
2937     TRACE("(%p %p)\n", this, locinfo);
2938     _Locinfo__Getcvt(locinfo, &this->cvt);
2939 }
2940
2941 /* ??0?$codecvt@_WDH@std@@QAE@ABV_Locinfo@1@I@Z */
2942 /* ??0?$codecvt@_WDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2943 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor_locinfo, 12)
2944 codecvt_wchar* __thiscall codecvt_wchar_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2945 {
2946     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2947
2948     codecvt_base_ctor_refs(&this->base, refs);
2949     this->base.facet.vtable = &MSVCP_codecvt_wchar_vtable;
2950
2951     codecvt_wchar__Init(this, locinfo);
2952     return this;
2953 }
2954
2955 /* ??0?$codecvt@GDH@std@@QAE@ABV_Locinfo@1@I@Z */
2956 /* ??0?$codecvt@GDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2957 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_locinfo, 12)
2958 codecvt_wchar* __thiscall codecvt_short_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2959 {
2960     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2961
2962     codecvt_wchar_ctor_locinfo(this, locinfo, refs);
2963     this->base.facet.vtable = &MSVCP_codecvt_short_vtable;
2964     return this;
2965 }
2966
2967 /* ??0?$codecvt@_WDH@std@@QAE@I@Z */
2968 /* ??0?$codecvt@_WDH@std@@QEAA@_K@Z */
2969 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor_refs, 8)
2970 codecvt_wchar* __thiscall codecvt_wchar_ctor_refs(codecvt_wchar *this, MSVCP_size_t refs)
2971 {
2972     _Locinfo locinfo;
2973
2974     TRACE("(%p %ld)\n", this, refs);
2975
2976     _Locinfo_ctor(&locinfo);
2977     codecvt_wchar_ctor_locinfo(this, &locinfo, refs);
2978     _Locinfo_dtor(&locinfo);
2979     return this;
2980 }
2981
2982 /* ??0?$codecvt@GDH@std@@QAE@I@Z */
2983 /* ??0?$codecvt@GDH@std@@QEAA@_K@Z */
2984 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_refs, 8)
2985 codecvt_wchar* __thiscall codecvt_short_ctor_refs(codecvt_wchar *this, MSVCP_size_t refs)
2986 {
2987     _Locinfo locinfo;
2988
2989     TRACE("(%p %ld)\n", this, refs);
2990
2991     _Locinfo_ctor(&locinfo);
2992     codecvt_short_ctor_locinfo(this, &locinfo, refs);
2993     _Locinfo_dtor(&locinfo);
2994     return this;
2995 }
2996
2997 /* ??0?$codecvt@GDH@std@@IAE@PBDI@Z */
2998 /* ??0?$codecvt@GDH@std@@IEAA@PEBD_K@Z */
2999 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_name, 12)
3000 codecvt_wchar* __thiscall codecvt_short_ctor_name(codecvt_wchar *this, const char *name, MSVCP_size_t refs)
3001 {
3002     _Locinfo locinfo;
3003
3004     TRACE("(%p %s %ld)\n", this, name, refs);
3005
3006     _Locinfo_ctor_cstr(&locinfo, name);
3007     codecvt_short_ctor_locinfo(this, &locinfo, refs);
3008     _Locinfo_dtor(&locinfo);
3009     return this;
3010 }
3011
3012 /* ??_F?$codecvt@_WDH@std@@QAEXXZ */
3013 /* ??_F?$codecvt@_WDH@std@@QEAAXXZ */
3014 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor, 4)
3015 codecvt_wchar* __thiscall codecvt_wchar_ctor(codecvt_wchar *this)
3016 {
3017     return codecvt_wchar_ctor_refs(this, 0);
3018 }
3019
3020 /* ??_F?$codecvt@GDH@std@@QAEXXZ */
3021 /* ??_F?$codecvt@GDH@std@@QEAAXXZ */
3022 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor, 4)
3023 codecvt_wchar* __thiscall codecvt_short_ctor(codecvt_wchar *this)
3024 {
3025     return codecvt_short_ctor_refs(this, 0);
3026 }
3027
3028 /* ??1?$codecvt@GDH@std@@MAE@XZ */
3029 /* ??1?$codecvt@GDH@std@@MEAA@XZ */
3030 /* ??1?$codecvt@_WDH@std@@MAE@XZ */
3031 /* ??1?$codecvt@_WDH@std@@MEAA@XZ */
3032 DEFINE_THISCALL_WRAPPER(codecvt_wchar_dtor, 4)
3033 void __thiscall codecvt_wchar_dtor(codecvt_wchar *this)
3034 {
3035     TRACE("(%p)\n", this);
3036     codecvt_base_dtor(&this->base);
3037 }
3038
3039 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_wchar_vector_dtor, 8)
3040 codecvt_wchar* __thiscall MSVCP_codecvt_wchar_vector_dtor(codecvt_wchar *this, unsigned int flags)
3041 {
3042     TRACE("(%p %x)\n", this, flags);
3043     if(flags & 2) {
3044         /* we have an array, with the number of elements stored before the first object */
3045         int i, *ptr = (int *)this-1;
3046
3047         for(i=*ptr-1; i>=0; i--)
3048             codecvt_wchar_dtor(this+i);
3049         MSVCRT_operator_delete(ptr);
3050     } else {
3051         codecvt_wchar_dtor(this);
3052         if(flags & 1)
3053             MSVCRT_operator_delete(this);
3054     }
3055
3056     return this;
3057 }
3058
3059 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_short_vector_dtor, 8)
3060 codecvt_wchar* __thiscall MSVCP_codecvt_short_vector_dtor(codecvt_wchar *this, unsigned int flags)
3061 {
3062     return MSVCP_codecvt_wchar_vector_dtor(this, flags);
3063 }
3064
3065 /* ?_Getcat@?$codecvt@_WDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3066 /* ?_Getcat@?$codecvt@_WDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3067 unsigned int __cdecl codecvt_wchar__Getcat(const locale_facet **facet, const locale *loc)
3068 {
3069     TRACE("(%p %p)\n", facet, loc);
3070
3071     if(facet && !*facet) {
3072         _Locinfo locinfo;
3073
3074         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
3075         if(!*facet) {
3076             ERR("Out of memory\n");
3077             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3078             return 0;
3079         }
3080
3081         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
3082         codecvt_wchar_ctor_locinfo((codecvt_wchar*)*facet, &locinfo, 0);
3083         _Locinfo_dtor(&locinfo);
3084     }
3085
3086     return LC_CTYPE;
3087 }
3088
3089 static codecvt_wchar* codecvt_wchar_use_facet(const locale *loc)
3090 {
3091     static codecvt_wchar *obj = NULL;
3092
3093     _Lockit lock;
3094     const locale_facet *fac;
3095
3096     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3097     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_wchar_id));
3098     if(fac) {
3099         _Lockit_dtor(&lock);
3100         return (codecvt_wchar*)fac;
3101     }
3102
3103     if(obj) {
3104         _Lockit_dtor(&lock);
3105         return obj;
3106     }
3107
3108     codecvt_wchar__Getcat(&fac, loc);
3109     obj = (codecvt_wchar*)fac;
3110     locale_facet__Incref(&obj->base.facet);
3111     locale_facet_register(&obj->base.facet);
3112     _Lockit_dtor(&lock);
3113
3114     return obj;
3115 }
3116
3117 /* ?_Getcat@?$codecvt@GDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3118 /* ?_Getcat@?$codecvt@GDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3119 unsigned int __cdecl codecvt_short__Getcat(const locale_facet **facet, const locale *loc)
3120 {
3121     TRACE("(%p %p)\n", facet, loc);
3122
3123     if(facet && !*facet) {
3124         _Locinfo locinfo;
3125
3126         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
3127         if(!*facet) {
3128             ERR("Out of memory\n");
3129             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3130             return 0;
3131         }
3132
3133         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
3134         codecvt_short_ctor((codecvt_wchar*)*facet);
3135         _Locinfo_dtor(&locinfo);
3136     }
3137
3138     return LC_CTYPE;
3139 }
3140
3141 static codecvt_wchar* codecvt_short_use_facet(const locale *loc)
3142 {
3143     static codecvt_wchar *obj = NULL;
3144
3145     _Lockit lock;
3146     const locale_facet *fac;
3147
3148     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3149     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_short_id));
3150     if(fac) {
3151         _Lockit_dtor(&lock);
3152         return (codecvt_wchar*)fac;
3153     }
3154
3155     if(obj) {
3156         _Lockit_dtor(&lock);
3157         return obj;
3158     }
3159
3160     codecvt_short__Getcat(&fac, loc);
3161     obj = (codecvt_wchar*)fac;
3162     locale_facet__Incref(&obj->base.facet);
3163     locale_facet_register(&obj->base.facet);
3164     _Lockit_dtor(&lock);
3165
3166     return obj;
3167 }
3168
3169 /* ?_Id_func@?$codecvt@_WDH@std@@SAAAVid@locale@2@XZ */
3170 /* ?_Id_func@?$codecvt@_WDH@std@@SAAEAVid@locale@2@XZ */
3171 locale_id* __cdecl codecvt_wchar__Id_func(void)
3172 {
3173     TRACE("()\n");
3174     return &codecvt_wchar_id;
3175 }
3176
3177 /* ?_Id_func@?$codecvt@GDH@std@@SAAAVid@locale@2@XZ */
3178 /* ?_Id_func@?$codecvt@GDH@std@@SAAEAVid@locale@2@XZ */
3179 locale_id* __cdecl codecvt_short__Id_func(void)
3180 {
3181     TRACE("()\n");
3182     return &codecvt_short_id;
3183 }
3184
3185 /* ?do_always_noconv@?$codecvt@GDH@std@@MBE_NXZ */
3186 /* ?do_always_noconv@?$codecvt@GDH@std@@MEBA_NXZ */
3187 /* ?do_always_noconv@?$codecvt@_WDH@std@@MBE_NXZ */
3188 /* ?do_always_noconv@?$codecvt@_WDH@std@@MEBA_NXZ */
3189 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_always_noconv, 4)
3190 MSVCP_bool __thiscall codecvt_wchar_do_always_noconv(const codecvt_wchar *this)
3191 {
3192     TRACE("(%p)\n", this);
3193     return FALSE;
3194 }
3195
3196 /* ?do_max_length@?$codecvt@GDH@std@@MBEHXZ */
3197 /* ?do_max_length@?$codecvt@GDH@std@@MEBAHXZ */
3198 /* ?do_max_length@?$codecvt@_WDH@std@@MBEHXZ */
3199 /* ?do_max_length@?$codecvt@_WDH@std@@MEBAHXZ */
3200 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_max_length, 4)
3201 int __thiscall codecvt_wchar_do_max_length(const codecvt_wchar *this)
3202 {
3203     TRACE("(%p)\n", this);
3204     return MB_LEN_MAX;
3205 }
3206
3207 /* ?do_in@?$codecvt@GDH@std@@MBEHAAHPBD1AAPBDPAG3AAPAG@Z */
3208 /* ?do_in@?$codecvt@GDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
3209 /* ?do_in@?$codecvt@_WDH@std@@MBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
3210 /* ?do_in@?$codecvt@_WDH@std@@MEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
3211 #define call_codecvt_wchar_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
3212     CALL_VTBL_FUNC(this, 16, int, \
3213             (const codecvt_wchar*, int*, const char*, const char*, const char**, wchar_t*, wchar_t*, wchar_t**), \
3214             (this, state, from, from_end, from_next, to, to_end, to_next))
3215 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_in, 32)
3216 int __thiscall codecvt_wchar_do_in(const codecvt_wchar *this, int *state,
3217         const char *from, const char *from_end, const char **from_next,
3218         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
3219 {
3220     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3221             from_end, from_next, to, to_end, to_next);
3222
3223     *from_next = from;
3224     *to_next = to;
3225
3226     while(*from_next!=from_end && *to_next!=to_end) {
3227         switch(_Mbrtowc(*to_next, *from_next, from_end-*from_next, state, &this->cvt)) {
3228         case -2:
3229             *from_next = from_end;
3230             return CODECVT_partial;
3231         case -1:
3232             return CODECVT_error;
3233         case 2:
3234             (*from_next)++;
3235             /* fall through */
3236         case 0:
3237         case 1:
3238             (*from_next)++;
3239             (*to_next)++;
3240         }
3241     }
3242
3243     return CODECVT_ok;
3244 }
3245
3246 /* ?in@?$codecvt@GDH@std@@QBEHAAHPBD1AAPBDPAG3AAPAG@Z */
3247 /* ?in@?$codecvt@GDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
3248 /* ?in@?$codecvt@_WDH@std@@QBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
3249 /* ?in@?$codecvt@_WDH@std@@QEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
3250 DEFINE_THISCALL_WRAPPER(codecvt_wchar_in, 32)
3251 int __thiscall codecvt_wchar_in(const codecvt_wchar *this, int *state,
3252         const char *from, const char *from_end, const char **from_next,
3253         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
3254 {
3255     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3256             from_end, from_next, to, to_end, to_next);
3257     return call_codecvt_wchar_do_in(this, state, from,
3258             from_end, from_next, to, to_end, to_next);
3259 }
3260
3261 /* ?do_out@?$codecvt@GDH@std@@MBEHAAHPBG1AAPBGPAD3AAPAD@Z */
3262 /* ?do_out@?$codecvt@GDH@std@@MEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
3263 /* ?do_out@?$codecvt@_WDH@std@@MBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
3264 /* ?do_out@?$codecvt@_WDH@std@@MEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
3265 #define call_codecvt_wchar_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
3266     CALL_VTBL_FUNC(this, 20, int, \
3267             (const codecvt_wchar*, int*, const wchar_t*, const wchar_t*, const wchar_t**, char*, char*, char**), \
3268             (this, state, from, from_end, from_next, to, to_end, to_next))
3269 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_out, 32)
3270 int __thiscall codecvt_wchar_do_out(const codecvt_wchar *this, int *state,
3271         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
3272         char *to, char *to_end, char **to_next)
3273 {
3274     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3275             from_end, from_next, to, to_end, to_next);
3276
3277     *from_next = from;
3278     *to_next = to;
3279
3280     while(*from_next!=from_end && *to_next!=to_end) {
3281         int old_state = *state, size;
3282         char buf[MB_LEN_MAX];
3283
3284         switch((size = _Wcrtomb(buf, **from_next, state, &this->cvt))) {
3285         case -1:
3286             return CODECVT_error;
3287         default:
3288             if(size > from_end-*from_next) {
3289                 *state = old_state;
3290                 return CODECVT_partial;
3291             }
3292
3293             (*from_next)++;
3294             (*to_next) += size;
3295         }
3296     }
3297
3298     return CODECVT_ok;
3299 }
3300
3301 /* ?out@?$codecvt@GDH@std@@QBEHAAHPBG1AAPBGPAD3AAPAD@Z */
3302 /* ?out@?$codecvt@GDH@std@@QEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
3303 /* ?out@?$codecvt@_WDH@std@@QBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
3304 /* ?out@?$codecvt@_WDH@std@@QEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
3305 DEFINE_THISCALL_WRAPPER(codecvt_wchar_out, 32)
3306 int __thiscall codecvt_wchar_out(const codecvt_wchar *this, int *state,
3307         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
3308         char *to, char *to_end, char **to_next)
3309 {
3310     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3311             from_end, from_next, to, to_end, to_next);
3312     return call_codecvt_wchar_do_out(this, state, from,
3313             from_end, from_next, to, to_end, to_next);
3314 }
3315
3316 /* ?do_unshift@?$codecvt@GDH@std@@MBEHAAHPAD1AAPAD@Z */
3317 /* ?do_unshift@?$codecvt@GDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
3318 /* ?do_unshift@?$codecvt@_WDH@std@@MBEHAAHPAD1AAPAD@Z */
3319 /* ?do_unshift@?$codecvt@_WDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
3320 #define call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
3321         int, (const codecvt_wchar*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
3322 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_unshift, 20)
3323 int __thiscall codecvt_wchar_do_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     if(*state)
3328         WARN("unexpected state: %x\n", *state);
3329
3330     *to_next = to;
3331     return CODECVT_ok;
3332 }
3333
3334 /* ?unshift@?$codecvt@GDH@std@@QBEHAAHPAD1AAPAD@Z */
3335 /* ?unshift@?$codecvt@GDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
3336 /* ?unshift@?$codecvt@_WDH@std@@QBEHAAHPAD1AAPAD@Z */
3337 /* ?unshift@?$codecvt@_WDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
3338 DEFINE_THISCALL_WRAPPER(codecvt_wchar_unshift, 20)
3339 int __thiscall codecvt_wchar_unshift(const codecvt_wchar *this,
3340         int *state, char *to, char *to_end, char **to_next)
3341 {
3342     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
3343     return call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next);
3344 }
3345
3346 /* ?do_length@?$codecvt@GDH@std@@MBEHABHPBD1I@Z */
3347 /* ?do_length@?$codecvt@GDH@std@@MEBAHAEBHPEBD1_K@Z */
3348 /* ?do_length@?$codecvt@_WDH@std@@MBEHABHPBD1I@Z */
3349 /* ?do_length@?$codecvt@_WDH@std@@MEBAHAEBHPEBD1_K@Z */
3350 #define call_codecvt_wchar_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
3351         int, (const codecvt_wchar*, const int*, const char*, const char*, MSVCP_size_t), \
3352         (this, state, from, from_end, max))
3353 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_length, 20)
3354 int __thiscall codecvt_wchar_do_length(const codecvt_wchar *this, const int *state,
3355         const char *from, const char *from_end, MSVCP_size_t max)
3356 {
3357     int tmp_state = *state, ret=0;
3358
3359     TRACE("(%p %p %p %p %ld)\n", this, state, from, from_end, max);
3360
3361     while(ret<max && from!=from_end) {
3362         switch(_Mbrtowc(NULL, from, from_end-from, &tmp_state, &this->cvt)) {
3363         case -2:
3364         case -1:
3365             return ret;
3366         case 2:
3367             from++;
3368             /* fall through */
3369         case 0:
3370         case 1:
3371             from++;
3372             ret++;
3373         }
3374     }
3375
3376     return ret;
3377 }
3378
3379 /* ?length@?$codecvt@GDH@std@@QBEHABHPBD1I@Z */
3380 /* ?length@?$codecvt@GDH@std@@QEBAHAEBHPEBD1_K@Z */
3381 /* ?length@?$codecvt@_WDH@std@@QBEHABHPBD1I@Z */
3382 /* ?length@?$codecvt@_WDH@std@@QEBAHAEBHPEBD1_K@Z */
3383 DEFINE_THISCALL_WRAPPER(codecvt_wchar_length, 20)
3384 int __thiscall codecvt_wchar_length(const codecvt_wchar *this, const int *state,
3385         const char *from, const char *from_end, MSVCP_size_t max)
3386 {
3387     TRACE("(%p %p %p %p %ld)\n", this, state, from, from_end, max);
3388     return call_codecvt_wchar_do_length(this, state, from, from_end, max);
3389 }
3390
3391 /* ?id@?$numpunct@D@std@@2V0locale@2@A */
3392 locale_id numpunct_char_id = {0};
3393
3394 /* ??_7?$numpunct@D@std@@6B@ */
3395 extern const vtable_ptr MSVCP_numpunct_char_vtable;
3396
3397 /* ?_Init@?$numpunct@D@std@@IAEXABV_Locinfo@2@_N@Z */
3398 /* ?_Init@?$numpunct@D@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3399 DEFINE_THISCALL_WRAPPER(numpunct_char__Init, 12)
3400 void __thiscall numpunct_char__Init(numpunct_char *this, const _Locinfo *locinfo, MSVCP_bool isdef)
3401 {
3402     int len;
3403
3404     TRACE("(%p %p %d)\n", this, locinfo, isdef);
3405
3406     len = strlen(_Locinfo__Getfalse(locinfo))+1;
3407     this->false_name = MSVCRT_operator_new(len);
3408     if(this->false_name)
3409         memcpy((char*)this->false_name, _Locinfo__Getfalse(locinfo), len);
3410
3411     len = strlen(_Locinfo__Gettrue(locinfo))+1;
3412     this->true_name = MSVCRT_operator_new(len);
3413     if(this->true_name)
3414         memcpy((char*)this->true_name, _Locinfo__Gettrue(locinfo), len);
3415
3416     if(isdef) {
3417         this->grouping = MSVCRT_operator_new(1);
3418         if(this->grouping)
3419             *(char*)this->grouping = 0;
3420
3421         this->dp = '.';
3422         this->sep = ',';
3423     } else {
3424         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3425
3426         len = strlen(lc->grouping)+1;
3427         this->grouping = MSVCRT_operator_new(len);
3428         if(this->grouping)
3429             memcpy((char*)this->grouping, lc->grouping, len);
3430
3431         this->dp = lc->decimal_point[0];
3432         this->sep = lc->thousands_sep[0];
3433     }
3434
3435     if(!this->false_name || !this->true_name || !this->grouping) {
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         ERR("Out of memory\n");
3441         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3442     }
3443 }
3444
3445 /* ?_Tidy@?$numpunct@D@std@@AAEXXZ */
3446 /* ?_Tidy@?$numpunct@D@std@@AEAAXXZ */
3447 DEFINE_THISCALL_WRAPPER(numpunct_char__Tidy, 4)
3448 void __thiscall numpunct_char__Tidy(numpunct_char *this)
3449 {
3450     TRACE("(%p)\n", this);
3451
3452     MSVCRT_operator_delete((char*)this->grouping);
3453     MSVCRT_operator_delete((char*)this->false_name);
3454     MSVCRT_operator_delete((char*)this->true_name);
3455 }
3456
3457 /* ??0?$numpunct@D@std@@QAE@ABV_Locinfo@1@I_N@Z */
3458 /* ??0?$numpunct@D@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3459 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_locinfo, 16)
3460 numpunct_char* __thiscall numpunct_char_ctor_locinfo(numpunct_char *this,
3461         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3462 {
3463     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3464     locale_facet_ctor_refs(&this->facet, refs);
3465     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3466     numpunct_char__Init(this, locinfo, usedef);
3467     return this;
3468 }
3469
3470 /* ??0?$numpunct@D@std@@IAE@PBDI_N@Z */
3471 /* ??0?$numpunct@D@std@@IEAA@PEBD_K_N@Z */
3472 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_name, 16)
3473 numpunct_char* __thiscall numpunct_char_ctor_name(numpunct_char *this,
3474         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3475 {
3476     _Locinfo locinfo;
3477
3478     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3479     locale_facet_ctor_refs(&this->facet, refs);
3480     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3481
3482     _Locinfo_ctor_cstr(&locinfo, name);
3483     numpunct_char__Init(this, &locinfo, usedef);
3484     _Locinfo_dtor(&locinfo);
3485     return this;
3486 }
3487
3488 /* ??0?$numpunct@D@std@@QAE@I@Z */
3489 /* ??0?$numpunct@D@std@@QEAA@_K@Z */
3490 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_refs, 8)
3491 numpunct_char* __thiscall numpunct_char_ctor_refs(numpunct_char *this, MSVCP_size_t refs)
3492 {
3493     TRACE("(%p %lu)\n", this, refs);
3494     return numpunct_char_ctor_name(this, "C", refs, FALSE);
3495 }
3496
3497 /* ??_F?$numpunct@D@std@@QAEXXZ */
3498 /* ??_F?$numpunct@D@std@@QEAAXXZ */
3499 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor, 4)
3500 numpunct_char* __thiscall numpunct_char_ctor(numpunct_char *this)
3501 {
3502     return numpunct_char_ctor_refs(this, 0);
3503 }
3504
3505 /* ??1?$numpunct@D@std@@MAE@XZ */
3506 /* ??1?$numpunct@D@std@@MEAA@XZ */
3507 DEFINE_THISCALL_WRAPPER(numpunct_char_dtor, 4)
3508 void __thiscall numpunct_char_dtor(numpunct_char *this)
3509 {
3510     TRACE("(%p)\n", this);
3511     numpunct_char__Tidy(this);
3512 }
3513
3514 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_char_vector_dtor, 8)
3515 numpunct_char* __thiscall MSVCP_numpunct_char_vector_dtor(numpunct_char *this, unsigned int flags)
3516 {
3517     TRACE("(%p %x)\n", this, flags);
3518     if(flags & 2) {
3519         /* we have an array, with the number of elements stored before the first object */
3520         int i, *ptr = (int *)this-1;
3521
3522         for(i=*ptr-1; i>=0; i--)
3523             numpunct_char_dtor(this+i);
3524         MSVCRT_operator_delete(ptr);
3525     } else {
3526         numpunct_char_dtor(this);
3527         if(flags & 1)
3528             MSVCRT_operator_delete(this);
3529     }
3530
3531     return this;
3532 }
3533
3534 /* ?_Getcat@?$numpunct@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3535 /* ?_Getcat@?$numpunct@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3536 MSVCP_size_t __cdecl numpunct_char__Getcat(const locale_facet **facet, const locale *loc)
3537 {
3538     TRACE("(%p %p)\n", facet, loc);
3539
3540     if(facet && !*facet) {
3541         *facet = MSVCRT_operator_new(sizeof(numpunct_char));
3542         if(!*facet) {
3543             ERR("Out of memory\n");
3544             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3545             return 0;
3546         }
3547         numpunct_char_ctor_name((numpunct_char*)*facet,
3548                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3549     }
3550
3551     return LC_NUMERIC;
3552 }
3553
3554 static numpunct_char* numpunct_char_use_facet(const locale *loc)
3555 {
3556     static numpunct_char *obj = NULL;
3557
3558     _Lockit lock;
3559     const locale_facet *fac;
3560
3561     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3562     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_char_id));
3563     if(fac) {
3564         _Lockit_dtor(&lock);
3565         return (numpunct_char*)fac;
3566     }
3567
3568     if(obj) {
3569         _Lockit_dtor(&lock);
3570         return obj;
3571     }
3572
3573     numpunct_char__Getcat(&fac, loc);
3574     obj = (numpunct_char*)fac;
3575     locale_facet__Incref(&obj->facet);
3576     locale_facet_register(&obj->facet);
3577     _Lockit_dtor(&lock);
3578
3579     return obj;
3580 }
3581
3582 /* ?do_decimal_point@?$numpunct@D@std@@MBEDXZ */
3583 /* ?do_decimal_point@?$numpunct@D@std@@MEBADXZ */
3584 DEFINE_THISCALL_WRAPPER(numpunct_char_do_decimal_point, 4)
3585 #define call_numpunct_char_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3586         char, (const numpunct_char *this), (this))
3587 char __thiscall numpunct_char_do_decimal_point(const numpunct_char *this)
3588 {
3589     TRACE("(%p)\n", this);
3590     return this->dp;
3591 }
3592
3593 /* ?decimal_point@?$numpunct@D@std@@QBEDXZ */
3594 /* ?decimal_point@?$numpunct@D@std@@QEBADXZ */
3595 DEFINE_THISCALL_WRAPPER(numpunct_char_decimal_point, 4)
3596 char __thiscall numpunct_char_decimal_point(const numpunct_char *this)
3597 {
3598     TRACE("(%p)\n", this);
3599     return call_numpunct_char_do_decimal_point(this);
3600 }
3601
3602 /* ?do_thousands_sep@?$numpunct@D@std@@MBEDXZ */
3603 /* ?do_thousands_sep@?$numpunct@D@std@@MEBADXZ */
3604 DEFINE_THISCALL_WRAPPER(numpunct_char_do_thousands_sep, 4)
3605 #define call_numpunct_char_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
3606         char, (const numpunct_char*), (this))
3607 char __thiscall numpunct_char_do_thousands_sep(const numpunct_char *this)
3608 {
3609     TRACE("(%p)\n", this);
3610     return this->sep;
3611 }
3612
3613 /* ?thousands_sep@?$numpunct@D@std@@QBEDXZ */
3614 /* ?thousands_sep@?$numpunct@D@std@@QEBADXZ */
3615 DEFINE_THISCALL_WRAPPER(numpunct_char_thousands_sep, 4)
3616 char __thiscall numpunct_char_thousands_sep(const numpunct_char *this)
3617 {
3618     TRACE("(%p)\n", this);
3619     return call_numpunct_char_do_thousands_sep(this);
3620 }
3621
3622 /* ?do_grouping@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3623 /* ?do_grouping@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3624 DEFINE_THISCALL_WRAPPER(numpunct_char_do_grouping, 8)
3625 #define call_numpunct_char_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
3626         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3627 basic_string_char* __thiscall numpunct_char_do_grouping(
3628         const numpunct_char *this, basic_string_char *ret)
3629 {
3630     TRACE("(%p)\n", this);
3631     return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping);
3632 }
3633
3634 /* ?grouping@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3635 /* ?grouping@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3636 DEFINE_THISCALL_WRAPPER(numpunct_char_grouping, 8)
3637 basic_string_char* __thiscall numpunct_char_grouping(const numpunct_char *this, basic_string_char *ret)
3638 {
3639     TRACE("(%p)\n", this);
3640     return call_numpunct_char_do_grouping(this, ret);
3641 }
3642
3643 /* ?do_falsename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3644 /* ?do_falsename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3645 DEFINE_THISCALL_WRAPPER(numpunct_char_do_falsename, 8)
3646 #define call_numpunct_char_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
3647         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3648 basic_string_char* __thiscall numpunct_char_do_falsename(
3649         const numpunct_char *this, basic_string_char *ret)
3650 {
3651     TRACE("(%p)\n", this);
3652     return MSVCP_basic_string_char_ctor_cstr(ret, this->false_name);
3653 }
3654
3655 /* ?falsename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3656 /* ?falsename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3657 DEFINE_THISCALL_WRAPPER(numpunct_char_falsename, 8)
3658 basic_string_char* __thiscall numpunct_char_falsename(const numpunct_char *this, basic_string_char *ret)
3659 {
3660     TRACE("(%p)\n", this);
3661     return call_numpunct_char_do_falsename(this, ret);
3662 }
3663
3664 /* ?do_truename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3665 /* ?do_truename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3666 DEFINE_THISCALL_WRAPPER(numpunct_char_do_truename, 8)
3667 #define call_numpunct_char_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
3668         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3669 basic_string_char* __thiscall numpunct_char_do_truename(
3670         const numpunct_char *this, basic_string_char *ret)
3671 {
3672     TRACE("(%p)\n", this);
3673     return MSVCP_basic_string_char_ctor_cstr(ret, this->true_name);
3674 }
3675
3676 /* ?truename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3677 /* ?truename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3678 DEFINE_THISCALL_WRAPPER(numpunct_char_truename, 8)
3679 basic_string_char* __thiscall numpunct_char_truename(const numpunct_char *this, basic_string_char *ret)
3680 {
3681     TRACE("(%p)\n", this);
3682     return call_numpunct_char_do_truename(this, ret);
3683 }
3684
3685 /* ?id@?$numpunct@_W@std@@2V0locale@2@A */
3686 locale_id numpunct_wchar_id = {0};
3687 /* ?id@?$numpunct@G@std@@2V0locale@2@A */
3688 locale_id numpunct_short_id = {0};
3689
3690 /* ??_7?$numpunct@_W@std@@6B@ */
3691 extern const vtable_ptr MSVCP_numpunct_wchar_vtable;
3692 /* ??_7?$numpunct@G@std@@6B@ */
3693 extern const vtable_ptr MSVCP_numpunct_short_vtable;
3694
3695 /* ?_Init@?$numpunct@_W@std@@IAEXABV_Locinfo@2@_N@Z */
3696 /* ?_Init@?$numpunct@_W@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3697 /* ?_Init@?$numpunct@G@std@@IAEXABV_Locinfo@2@_N@Z */
3698 /* ?_Init@?$numpunct@G@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3699 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Init, 12)
3700 void __thiscall numpunct_wchar__Init(numpunct_wchar *this,
3701         const _Locinfo *locinfo, MSVCP_bool isdef)
3702 {
3703     const char *to_convert;
3704     _Cvtvec cvt;
3705     int len;
3706
3707     TRACE("(%p %p %d)\n", this, locinfo, isdef);
3708
3709     _Locinfo__Getcvt(locinfo, &cvt);
3710
3711     to_convert = _Locinfo__Getfalse(locinfo);
3712     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3713     this->false_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3714     if(this->false_name)
3715         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3716                 (wchar_t*)this->false_name, len);
3717
3718     to_convert = _Locinfo__Gettrue(locinfo);
3719     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3720     this->true_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3721     if(this->true_name)
3722         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3723                 (wchar_t*)this->true_name, len);
3724
3725     if(isdef) {
3726         this->grouping = MSVCRT_operator_new(1);
3727         if(this->grouping)
3728             *(char*)this->grouping = 0;
3729
3730         this->dp = '.';
3731         this->sep = ',';
3732     } else {
3733         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3734
3735         len = strlen(lc->grouping)+1;
3736         this->grouping = MSVCRT_operator_new(len);
3737         if(this->grouping)
3738             memcpy((char*)this->grouping, lc->grouping, len);
3739
3740         this->dp = lc->decimal_point[0];
3741         this->sep = lc->thousands_sep[0];
3742     }
3743
3744     if(!this->false_name || !this->true_name || !this->grouping) {
3745         MSVCRT_operator_delete((char*)this->grouping);
3746         MSVCRT_operator_delete((wchar_t*)this->false_name);
3747         MSVCRT_operator_delete((wchar_t*)this->true_name);
3748
3749         ERR("Out of memory\n");
3750         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3751     }
3752 }
3753
3754 /* ?_Tidy@?$numpunct@_W@std@@AAEXXZ */
3755 /* ?_Tidy@?$numpunct@_W@std@@AEAAXXZ */
3756 /* ?_Tidy@?$numpunct@G@std@@AAEXXZ */
3757 /* ?_Tidy@?$numpunct@G@std@@AEAAXXZ */
3758 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Tidy, 4)
3759 void __thiscall numpunct_wchar__Tidy(numpunct_wchar *this)
3760 {
3761     TRACE("(%p)\n", this);
3762
3763     MSVCRT_operator_delete((char*)this->grouping);
3764     MSVCRT_operator_delete((wchar_t*)this->false_name);
3765     MSVCRT_operator_delete((wchar_t*)this->true_name);
3766 }
3767
3768 /* ??0?$numpunct@_W@std@@QAE@ABV_Locinfo@1@I_N@Z */
3769 /* ??0?$numpunct@_W@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3770 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_locinfo, 16)
3771 numpunct_wchar* __thiscall numpunct_wchar_ctor_locinfo(numpunct_wchar *this,
3772         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3773 {
3774     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3775     locale_facet_ctor_refs(&this->facet, refs);
3776     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3777     numpunct_wchar__Init(this, locinfo, usedef);
3778     return this;
3779 }
3780
3781 /* ??0?$numpunct@G@std@@QAE@ABV_Locinfo@1@I_N@Z */
3782 /* ??0?$numpunct@G@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3783 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_locinfo, 16)
3784 numpunct_wchar* __thiscall numpunct_short_ctor_locinfo(numpunct_wchar *this,
3785         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3786 {
3787     numpunct_wchar_ctor_locinfo(this, locinfo, refs, usedef);
3788     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3789     return this;
3790 }
3791
3792 /* ??0?$numpunct@_W@std@@IAE@PBDI_N@Z */
3793 /* ??0?$numpunct@_W@std@@IEAA@PEBD_K_N@Z */
3794 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_name, 16)
3795 numpunct_wchar* __thiscall numpunct_wchar_ctor_name(numpunct_wchar *this,
3796         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3797 {
3798     _Locinfo locinfo;
3799
3800     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3801     locale_facet_ctor_refs(&this->facet, refs);
3802     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3803
3804     _Locinfo_ctor_cstr(&locinfo, name);
3805     numpunct_wchar__Init(this, &locinfo, usedef);
3806     _Locinfo_dtor(&locinfo);
3807     return this;
3808 }
3809
3810 /* ??0?$numpunct@G@std@@IAE@PBDI_N@Z */
3811 /* ??0?$numpunct@G@std@@IEAA@PEBD_K_N@Z */
3812     DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_name, 16)
3813 numpunct_wchar* __thiscall numpunct_short_ctor_name(numpunct_wchar *this,
3814         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3815 {
3816     numpunct_wchar_ctor_name(this, name, refs, usedef);
3817     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3818     return this;
3819 }
3820
3821 /* ??0?$numpunct@_W@std@@QAE@I@Z */
3822 /* ??0?$numpunct@_W@std@@QEAA@_K@Z */
3823     DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_refs, 8)
3824 numpunct_wchar* __thiscall numpunct_wchar_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3825 {
3826     TRACE("(%p %lu)\n", this, refs);
3827     return numpunct_wchar_ctor_name(this, "C", refs, FALSE);
3828 }
3829
3830 /* ??0?$numpunct@G@std@@QAE@I@Z */
3831 /* ??0?$numpunct@G@std@@QEAA@_K@Z */
3832 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_refs, 8)
3833 numpunct_wchar* __thiscall numpunct_short_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3834 {
3835     numpunct_wchar_ctor_refs(this, refs);
3836     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3837     return this;
3838 }
3839
3840 /* ??_F?$numpunct@_W@std@@QAEXXZ */
3841 /* ??_F?$numpunct@_W@std@@QEAAXXZ */
3842 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor, 4)
3843 numpunct_wchar* __thiscall numpunct_wchar_ctor(numpunct_wchar *this)
3844 {
3845     return numpunct_wchar_ctor_refs(this, 0);
3846 }
3847
3848 /* ??_F?$numpunct@G@std@@QAEXXZ */
3849 /* ??_F?$numpunct@G@std@@QEAAXXZ */
3850 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor, 4)
3851 numpunct_wchar* __thiscall numpunct_short_ctor(numpunct_wchar *this)
3852 {
3853     return numpunct_short_ctor_refs(this, 0);
3854 }
3855
3856 /* ??1?$numpunct@_W@std@@MAE@XZ */
3857 /* ??1?$numpunct@_W@std@@MEAA@XZ */
3858 /* ??1?$numpunct@G@std@@MAE@XZ */
3859 /* ??1?$numpunct@G@std@@MEAA@XZ */
3860 DEFINE_THISCALL_WRAPPER(numpunct_wchar_dtor, 4)
3861 void __thiscall numpunct_wchar_dtor(numpunct_wchar *this)
3862 {
3863     TRACE("(%p)\n", this);
3864     numpunct_wchar__Tidy(this);
3865 }
3866
3867 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_wchar_vector_dtor, 8)
3868 numpunct_wchar* __thiscall MSVCP_numpunct_wchar_vector_dtor(numpunct_wchar *this, unsigned int flags)
3869 {
3870     TRACE("(%p %x)\n", this, flags);
3871     if(flags & 2) {
3872         /* we have an array, with the number of elements stored before the first object */
3873         int i, *ptr = (int *)this-1;
3874
3875         for(i=*ptr-1; i>=0; i--)
3876             numpunct_wchar_dtor(this+i);
3877         MSVCRT_operator_delete(ptr);
3878     } else {
3879         numpunct_wchar_dtor(this);
3880         if(flags & 1)
3881             MSVCRT_operator_delete(this);
3882     }
3883
3884     return this;
3885 }
3886
3887 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_short_vector_dtor, 8)
3888 numpunct_wchar* __thiscall MSVCP_numpunct_short_vector_dtor(numpunct_wchar *this, unsigned int flags)
3889 {
3890     return MSVCP_numpunct_wchar_vector_dtor(this, flags);
3891 }
3892
3893 /* ?_Getcat@?$numpunct@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3894 /* ?_Getcat@?$numpunct@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3895 MSVCP_size_t __cdecl numpunct_wchar__Getcat(const locale_facet **facet, const locale *loc)
3896 {
3897     TRACE("(%p %p)\n", facet, loc);
3898
3899     if(facet && !*facet) {
3900         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3901         if(!*facet) {
3902             ERR("Out of memory\n");
3903             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3904             return 0;
3905         }
3906         numpunct_wchar_ctor_name((numpunct_wchar*)*facet,
3907                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3908     }
3909
3910     return LC_NUMERIC;
3911 }
3912
3913 static numpunct_wchar* numpunct_wchar_use_facet(const locale *loc)
3914 {
3915     static numpunct_wchar *obj = NULL;
3916
3917     _Lockit lock;
3918     const locale_facet *fac;
3919
3920     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3921     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_wchar_id));
3922     if(fac) {
3923         _Lockit_dtor(&lock);
3924         return (numpunct_wchar*)fac;
3925     }
3926
3927     if(obj) {
3928         _Lockit_dtor(&lock);
3929         return obj;
3930     }
3931
3932     numpunct_wchar__Getcat(&fac, loc);
3933     obj = (numpunct_wchar*)fac;
3934     locale_facet__Incref(&obj->facet);
3935     locale_facet_register(&obj->facet);
3936     _Lockit_dtor(&lock);
3937
3938     return obj;
3939 }
3940
3941 /* ?_Getcat@?$numpunct@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3942 /* ?_Getcat@?$numpunct@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3943 MSVCP_size_t __cdecl numpunct_short__Getcat(const locale_facet **facet, const locale *loc)
3944 {
3945     TRACE("(%p %p)\n", facet, loc);
3946
3947     if(facet && !*facet) {
3948         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3949         if(!*facet) {
3950             ERR("Out of memory\n");
3951             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3952             return 0;
3953         }
3954         numpunct_short_ctor_name((numpunct_wchar*)*facet,
3955                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3956     }
3957
3958     return LC_NUMERIC;
3959 }
3960
3961 static numpunct_wchar* numpunct_short_use_facet(const locale *loc)
3962 {
3963     static numpunct_wchar *obj = NULL;
3964
3965     _Lockit lock;
3966     const locale_facet *fac;
3967
3968     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3969     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_short_id));
3970     if(fac) {
3971         _Lockit_dtor(&lock);
3972         return (numpunct_wchar*)fac;
3973     }
3974
3975     if(obj) {
3976         _Lockit_dtor(&lock);
3977         return obj;
3978     }
3979
3980     numpunct_short__Getcat(&fac, loc);
3981     obj = (numpunct_wchar*)fac;
3982     locale_facet__Incref(&obj->facet);
3983     locale_facet_register(&obj->facet);
3984     _Lockit_dtor(&lock);
3985
3986     return obj;
3987 }
3988
3989 /* ?do_decimal_point@?$numpunct@_W@std@@MBE_WXZ */
3990 /* ?do_decimal_point@?$numpunct@_W@std@@MEBA_WXZ */
3991 /* ?do_decimal_point@?$numpunct@G@std@@MBEGXZ */
3992 /* ?do_decimal_point@?$numpunct@G@std@@MEBAGXZ */
3993 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_decimal_point, 4)
3994 #define call_numpunct_wchar_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3995         wchar_t, (const numpunct_wchar *this), (this))
3996 wchar_t __thiscall numpunct_wchar_do_decimal_point(const numpunct_wchar *this)
3997 {
3998     TRACE("(%p)\n", this);
3999     return this->dp;
4000 }
4001
4002 /* ?decimal_point@?$numpunct@_W@std@@QBE_WXZ */
4003 /* ?decimal_point@?$numpunct@_W@std@@QEBA_WXZ */
4004 /* ?decimal_point@?$numpunct@G@std@@QBEGXZ */
4005 /* ?decimal_point@?$numpunct@G@std@@QEBAGXZ */
4006 DEFINE_THISCALL_WRAPPER(numpunct_wchar_decimal_point, 4)
4007 wchar_t __thiscall numpunct_wchar_decimal_point(const numpunct_wchar *this)
4008 {
4009     TRACE("(%p)\n", this);
4010     return call_numpunct_wchar_do_decimal_point(this);
4011 }
4012
4013 /* ?do_thousands_sep@?$numpunct@_W@std@@MBE_WXZ */
4014 /* ?do_thousands_sep@?$numpunct@_W@std@@MEBA_WXZ */
4015 /* ?do_thousands_sep@?$numpunct@G@std@@MBEGXZ */
4016 /* ?do_thousands_sep@?$numpunct@G@std@@MEBAGXZ */
4017 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_thousands_sep, 4)
4018 #define call_numpunct_wchar_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
4019         wchar_t, (const numpunct_wchar *this), (this))
4020 wchar_t __thiscall numpunct_wchar_do_thousands_sep(const numpunct_wchar *this)
4021 {
4022     TRACE("(%p)\n", this);
4023     return this->sep;
4024 }
4025
4026 /* ?thousands_sep@?$numpunct@_W@std@@QBE_WXZ */
4027 /* ?thousands_sep@?$numpunct@_W@std@@QEBA_WXZ */
4028 /* ?thousands_sep@?$numpunct@G@std@@QBEGXZ */
4029 /* ?thousands_sep@?$numpunct@G@std@@QEBAGXZ */
4030 DEFINE_THISCALL_WRAPPER(numpunct_wchar_thousands_sep, 4)
4031 wchar_t __thiscall numpunct_wchar_thousands_sep(const numpunct_wchar *this)
4032 {
4033     TRACE("(%p)\n", this);
4034     return call_numpunct_wchar_do_thousands_sep(this);
4035 }
4036
4037 /* ?do_grouping@?$numpunct@_W@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4038 /* ?do_grouping@?$numpunct@_W@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4039 /* ?do_grouping@?$numpunct@G@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4040 /* ?do_grouping@?$numpunct@G@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4041 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_grouping, 8)
4042 #define call_numpunct_wchar_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
4043         basic_string_char*, (const numpunct_wchar*, basic_string_char*), (this, ret))
4044 basic_string_char* __thiscall numpunct_wchar_do_grouping(const numpunct_wchar *this, basic_string_char *ret)
4045 {
4046     TRACE("(%p)\n", this);
4047     return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping);
4048 }
4049
4050 /* ?grouping@?$numpunct@_W@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4051 /* ?grouping@?$numpunct@_W@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4052 /* ?grouping@?$numpunct@G@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4053 /* ?grouping@?$numpunct@G@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
4054 DEFINE_THISCALL_WRAPPER(numpunct_wchar_grouping, 8)
4055 basic_string_char* __thiscall numpunct_wchar_grouping(const numpunct_wchar *this, basic_string_char *ret)
4056 {
4057     TRACE("(%p)\n", this);
4058     return call_numpunct_wchar_do_grouping(this, ret);
4059 }
4060
4061 /* ?do_falsename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4062 /* ?do_falsename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4063 /* ?do_falsename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4064 /* ?do_falsename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4065 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_falsename, 8)
4066 #define call_numpunct_wchar_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
4067         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
4068 basic_string_wchar* __thiscall numpunct_wchar_do_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
4069 {
4070     TRACE("(%p)\n", this);
4071     return MSVCP_basic_string_wchar_ctor_cstr(ret, this->false_name);
4072 }
4073
4074 /* ?falsename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4075 /* ?falsename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4076 /* ?falsename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4077 /* ?falsename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4078 DEFINE_THISCALL_WRAPPER(numpunct_wchar_falsename, 8)
4079 basic_string_wchar* __thiscall numpunct_wchar_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
4080 {
4081     TRACE("(%p)\n", this);
4082     return call_numpunct_wchar_do_falsename(this, ret);
4083 }
4084
4085 /* ?do_truename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4086 /* ?do_truename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4087 /* ?do_truename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4088 /* ?do_truename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4089 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_truename, 8)
4090 #define call_numpunct_wchar_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
4091         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
4092 basic_string_wchar* __thiscall numpunct_wchar_do_truename(const numpunct_wchar *this, basic_string_wchar *ret)
4093 {
4094     TRACE("(%p)\n", this);
4095     return MSVCP_basic_string_wchar_ctor_cstr(ret, this->true_name);
4096 }
4097
4098 /* ?truename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4099 /* ?truename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
4100 /* ?truename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4101 /* ?truename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
4102 DEFINE_THISCALL_WRAPPER(numpunct_wchar_truename, 8)
4103 basic_string_wchar* __thiscall numpunct_wchar_truename(const numpunct_wchar *this, basic_string_wchar *ret)
4104 {
4105     TRACE("(%p)\n", this);
4106     return call_numpunct_wchar_do_truename(this, ret);
4107 }
4108
4109 double __cdecl _Stod(const char *buf, char **buf_end, LONG exp)
4110 {
4111     double ret = strtod(buf, buf_end);
4112
4113     if(exp)
4114         ret *= pow(10, exp);
4115     return ret;
4116 }
4117
4118 double __cdecl _Stodx(const char *buf, char **buf_end, LONG exp, int *err)
4119 {
4120     double ret;
4121
4122     *err = *_errno();
4123     *_errno() = 0;
4124     ret = _Stod(buf, buf_end, exp);
4125     if(*_errno()) {
4126         *err = *_errno();
4127     }else {
4128         *_errno() = *err;
4129         *err = 0;
4130     }
4131     return ret;
4132 }
4133
4134 float __cdecl _Stof(const char *buf, char **buf_end, LONG exp)
4135 {
4136     return _Stod(buf, buf_end, exp);
4137 }
4138
4139 float __cdecl _Stofx(const char *buf, char **buf_end, LONG exp, int *err)
4140 {
4141     return _Stodx(buf, buf_end, exp, err);
4142 }
4143
4144 __int64 __cdecl _Stoll(const char *buf, char **buf_end, int base)
4145 {
4146     return _strtoi64(buf, buf_end, base);
4147 }
4148
4149 __int64 __cdecl _Stollx(const char *buf, char **buf_end, int base, int *err)
4150 {
4151     __int64 ret;
4152
4153     *err = *_errno();
4154     *_errno() = 0;
4155     ret = _strtoi64(buf, buf_end, base);
4156     if(*_errno()) {
4157         *err = *_errno();
4158     }else {
4159         *_errno() = *err;
4160         *err = 0;
4161     }
4162     return ret;
4163 }
4164
4165 LONG __cdecl _Stolx(const char *buf, char **buf_end, int base, int *err)
4166 {
4167     __int64 i = _Stollx(buf, buf_end, base, err);
4168     if(!*err && i!=(__int64)((LONG)i))
4169         *err = ERANGE;
4170     return i;
4171 }
4172
4173 unsigned __int64 __cdecl _Stoull(const char *buf, char **buf_end, int base)
4174 {
4175     return _strtoui64(buf, buf_end, base);
4176 }
4177
4178 unsigned __int64 __cdecl _Stoullx(const char *buf, char **buf_end, int base, int *err)
4179 {
4180     unsigned __int64 ret;
4181
4182     *err = *_errno();
4183     *_errno() = 0;
4184     ret = _strtoui64(buf, buf_end, base);
4185     if(*_errno()) {
4186         *err = *_errno();
4187     }else {
4188         *_errno() = *err;
4189         *err = 0;
4190     }
4191     return ret;
4192 }
4193
4194 ULONG __cdecl _Stoul(const char *buf, char **buf_end, int base)
4195 {
4196     int err;
4197     unsigned __int64 i = _Stoullx(buf[0]=='-' ? buf+1 : buf, buf_end, base, &err);
4198     if(!err && i!=(unsigned __int64)((ULONG)i))
4199         *_errno() = ERANGE;
4200     return buf[0]=='-' ? -i : i;
4201 }
4202
4203 ULONG __cdecl _Stoulx(const char *buf, char **buf_end, int base, int *err)
4204 {
4205     unsigned __int64 i = _Stoullx(buf[0]=='-' ? buf+1 : buf, buf_end, base, err);
4206     if(!*err && i!=(unsigned __int64)((ULONG)i))
4207         *err = ERANGE;
4208     return buf[0]=='-' ? -i : i;
4209 }
4210
4211 /* ?id@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
4212 locale_id num_get_wchar_id = {0};
4213 /* ?id@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@2V0locale@2@A */
4214 locale_id num_get_short_id = {0};
4215
4216 /* ??_7?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
4217 extern const vtable_ptr MSVCP_num_get_wchar_vtable;
4218 /* ??_7?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@6B@ */
4219 extern const vtable_ptr MSVCP_num_get_short_vtable;
4220
4221 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4222 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4223 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4224 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4225 DEFINE_THISCALL_WRAPPER(num_get_wchar__Init, 8)
4226 void __thiscall num_get_wchar__Init(num_get *this, const _Locinfo *locinfo)
4227 {
4228     TRACE("(%p %p)\n", this, locinfo);
4229     _Locinfo__Getcvt(locinfo, &this->cvt);
4230 }
4231
4232 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4233 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4234 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_locinfo, 12)
4235 num_get* __thiscall num_get_wchar_ctor_locinfo(num_get *this,
4236         const _Locinfo *locinfo, MSVCP_size_t refs)
4237 {
4238     TRACE("(%p %p %lu)\n", this, locinfo, refs);
4239
4240     locale_facet_ctor_refs(&this->facet, refs);
4241     this->facet.vtable = &MSVCP_num_get_wchar_vtable;
4242
4243     num_get_wchar__Init(this, locinfo);
4244     return this;
4245 }
4246
4247 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4248 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4249 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_locinfo, 12)
4250 num_get* __thiscall num_get_short_ctor_locinfo(num_get *this,
4251         const _Locinfo *locinfo, MSVCP_size_t refs)
4252 {
4253     num_get_wchar_ctor_locinfo(this, locinfo, refs);
4254     this->facet.vtable = &MSVCP_num_get_short_vtable;
4255     return this;
4256 }
4257
4258 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
4259 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
4260 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_refs, 8)
4261 num_get* __thiscall num_get_wchar_ctor_refs(num_get *this, MSVCP_size_t refs)
4262 {
4263     _Locinfo locinfo;
4264
4265     TRACE("(%p %lu)\n", this, refs);
4266
4267     _Locinfo_ctor(&locinfo);
4268     num_get_wchar_ctor_locinfo(this, &locinfo, refs);
4269     _Locinfo_dtor(&locinfo);
4270     return this;
4271 }
4272
4273 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@I@Z */
4274 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@_K@Z */
4275 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_refs, 8)
4276 num_get* __thiscall num_get_short_ctor_refs(num_get *this, MSVCP_size_t refs)
4277 {
4278     num_get_wchar_ctor_refs(this, refs);
4279     this->facet.vtable = &MSVCP_num_get_short_vtable;
4280     return this;
4281 }
4282
4283 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
4284 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
4285 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor, 4)
4286 num_get* __thiscall num_get_wchar_ctor(num_get *this)
4287 {
4288     return num_get_wchar_ctor_refs(this, 0);
4289 }
4290
4291 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
4292 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
4293 DEFINE_THISCALL_WRAPPER(num_get_short_ctor, 4)
4294 num_get* __thiscall num_get_short_ctor(num_get *this)
4295 {
4296     return num_get_short_ctor_refs(this, 0);
4297 }
4298
4299 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
4300 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
4301 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MAE@XZ */
4302 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEAA@XZ */
4303 DEFINE_THISCALL_WRAPPER(num_get_wchar_dtor, 4)
4304 void __thiscall num_get_wchar_dtor(num_get *this)
4305 {
4306     TRACE("(%p)\n", this);
4307     locale_facet_dtor(&this->facet);
4308 }
4309
4310 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_wchar_vector_dtor, 8)
4311 num_get* __thiscall MSVCP_num_get_wchar_vector_dtor(num_get *this, unsigned int flags)
4312 {
4313     TRACE("(%p %x)\n", this, flags);
4314     if(flags & 2) {
4315         /* we have an array, with the number of elements stored before the first object */
4316         int i, *ptr = (int *)this-1;
4317
4318         for(i=*ptr-1; i>=0; i--)
4319             num_get_wchar_dtor(this+i);
4320         MSVCRT_operator_delete(ptr);
4321     } else {
4322         num_get_wchar_dtor(this);
4323         if(flags & 1)
4324             MSVCRT_operator_delete(this);
4325     }
4326
4327     return this;
4328 }
4329
4330 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_short_vector_dtor, 8)
4331 num_get* __thiscall MSVCP_num_get_short_vector_dtor(num_get *this, unsigned int flags)
4332 {
4333     return MSVCP_num_get_wchar_vector_dtor(this, flags);
4334 }
4335
4336 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4337 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4338 MSVCP_size_t __cdecl num_get_wchar__Getcat(const locale_facet **facet, const locale *loc)
4339 {
4340     TRACE("(%p %p)\n", facet, loc);
4341
4342     if(facet && !*facet) {
4343         _Locinfo locinfo;
4344
4345         *facet = MSVCRT_operator_new(sizeof(num_get));
4346         if(!*facet) {
4347             ERR("Out of memory\n");
4348             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
4349             return 0;
4350         }
4351
4352         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
4353         num_get_wchar_ctor_locinfo((num_get*)*facet, &locinfo, 0);
4354         _Locinfo_dtor(&locinfo);
4355     }
4356
4357     return LC_NUMERIC;
4358 }
4359
4360 num_get* num_get_wchar_use_facet(const locale *loc)
4361 {
4362         static num_get *obj = NULL;
4363
4364         _Lockit lock;
4365         const locale_facet *fac;
4366
4367         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
4368         fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_wchar_id));
4369         if(fac) {
4370             _Lockit_dtor(&lock);
4371             return (num_get*)fac;
4372         }
4373
4374         if(obj) {
4375             _Lockit_dtor(&lock);
4376             return obj;
4377         }
4378
4379         num_get_wchar__Getcat(&fac, loc);
4380         obj = (num_get*)fac;
4381         locale_facet__Incref(&obj->facet);
4382         locale_facet_register(&obj->facet);
4383         _Lockit_dtor(&lock);
4384
4385         return obj;
4386 }
4387
4388 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4389 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4390 MSVCP_size_t __cdecl num_get_short__Getcat(const locale_facet **facet, const locale *loc)
4391 {
4392     if(facet && !*facet) {
4393         num_get_wchar__Getcat(facet, loc);
4394         (*(locale_facet**)facet)->vtable = &MSVCP_num_get_short_vtable;
4395     }
4396
4397     return LC_NUMERIC;
4398 }
4399
4400 static num_get* num_get_short_use_facet(const locale *loc)
4401 {
4402     static num_get *obj = NULL;
4403
4404     _Lockit lock;
4405     const locale_facet *fac;
4406
4407     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
4408     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_short_id));
4409     if(fac) {
4410         _Lockit_dtor(&lock);
4411         return (num_get*)fac;
4412     }
4413
4414     if(obj) {
4415         _Lockit_dtor(&lock);
4416         return obj;
4417     }
4418
4419     num_get_short__Getcat(&fac, loc);
4420     obj = (num_get*)fac;
4421     locale_facet__Incref(&obj->facet);
4422     locale_facet_register(&obj->facet);
4423     _Lockit_dtor(&lock);
4424
4425     return obj;
4426 }
4427
4428 static inline wchar_t mb_to_wc(char ch, const _Cvtvec *cvt)
4429 {
4430     int state;
4431     wchar_t ret;
4432
4433     return _Mbrtowc(&ret, &ch, 1, &state, cvt) == 1 ? ret : 0;
4434 }
4435
4436 static int num_get__Getffld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4437         istreambuf_iterator_wchar *last, const locale *loc, numpunct_wchar *numpunct)
4438 {
4439     basic_string_char grouping_bstr;
4440     int i, groups_no = 0, cur_group = 0, exp = 0;
4441     char *dest_beg = dest, *num_end = dest+25, *exp_end = dest+31, *groups = NULL;
4442     wchar_t sep, digits[11], *digits_pos;
4443     const char *grouping;
4444     BOOL error = FALSE, got_digit = FALSE, dest_empty = TRUE;
4445
4446     TRACE("(%p %p %p %p)\n", dest, first, last, loc);
4447
4448     for(i=0; i<10; i++)
4449         digits[i] = mb_to_wc('0'+i, &this->cvt);
4450     digits[10] = 0;
4451
4452     numpunct_wchar_grouping(numpunct, &grouping_bstr);
4453     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
4454     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : (wchar_t)0;
4455
4456     istreambuf_iterator_wchar_val(first);
4457     if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4458         *dest++ = '-';
4459         istreambuf_iterator_wchar_inc(first);
4460     }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4461         *dest++ = '+';
4462         istreambuf_iterator_wchar_inc(first);
4463     }
4464
4465     if(sep) {
4466         groups_no = strlen(grouping)+2;
4467         groups = calloc(groups_no, sizeof(char));
4468     }
4469
4470     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4471         if(!(digits_pos = wcschr(digits, first->val))) {
4472             if(sep && first->val==sep) {
4473                 if(cur_group == groups_no+1) {
4474                     if(groups[1] != groups[2]) {
4475                         error = TRUE;
4476                         break;
4477                     }else {
4478                         memmove(groups+1, groups+2, groups_no);
4479                         groups[cur_group] = 0;
4480                     }
4481                 }else {
4482                     cur_group++;
4483                 }
4484             }else {
4485                 break;
4486             }
4487         }else {
4488             got_digit = TRUE;
4489             if(dest_empty && first->val == digits[0])
4490                 continue;
4491             dest_empty = FALSE;
4492             if(dest < num_end)
4493                 *dest++ = '0'+digits_pos-digits;
4494             else
4495                 exp++;
4496             if(sep && groups[cur_group]<CHAR_MAX)
4497                 groups[cur_group]++;
4498         }
4499     }
4500
4501     if(cur_group && !groups[cur_group])
4502         error = TRUE;
4503     else if(!cur_group)
4504         cur_group--;
4505
4506     for(; cur_group>=0 && !error; cur_group--) {
4507         if(*grouping == CHAR_MAX) {
4508             if(cur_group)
4509                 error = TRUE;
4510             break;
4511         }else if((cur_group && *grouping!=groups[cur_group])
4512                 || (!cur_group && *grouping<groups[cur_group])) {
4513             error = TRUE;
4514             break;
4515         }else if(grouping[1]) {
4516             grouping++;
4517         }
4518     }
4519     MSVCP_basic_string_char_dtor(&grouping_bstr);
4520     free(groups);
4521
4522     if(error) {
4523         *dest_beg = '\0';
4524         return 0;
4525     }else if(dest_empty) {
4526         *dest++ = '0';
4527     }
4528
4529     if(first->strbuf && first->val==numpunct_wchar_decimal_point(numpunct)) {
4530         if(dest < num_end)
4531             *dest++ = *localeconv()->decimal_point;
4532         istreambuf_iterator_wchar_inc(first);
4533
4534         if(dest_empty) {
4535             for(; first->strbuf && first->val==digits[0]; istreambuf_iterator_wchar_inc(first)) {
4536                 got_digit = TRUE;
4537                 exp--;
4538             }
4539
4540             if(!first->strbuf || !wcschr(digits, first->val))
4541                 dest--;
4542         }
4543     }
4544
4545     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4546         if(!(digits_pos = wcschr(digits, first->val)))
4547             break;
4548         else if(dest<num_end) {
4549             got_digit = TRUE;
4550             *dest++ = '0'+digits_pos-digits;
4551         }
4552     }
4553
4554     if(!got_digit) {
4555         *dest_beg = '\0';
4556         return 0;
4557     }
4558
4559     if(first->strbuf && (first->val==mb_to_wc('e', &this->cvt) || first->val==mb_to_wc('E', &this->cvt))) {
4560         *dest++ = 'e';
4561         istreambuf_iterator_wchar_inc(first);
4562
4563         if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4564             *dest++ = '-';
4565             istreambuf_iterator_wchar_inc(first);
4566         }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4567             *dest++ = '+';
4568             istreambuf_iterator_wchar_inc(first);
4569         }
4570
4571         error = dest_empty = TRUE;
4572         for(; first->strbuf && first->val==digits[0]; istreambuf_iterator_wchar_inc(first))
4573             error = FALSE;
4574
4575         for(; first->strbuf && (digits_pos = wcschr(digits, first->val)); istreambuf_iterator_wchar_inc(first)) {
4576             error = dest_empty = FALSE;
4577             if(dest<exp_end)
4578                 *dest++ = '0'+digits_pos-digits;
4579         }
4580
4581         if(error) {
4582             *dest_beg = '\0';
4583             return 0;
4584         }else if(dest_empty) {
4585             *dest++ = '0';
4586         }
4587     }
4588
4589     *dest++ = '\0';
4590     return exp;
4591 }
4592
4593 /* ?_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 */
4594 /* ?_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 */
4595 int __cdecl num_get_wchar__Getffld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4596     istreambuf_iterator_wchar *last, const locale *loc)
4597 {
4598     return num_get__Getffld(this, dest, first, last, loc, numpunct_wchar_use_facet(loc));
4599 }
4600
4601 /* ?_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 */
4602 /* ?_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 */
4603 int __cdecl num_get_short__Getffld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4604     istreambuf_iterator_wchar *last, const locale *loc)
4605 {
4606     return num_get__Getffld(this, dest, first, last, loc, numpunct_short_use_facet(loc));
4607 }
4608
4609 /* ?_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 */
4610 /* ?_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 */
4611 /* ?_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 */
4612 /* ?_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 */
4613 int __cdecl num_get_wchar__Getffldx(num_get *this, char *dest, istreambuf_iterator_wchar *first,
4614     istreambuf_iterator_wchar *last, ios_base *ios, int *phexexp)
4615 {
4616     FIXME("(%p %p %p %p %p) stub\n", dest, first, last, ios, phexexp);
4617     return -1;
4618 }
4619
4620 static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4621     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc, numpunct_wchar *numpunct)
4622 {
4623     wchar_t digits[23], *digits_pos, sep;
4624     basic_string_char grouping_bstr;
4625     int i, basefield, base, groups_no = 0, cur_group = 0;
4626     char *dest_beg = dest, *dest_end = dest+24, *groups = NULL;
4627     const char *grouping;
4628     BOOL error = TRUE, dest_empty = TRUE;
4629
4630     TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
4631
4632     for(i=0; i<10; i++)
4633         digits[i] = mb_to_wc('0'+i, &this->cvt);
4634     for(i=0; i<6; i++) {
4635         digits[10+i] = mb_to_wc('a'+i, &this->cvt);
4636         digits[16+i] = mb_to_wc('A'+i, &this->cvt);
4637     }
4638
4639     numpunct_wchar_grouping(numpunct, &grouping_bstr);
4640     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
4641     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
4642
4643     basefield = fmtflags & FMTFLAG_basefield;
4644     if(basefield == FMTFLAG_oct)
4645         base = 8;
4646     else if(basefield == FMTFLAG_hex)
4647         base = 22; /* equal to the size of digits buffer */
4648     else if(!basefield)
4649         base = 0;
4650     else
4651         base = 10;
4652
4653     istreambuf_iterator_wchar_val(first);
4654     if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4655         *dest++ = '-';
4656         istreambuf_iterator_wchar_inc(first);
4657     }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4658         *dest++ = '+';
4659         istreambuf_iterator_wchar_inc(first);
4660     }
4661
4662     if(!base && first->strbuf && first->val==digits[0]) {
4663         istreambuf_iterator_wchar_inc(first);
4664         if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('x', &this->cvt))) {
4665             istreambuf_iterator_wchar_inc(first);
4666             base = 22;
4667         }else {
4668             error = FALSE;
4669             base = 8;
4670         }
4671     }else {
4672         base = 10;
4673     }
4674     digits[base] = 0;
4675
4676     if(sep) {
4677         groups_no = strlen(grouping)+2;
4678         groups = calloc(groups_no, sizeof(char));
4679     }
4680
4681     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4682         if(!(digits_pos = wcschr(digits, first->val))) {
4683             if(sep && first->val==sep) {
4684                 if(cur_group == groups_no+1) {
4685                     if(groups[1] != groups[2]) {
4686                         error = TRUE;
4687                         break;
4688                     }else {
4689                         memmove(groups+1, groups+2, groups_no);
4690                         groups[cur_group] = 0;
4691                     }
4692                 }else {
4693                     cur_group++;
4694                 }
4695             }else {
4696                 break;
4697             }
4698         }else {
4699             error = FALSE;
4700             if(dest_empty && first->val == digits[0])
4701                 continue;
4702             dest_empty = FALSE;
4703             /* skip digits that can't be copied to dest buffer, other
4704              * functions are responsible for detecting overflows */
4705             if(dest < dest_end)
4706                 *dest++ = (digits_pos-digits<10 ? '0'+digits_pos-digits :
4707                         (digits_pos-digits<16 ? 'a'+digits_pos-digits-10 :
4708                          'A'+digits_pos-digits-16));
4709             if(sep && groups[cur_group]<CHAR_MAX)
4710                 groups[cur_group]++;
4711         }
4712     }
4713
4714     if(cur_group && !groups[cur_group])
4715         error = TRUE;
4716     else if(!cur_group)
4717         cur_group--;
4718
4719     for(; cur_group>=0 && !error; cur_group--) {
4720         if(*grouping == CHAR_MAX) {
4721             if(cur_group)
4722                 error = TRUE;
4723             break;
4724         }else if((cur_group && *grouping!=groups[cur_group])
4725                 || (!cur_group && *grouping<groups[cur_group])) {
4726             error = TRUE;
4727             break;
4728         }else if(grouping[1]) {
4729             grouping++;
4730         }
4731     }
4732     MSVCP_basic_string_char_dtor(&grouping_bstr);
4733     free(groups);
4734
4735     if(error)
4736         dest = dest_beg;
4737     else if(dest_empty)
4738         *dest++ = '0';
4739     *dest = '\0';
4740
4741     return (base==22 ? 16 : base);
4742 }
4743
4744 /* ?_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 */
4745 /* ?_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 */
4746 int __cdecl num_get_wchar__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4747     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
4748 {
4749     return num_get__Getifld(this, dest, first, last,
4750             fmtflags, loc, numpunct_wchar_use_facet(loc));
4751 }
4752
4753 /* ?_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 */
4754 /* ?_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 */
4755 int __cdecl num_get_short__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4756     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
4757 {
4758     return num_get__Getifld(this, dest, first, last,
4759             fmtflags, loc, numpunct_short_use_facet(loc));
4760 }
4761
4762 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABEH_W000@Z */
4763 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAH_W000@Z */
4764 /* ?_Hexdig@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABEHGGGG@Z */
4765 /* ?_Hexdig@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHGGGG@Z */
4766 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_wchar__Hexdig, 20)
4767 int __thiscall MSVCP_num_get_wchar__Hexdig(num_get *this, wchar_t dig, wchar_t e0, wchar_t al, wchar_t au)
4768 {
4769     FIXME("(%p %c %c %c %c) stub\n", this, dig, e0, al, au);
4770     return -1;
4771 }
4772
4773 static istreambuf_iterator_wchar* num_get_do_get_void(const num_get *this,
4774         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4775         istreambuf_iterator_wchar last, ios_base *base, int *state,
4776         void **pval, numpunct_wchar *numpunct)
4777 {
4778     unsigned __int64 v;
4779     char tmp[25], *end;
4780     int err;
4781
4782     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4783
4784     v = _Stoullx(tmp, &end, num_get__Getifld(this, tmp, &first,
4785                 &last, FMTFLAG_hex, base->loc, numpunct), &err);
4786     if(v!=(unsigned __int64)((INT_PTR)v))
4787         *state |= IOSTATE_failbit;
4788     else if(end!=tmp && !err)
4789         *pval = (void*)((INT_PTR)v);
4790     else
4791         *state |= IOSTATE_failbit;
4792
4793     if(!first.strbuf)
4794         *state |= IOSTATE_eofbit;
4795
4796     *ret = first;
4797     return ret;
4798 }
4799
4800 /* ?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 */
4801 /* ?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 */
4802 #define call_num_get_wchar_do_get_void(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 4, istreambuf_iterator_wchar*, \
4803         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, void**), \
4804         (this, ret, first, last, base, state, pval))
4805 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_void,36)
4806 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4807     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4808 {
4809     return num_get_do_get_void(this, ret, first, last, base,
4810             state, pval, numpunct_wchar_use_facet(base->loc));
4811 }
4812
4813 /* ?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 */
4814 /* ?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 */
4815 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_void,36)
4816 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4817     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4818 {
4819     return num_get_do_get_void(this, ret, first, last, base,
4820             state, pval, numpunct_short_use_facet(base->loc));
4821 }
4822
4823 /* ?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 */
4824 /* ?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 */
4825 /* ?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 */
4826 /* ?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 */
4827 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_void,36)
4828 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4829     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4830 {
4831     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4832     return call_num_get_wchar_do_get_void(this, ret, first, last, base, state, pval);
4833 }
4834
4835 static istreambuf_iterator_wchar* num_get_do_get_double(const num_get *this,
4836         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4837         istreambuf_iterator_wchar last, ios_base *base, int *state,
4838         double *pval, numpunct_wchar *numpunct)
4839 {
4840     double v;
4841     char tmp[32], *end;
4842     int err;
4843
4844     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4845
4846     v = _Stodx(tmp, &end, num_get__Getffld(this, tmp, &first, &last, base->loc, numpunct), &err);
4847     if(end!=tmp && !err)
4848         *pval = v;
4849     else
4850         *state |= IOSTATE_failbit;
4851
4852     if(!first.strbuf)
4853         *state |= IOSTATE_eofbit;
4854
4855     *ret = first;
4856     return ret;
4857 }
4858
4859 /* ?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 */
4860 /* ?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 */
4861 /* ?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 */
4862 /* ?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 */
4863 #define call_num_get_wchar_do_get_ldouble(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 8, istreambuf_iterator_wchar*, \
4864         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, double*), \
4865         (this, ret, first, last, base, state, pval))
4866 #define call_num_get_wchar_do_get_double(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 12, istreambuf_iterator_wchar*, \
4867         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, double*), \
4868         (this, ret, first, last, base, state, pval))
4869 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_double,36)
4870 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4871     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4872 {
4873     return num_get_do_get_double(this, ret, first, last, base,
4874             state, pval, numpunct_wchar_use_facet(base->loc));
4875 }
4876
4877 /* ?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 */
4878 /* ?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 */
4879 /* ?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 */
4880 /* ?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 */
4881 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_double,36)
4882 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4883     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4884 {
4885     return num_get_do_get_double(this, ret, first, last, base,
4886             state, pval, numpunct_short_use_facet(base->loc));
4887 }
4888
4889 /* ?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 */
4890 /* ?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 */
4891 /* ?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 */
4892 /* ?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 */
4893 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ldouble,36)
4894 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ldouble(const num_get *this, istreambuf_iterator_wchar *ret,
4895         istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4896 {
4897     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4898     return call_num_get_wchar_do_get_ldouble(this, ret, first, last, base, state, pval);
4899 }
4900
4901 /* ?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 */
4902 /* ?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 */
4903 /* ?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 */
4904 /* ?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 */
4905 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_double,36)
4906 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4907     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4908 {
4909     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4910     return call_num_get_wchar_do_get_double(this, ret, first, last, base, state, pval);
4911 }
4912
4913 static istreambuf_iterator_wchar* num_get_do_get_float(const num_get *this,
4914         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4915         istreambuf_iterator_wchar last, ios_base *base, int *state,
4916         float *pval, numpunct_wchar *numpunct)
4917 {
4918     float v;
4919     char tmp[32], *end;
4920     int err;
4921
4922     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4923
4924     v = _Stofx(tmp, &end, num_get__Getffld(this, tmp, &first,
4925                 &last, base->loc, numpunct), &err);
4926     if(end!=tmp && !err)
4927         *pval = v;
4928     else
4929         *state |= IOSTATE_failbit;
4930
4931     if(!first.strbuf)
4932         *state |= IOSTATE_eofbit;
4933
4934     *ret = first;
4935     return ret;
4936 }
4937
4938 /* ?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 */
4939 /* ?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 */
4940 #define call_num_get_wchar_do_get_float(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 16, istreambuf_iterator_wchar*, \
4941         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, float*), \
4942         (this, ret, first, last, base, state, pval))
4943 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_float,36)
4944 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4945     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4946 {
4947     return num_get_do_get_float(this, ret, first, last, base,
4948             state, pval, numpunct_wchar_use_facet(base->loc));
4949 }
4950
4951 /* ?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 */
4952 /* ?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 */
4953 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_float,36)
4954 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4955     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4956 {
4957     return num_get_do_get_float(this, ret, first, last, base,
4958             state, pval, numpunct_short_use_facet(base->loc));
4959 }
4960
4961 /* ?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 */
4962 /* ?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 */
4963 /* ?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 */
4964 /* ?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 */
4965 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_float,36)
4966 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4967     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4968 {
4969     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4970     return call_num_get_wchar_do_get_float(this, ret, first, last, base, state, pval);
4971 }
4972
4973 static istreambuf_iterator_wchar* num_get_do_get_uint64(const num_get *this,
4974         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4975         istreambuf_iterator_wchar last, ios_base *base, int *state,
4976         ULONGLONG *pval, numpunct_wchar *numpunct)
4977 {
4978     unsigned __int64 v;
4979     char tmp[25], *end;
4980     int err;
4981
4982     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4983
4984     v = _Stoullx(tmp, &end, num_get__Getifld(this, tmp, &first,
4985                 &last, base->fmtfl, base->loc, numpunct), &err);
4986     if(end!=tmp && !err)
4987         *pval = v;
4988     else
4989         *state |= IOSTATE_failbit;
4990
4991     if(!first.strbuf)
4992         *state |= IOSTATE_eofbit;
4993
4994     *ret = first;
4995     return ret;
4996 }
4997
4998 /* ?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 */
4999 /* ?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 */
5000 #define call_num_get_wchar_do_get_uint64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 20, istreambuf_iterator_wchar*, \
5001         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, ULONGLONG*), \
5002         (this, ret, first, last, base, state, pval))
5003 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint64,36)
5004 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
5005     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
5006 {
5007     return num_get_do_get_uint64(this, ret, first, last, base,
5008             state, pval, numpunct_wchar_use_facet(base->loc));
5009 }
5010
5011 /* ?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 */
5012 /* ?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 */
5013 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_uint64,36)
5014 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
5015     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
5016 {
5017     return num_get_do_get_uint64(this, ret, first, last, base,
5018             state, pval, numpunct_short_use_facet(base->loc));
5019 }
5020
5021 /* ?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 */
5022 /* ?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 */
5023 /* ?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 */
5024 /* ?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 */
5025 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint64,36)
5026 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
5027     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
5028 {
5029     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5030     return call_num_get_wchar_do_get_uint64(this, ret, first, last, base, state, pval);
5031 }
5032
5033 static istreambuf_iterator_wchar* num_get_do_get_int64(const num_get *this,
5034         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5035         istreambuf_iterator_wchar last, ios_base *base, int *state,
5036         LONGLONG *pval, numpunct_wchar *numpunct)
5037 {
5038     __int64 v;
5039     char tmp[25], *end;
5040     int err;
5041
5042     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5043
5044     v = _Stollx(tmp, &end, num_get__Getifld(this, tmp, &first,
5045                 &last, base->fmtfl, base->loc, numpunct), &err);
5046     if(end!=tmp && !err)
5047         *pval = v;
5048     else
5049         *state |= IOSTATE_failbit;
5050
5051     if(!first.strbuf)
5052         *state |= IOSTATE_eofbit;
5053
5054     *ret = first;
5055     return ret;
5056 }
5057
5058 /* ?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 */
5059 /* ?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 */
5060 #define call_num_get_wchar_do_get_int64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 24, istreambuf_iterator_wchar*, \
5061         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, LONGLONG*), \
5062         (this, ret, first, last, base, state, pval))
5063 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_int64,36)
5064 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
5065     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
5066 {
5067     return num_get_do_get_int64(this, ret, first, last, base,
5068             state, pval, numpunct_wchar_use_facet(base->loc));
5069 }
5070
5071 /* ?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 */
5072 /* ?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 */
5073 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_int64,36)
5074 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
5075     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
5076 {
5077     return num_get_do_get_int64(this, ret, first, last, base,
5078             state, pval, numpunct_short_use_facet(base->loc));
5079 }
5080
5081 /* ?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 */
5082 /* ?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 */
5083 /* ?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 */
5084 /* ?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 */
5085 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_int64,36)
5086 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
5087     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
5088 {
5089     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5090     return call_num_get_wchar_do_get_int64(this, ret, first, last, base, state, pval);
5091 }
5092
5093 static istreambuf_iterator_wchar* num_get_do_get_ulong(const num_get *this,
5094         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5095         istreambuf_iterator_wchar last, ios_base *base, int *state,
5096         ULONG *pval, numpunct_wchar *numpunct)
5097 {
5098     ULONG v;
5099     char tmp[25], *end;
5100     int err;
5101
5102     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5103
5104     v = _Stoulx(tmp, &end, num_get__Getifld(this, tmp, &first,
5105                 &last, base->fmtfl, base->loc, numpunct), &err);
5106     if(end!=tmp && !err)
5107         *pval = v;
5108     else
5109         *state |= IOSTATE_failbit;
5110
5111     if(!first.strbuf)
5112         *state |= IOSTATE_eofbit;
5113
5114     *ret = first;
5115     return ret;
5116 }
5117
5118 /* ?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 */
5119 /* ?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 */
5120 #define call_num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 28, istreambuf_iterator_wchar*, \
5121         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, ULONG*), \
5122         (this, ret, first, last, base, state, pval))
5123 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ulong,36)
5124 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
5125     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
5126 {
5127     return num_get_do_get_ulong(this, ret, first, last, base,
5128             state, pval, numpunct_wchar_use_facet(base->loc));
5129 }
5130
5131 /* ?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 */
5132 /* ?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 */
5133 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_ulong,36)
5134 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
5135     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
5136 {
5137     return num_get_do_get_ulong(this, ret, first, last, base,
5138             state, pval, numpunct_short_use_facet(base->loc));
5139 }
5140
5141 /* ?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 */
5142 /* ?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 */
5143 /* ?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 */
5144 /* ?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 */
5145 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ulong,36)
5146 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
5147     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
5148 {
5149     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5150     return call_num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval);
5151 }
5152
5153 static istreambuf_iterator_wchar* num_get_do_get_long(const num_get *this,
5154         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5155         istreambuf_iterator_wchar last, ios_base *base, int *state,
5156         LONG *pval, numpunct_wchar *numpunct)
5157 {
5158     LONG v;
5159     char tmp[25], *end;
5160     int err;
5161
5162     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5163
5164     v = _Stolx(tmp, &end, num_get__Getifld(this, tmp, &first,
5165                 &last, base->fmtfl, base->loc, numpunct), &err);
5166     if(end!=tmp && !err)
5167         *pval = v;
5168     else
5169         *state |= IOSTATE_failbit;
5170
5171     if(!first.strbuf)
5172         *state |= IOSTATE_eofbit;
5173
5174     *ret = first;
5175     return ret;
5176 }
5177
5178 /* ?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 */
5179 /* ?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 */
5180 #define call_num_get_wchar_do_get_long(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 32, istreambuf_iterator_wchar*, \
5181         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, LONG*), \
5182         (this, ret, first, last, base, state, pval))
5183 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_long,36)
5184 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
5185     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
5186 {
5187     return num_get_do_get_long(this, ret, first, last, base,
5188             state, pval, numpunct_wchar_use_facet(base->loc));
5189 }
5190
5191 /* ?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 */
5192 /* ?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 */
5193 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_long,36)
5194 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
5195     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
5196 {
5197     return num_get_do_get_long(this, ret, first, last, base,
5198         state, pval, numpunct_short_use_facet(base->loc));
5199 }
5200
5201 /* ?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 */
5202 /* ?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 */
5203 /* ?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 */
5204 /* ?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 */
5205 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_long,36)
5206 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
5207     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
5208 {
5209     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5210     return call_num_get_wchar_do_get_long(this, ret, first, last, base, state, pval);
5211 }
5212
5213 /* ?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 */
5214 /* ?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 */
5215 #define call_num_get_wchar_do_get_uint(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 36, istreambuf_iterator_wchar*, \
5216         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, unsigned int*), \
5217         (this, ret, first, last, base, state, pval))
5218 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint,36)
5219 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
5220     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
5221 {
5222     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5223     return num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval);
5224 }
5225
5226 /* ?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 */
5227 /* ?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 */
5228 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_uint,36)
5229 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
5230     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
5231 {
5232     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5233     return num_get_short_do_get_ulong(this, ret, first, last, base, state, pval);
5234 }
5235
5236 /* ?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 */
5237 /* ?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 */
5238 /* ?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 */
5239 /* ?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 */
5240 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint,36)
5241 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
5242     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
5243 {
5244     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5245     return call_num_get_wchar_do_get_uint(this, ret, first, last, base, state, pval);
5246 }
5247
5248 /* ?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 */
5249 /* ?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 */
5250 #define call_num_get_wchar_do_get_ushort(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 40, istreambuf_iterator_wchar*, \
5251         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, unsigned short*), \
5252         (this, ret, first, last, base, state, pval))
5253 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ushort,36)
5254 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
5255     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
5256 {
5257     ULONG v;
5258     char tmp[25], *beg, *end;
5259     int err, b;
5260
5261     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5262
5263     b = num_get_wchar__Getifld(this, tmp,
5264             &first, &last, base->fmtfl, base->loc);
5265     beg = tmp + (tmp[0]=='-' ? 1 : 0);
5266     v = _Stoulx(beg, &end, b, &err);
5267
5268     if(v != (ULONG)((unsigned short)v))
5269         *state |= IOSTATE_failbit;
5270     else if(end!=beg && !err)
5271         *pval = (tmp[0]=='-' ? -((unsigned short)v) : v);
5272     else
5273         *state |= IOSTATE_failbit;
5274
5275     if(!first.strbuf)
5276         *state |= IOSTATE_eofbit;
5277
5278     *ret = first;
5279     return ret;
5280 }
5281
5282 /* ?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 */
5283 /* ?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 */
5284 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_ushort,36)
5285 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
5286     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
5287 {
5288     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
5289     return ret;
5290 }
5291
5292 /* ?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 */
5293 /* ?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 */
5294 /* ?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@ */
5295 /* ?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 */
5296 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ushort,36)
5297 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
5298     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
5299 {
5300     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5301     return call_num_get_wchar_do_get_ushort(this, ret, first, last, base, state, pval);
5302 }
5303
5304 static istreambuf_iterator_wchar* num_get_do_get_bool(const num_get *this,
5305         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
5306         istreambuf_iterator_wchar last, ios_base *base, int *state,
5307         MSVCP_bool *pval, numpunct_wchar *numpunct)
5308 {
5309     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5310
5311     if(base->fmtfl & FMTFLAG_boolalpha) {
5312         basic_string_wchar false_bstr, true_bstr;
5313         const wchar_t *pfalse, *ptrue;
5314
5315         numpunct_wchar_falsename(numpunct, &false_bstr);
5316         numpunct_wchar_truename(numpunct, &true_bstr);
5317         pfalse = MSVCP_basic_string_wchar_c_str(&false_bstr);
5318         ptrue = MSVCP_basic_string_wchar_c_str(&true_bstr);
5319
5320         for(istreambuf_iterator_wchar_val(&first); first.strbuf;
5321                 istreambuf_iterator_wchar_inc(&first)) {
5322             if(pfalse && *pfalse && first.val!=*pfalse)
5323                 pfalse = NULL;
5324             if(ptrue && *ptrue && first.val!=*ptrue)
5325                 ptrue = NULL;
5326
5327             if(pfalse && *pfalse && ptrue && !*ptrue)
5328                 ptrue = NULL;
5329             if(ptrue && *ptrue && pfalse && !*pfalse)
5330                 pfalse = NULL;
5331
5332             if(pfalse)
5333                 pfalse++;
5334             if(ptrue)
5335                 ptrue++;
5336
5337             if((!pfalse || !*pfalse) && (!ptrue || !*ptrue))
5338                 break;
5339         }
5340
5341         if(ptrue)
5342             *pval = TRUE;
5343         else if(pfalse)
5344             *pval = FALSE;
5345         else
5346             *state |= IOSTATE_failbit;
5347
5348         MSVCP_basic_string_wchar_dtor(&false_bstr);
5349         MSVCP_basic_string_wchar_dtor(&true_bstr);
5350     }else {
5351         char tmp[25], *end;
5352         int err;
5353         LONG v = _Stolx(tmp, &end, num_get__Getifld(this, tmp, &first,
5354                     &last, base->fmtfl, base->loc, numpunct), &err);
5355
5356         if(end!=tmp && err==0 && (v==0 || v==1))
5357             *pval = v;
5358         else
5359             *state |= IOSTATE_failbit;
5360     }
5361
5362     if(!first.strbuf)
5363         *state |= IOSTATE_eofbit;
5364     memcpy(ret, &first, sizeof(first));
5365     return ret;
5366 }
5367
5368 /* ?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 */
5369 /* ?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 */
5370 #define call_num_get_wchar_do_get_bool(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 44, istreambuf_iterator_wchar*, \
5371         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, MSVCP_bool*), \
5372         (this, ret, first, last, base, state, pval))
5373 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_bool,36)
5374 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
5375     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
5376 {
5377     return num_get_do_get_bool(this, ret, first, last, base,
5378             state, pval, numpunct_wchar_use_facet(base->loc));
5379 }
5380
5381 /* ?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 */
5382 /* ?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 */
5383 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_bool,36)
5384 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
5385     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
5386 {
5387     return num_get_do_get_bool(this, ret, first, last, base,
5388             state, pval, numpunct_short_use_facet(base->loc));
5389 }
5390
5391 /* ?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 */
5392 /* ?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 */
5393 /* ?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 */
5394 /* ?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 */
5395 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_bool,36)
5396 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
5397     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
5398 {
5399     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5400     return call_num_get_wchar_do_get_bool(this, ret, first, last, base, state, pval);
5401 }
5402
5403 /* ?id@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
5404 locale_id num_get_char_id = {0};
5405
5406 /* ??_7?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
5407 extern const vtable_ptr MSVCP_num_get_char_vtable;
5408
5409 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
5410 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
5411 DEFINE_THISCALL_WRAPPER(num_get_char__Init, 8)
5412 void __thiscall num_get_char__Init(num_get *this, const _Locinfo *locinfo)
5413 {
5414     TRACE("(%p %p)\n", this, locinfo);
5415     _Locinfo__Getcvt(locinfo, &this->cvt);
5416 }
5417
5418 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
5419 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
5420 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_locinfo, 12)
5421 num_get* __thiscall num_get_char_ctor_locinfo(num_get *this,
5422         const _Locinfo *locinfo, MSVCP_size_t refs)
5423 {
5424     TRACE("(%p %p %lu)\n", this, locinfo, refs);
5425
5426     locale_facet_ctor_refs(&this->facet, refs);
5427     this->facet.vtable = &MSVCP_num_get_char_vtable;
5428
5429     num_get_char__Init(this, locinfo);
5430     return this;
5431 }
5432
5433 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
5434 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
5435 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_refs, 8)
5436 num_get* __thiscall num_get_char_ctor_refs(num_get *this, MSVCP_size_t refs)
5437 {
5438     _Locinfo locinfo;
5439
5440     TRACE("(%p %lu)\n", this, refs);
5441
5442     _Locinfo_ctor(&locinfo);
5443     num_get_char_ctor_locinfo(this, &locinfo, refs);
5444     _Locinfo_dtor(&locinfo);
5445     return this;
5446 }
5447
5448 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
5449 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
5450 DEFINE_THISCALL_WRAPPER(num_get_char_ctor, 4)
5451 num_get* __thiscall num_get_char_ctor(num_get *this)
5452 {
5453     return num_get_char_ctor_refs(this, 0);
5454 }
5455
5456 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
5457 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
5458 DEFINE_THISCALL_WRAPPER(num_get_char_dtor, 4)
5459 void __thiscall num_get_char_dtor(num_get *this)
5460 {
5461     TRACE("(%p)\n", this);
5462     locale_facet_dtor(&this->facet);
5463 }
5464
5465 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_char_vector_dtor, 8)
5466 num_get* __thiscall MSVCP_num_get_char_vector_dtor(num_get *this, unsigned int flags)
5467 {
5468     TRACE("(%p %x)\n", this, flags);
5469     if(flags & 2) {
5470         /* we have an array, with the number of elements stored before the first object */
5471         int i, *ptr = (int *)this-1;
5472
5473         for(i=*ptr-1; i>=0; i--)
5474             num_get_char_dtor(this+i);
5475         MSVCRT_operator_delete(ptr);
5476     } else {
5477         num_get_char_dtor(this);
5478         if(flags & 1)
5479             MSVCRT_operator_delete(this);
5480     }
5481
5482     return this;
5483 }
5484
5485 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
5486 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
5487 MSVCP_size_t __cdecl num_get_char__Getcat(const locale_facet **facet, const locale *loc)
5488 {
5489     TRACE("(%p %p)\n", facet, loc);
5490
5491     if(facet && !*facet) {
5492         _Locinfo locinfo;
5493
5494         *facet = MSVCRT_operator_new(sizeof(num_get));
5495         if(!*facet) {
5496             ERR("Out of memory\n");
5497             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
5498             return 0;
5499         }
5500
5501         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
5502         num_get_char_ctor_locinfo((num_get*)*facet, &locinfo, 0);
5503         _Locinfo_dtor(&locinfo);
5504     }
5505
5506     return LC_NUMERIC;
5507 }
5508
5509 num_get* num_get_char_use_facet(const locale *loc)
5510 {
5511     static num_get *obj = NULL;
5512
5513     _Lockit lock;
5514     const locale_facet *fac;
5515
5516     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
5517     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_char_id));
5518     if(fac) {
5519         _Lockit_dtor(&lock);
5520         return (num_get*)fac;
5521     }
5522
5523     if(obj) {
5524         _Lockit_dtor(&lock);
5525         return obj;
5526     }
5527
5528     num_get_char__Getcat(&fac, loc);
5529     obj = (num_get*)fac;
5530     locale_facet__Incref(&obj->facet);
5531     locale_facet_register(&obj->facet);
5532     _Lockit_dtor(&lock);
5533
5534     return obj;
5535 }
5536
5537 /* ?_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 */
5538 /* ?_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 */
5539 /* Copies number to dest buffer, validates grouping and skips separators.
5540  * Updates first so it points past the number, all digits are skipped.
5541  * Returns how exponent needs to changed.
5542  * Size of dest buffer is not specified, assuming it's not smaller than 32:
5543  * strlen(+0.e+) + 22(digits) + 4(expontent) + 1(nullbyte)
5544  */
5545 int __cdecl num_get_char__Getffld(const num_get *this, char *dest, istreambuf_iterator_char *first,
5546         istreambuf_iterator_char *last, const locale *loc)
5547 {
5548     numpunct_char *numpunct = numpunct_char_use_facet(loc);
5549     basic_string_char grouping_bstr;
5550     int groups_no = 0, cur_group = 0, exp = 0;
5551     char *dest_beg = dest, *num_end = dest+25, *exp_end = dest+31, *groups = NULL, sep;
5552     const char *grouping;
5553     BOOL error = FALSE, got_digit = FALSE, dest_empty = TRUE;
5554
5555     TRACE("(%p %p %p %p)\n", dest, first, last, loc);
5556
5557     numpunct_char_grouping(numpunct, &grouping_bstr);
5558     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
5559     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
5560
5561     istreambuf_iterator_char_val(first);
5562     if(first->strbuf && (first->val=='-' || first->val=='+')) {
5563         *dest++ = first->val;
5564         istreambuf_iterator_char_inc(first);
5565     }
5566
5567     if(sep) {
5568         groups_no = strlen(grouping)+2;
5569         groups = calloc(groups_no, sizeof(char));
5570     }
5571
5572     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5573         if(first->val<'0' || first->val>'9') {
5574             if(sep && first->val==sep) {
5575                 if(cur_group == groups_no+1) {
5576                     if(groups[1] != groups[2]) {
5577                         error = TRUE;
5578                         break;
5579                     }else {
5580                         memmove(groups+1, groups+2, groups_no);
5581                         groups[cur_group] = 0;
5582                     }
5583                 }else {
5584                     cur_group++;
5585                 }
5586             }else {
5587                 break;
5588             }
5589         }else {
5590             got_digit = TRUE;
5591             if(dest_empty && first->val == '0')
5592                 continue;
5593             dest_empty = FALSE;
5594             if(dest < num_end)
5595                 *dest++ = first->val;
5596             else
5597                 exp++;
5598             if(sep && groups[cur_group]<CHAR_MAX)
5599                 groups[cur_group]++;
5600         }
5601     }
5602
5603     if(cur_group && !groups[cur_group])
5604         error = TRUE;
5605     else if(!cur_group)
5606         cur_group--;
5607
5608     for(; cur_group>=0 && !error; cur_group--) {
5609         if(*grouping == CHAR_MAX) {
5610             if(cur_group)
5611                 error = TRUE;
5612             break;
5613         }else if((cur_group && *grouping!=groups[cur_group])
5614                 || (!cur_group && *grouping<groups[cur_group])) {
5615             error = TRUE;
5616             break;
5617         }else if(grouping[1]) {
5618             grouping++;
5619         }
5620     }
5621     MSVCP_basic_string_char_dtor(&grouping_bstr);
5622     free(groups);
5623
5624     if(error) {
5625         *dest_beg = '\0';
5626         return 0;
5627     }else if(dest_empty) {
5628         *dest++ = '0';
5629     }
5630
5631     if(first->strbuf && first->val==numpunct_char_decimal_point(numpunct)) {
5632         if(dest < num_end)
5633             *dest++ = *localeconv()->decimal_point;
5634         istreambuf_iterator_char_inc(first);
5635
5636         if(dest_empty) {
5637             for(; first->strbuf && first->val=='0'; istreambuf_iterator_char_inc(first)) {
5638                 got_digit = TRUE;
5639                 exp--;
5640             }
5641
5642             if(!first->strbuf || first->val<'1' || first->val>'9')
5643                 dest--;
5644         }
5645     }
5646
5647     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5648         if(first->val<'0' || first->val>'9')
5649             break;
5650         else if(dest<num_end) {
5651             got_digit = TRUE;
5652             *dest++ = first->val;
5653         }
5654     }
5655
5656     if(!got_digit) {
5657         *dest_beg = '\0';
5658         return 0;
5659     }
5660
5661     if(first->strbuf && (first->val=='e' || first->val=='E')) {
5662         *dest++ = first->val;
5663         istreambuf_iterator_char_inc(first);
5664
5665         if(first->strbuf && (first->val=='-' || first->val=='+')) {
5666             *dest++ = first->val;
5667             istreambuf_iterator_char_inc(first);
5668         }
5669
5670         error = dest_empty = TRUE;
5671         for(; first->strbuf && first->val=='0'; istreambuf_iterator_char_inc(first))
5672             error = FALSE;
5673
5674         for(; first->strbuf && first->val>='0' && first->val<='9'; istreambuf_iterator_char_inc(first)) {
5675             error = dest_empty = FALSE;
5676             if(dest<exp_end)
5677                 *dest++ = first->val;
5678         }
5679
5680         if(error) {
5681             *dest_beg = '\0';
5682             return 0;
5683         }else if(dest_empty) {
5684             *dest++ = '0';
5685         }
5686     }
5687
5688     *dest++ = '\0';
5689     return exp;
5690 }
5691
5692 /* ?_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 */
5693 /* ?_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 */
5694 int __cdecl num_get_char__Getffldx(const num_get *this, char *dest, istreambuf_iterator_char *first,
5695     istreambuf_iterator_char *last, ios_base *ios, int *phexexp)
5696 {
5697     FIXME("(%p %p %p %p %p) stub\n", dest, first, last, ios, phexexp);
5698     return -1;
5699 }
5700
5701 /* ?_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 */
5702 /* ?_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 */
5703 /* Copies number to dest buffer, validates grouping and skips separators.
5704  * Updates first so it points past the number, all digits are skipped.
5705  * Returns number base (8, 10 or 16).
5706  * Size of dest buffer is not specified, assuming it's not smaller than 25:
5707  * 22(8^22>2^64)+1(detect overflows)+1(sign)+1(nullbyte) = 25
5708  */
5709 int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_iterator_char *first,
5710         istreambuf_iterator_char *last, int fmtflags, const locale *loc)
5711 {
5712     static const char digits[] = "0123456789abcdefABCDEF";
5713
5714     numpunct_char *numpunct = numpunct_char_use_facet(loc);
5715     basic_string_char grouping_bstr;
5716     int basefield, base, groups_no = 0, cur_group = 0;
5717     char *dest_beg = dest, *dest_end = dest+24, *groups = NULL, sep;
5718     const char *grouping;
5719     BOOL error = TRUE, dest_empty = TRUE;
5720
5721     TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
5722
5723     numpunct_char_grouping(numpunct, &grouping_bstr);
5724     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
5725     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
5726
5727     basefield = fmtflags & FMTFLAG_basefield;
5728     if(basefield == FMTFLAG_oct)
5729         base = 8;
5730     else if(basefield == FMTFLAG_hex)
5731         base = 22; /* equal to the size of digits buffer */
5732     else if(!basefield)
5733         base = 0;
5734     else
5735         base = 10;
5736
5737     istreambuf_iterator_char_val(first);
5738     if(first->strbuf && (first->val=='-' || first->val=='+')) {
5739         *dest++ = first->val;
5740         istreambuf_iterator_char_inc(first);
5741     }
5742
5743     if(!base && first->strbuf && first->val=='0') {
5744         istreambuf_iterator_char_inc(first);
5745         if(first->strbuf && (first->val=='x' || first->val=='X')) {
5746             istreambuf_iterator_char_inc(first);
5747             base = 22;
5748         }else {
5749             error = FALSE;
5750             base = 8;
5751         }
5752     }else {
5753         base = 10;
5754     }
5755
5756     if(sep) {
5757         groups_no = strlen(grouping)+2;
5758         groups = calloc(groups_no, sizeof(char));
5759     }
5760
5761     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5762         if(!memchr(digits, first->val, base)) {
5763             if(sep && first->val==sep) {
5764                 if(cur_group == groups_no+1) {
5765                     if(groups[1] != groups[2]) {
5766                         error = TRUE;
5767                         break;
5768                     }else {
5769                         memmove(groups+1, groups+2, groups_no);
5770                         groups[cur_group] = 0;
5771                     }
5772                 }else {
5773                     cur_group++;
5774                 }
5775             }else {
5776                 break;
5777             }
5778         }else {
5779             error = FALSE;
5780             if(dest_empty && first->val == '0')
5781                 continue;
5782             dest_empty = FALSE;
5783             /* skip digits that can't be copied to dest buffer, other
5784              * functions are responsible for detecting overflows */
5785             if(dest < dest_end)
5786                 *dest++ = first->val;
5787             if(sep && groups[cur_group]<CHAR_MAX)
5788                 groups[cur_group]++;
5789         }
5790     }
5791
5792     if(cur_group && !groups[cur_group])
5793         error = TRUE;
5794     else if(!cur_group)
5795         cur_group--;
5796
5797     for(; cur_group>=0 && !error; cur_group--) {
5798         if(*grouping == CHAR_MAX) {
5799             if(cur_group)
5800                 error = TRUE;
5801             break;
5802         }else if((cur_group && *grouping!=groups[cur_group])
5803                 || (!cur_group && *grouping<groups[cur_group])) {
5804             error = TRUE;
5805             break;
5806         }else if(grouping[1]) {
5807             grouping++;
5808         }
5809     }
5810     MSVCP_basic_string_char_dtor(&grouping_bstr);
5811     free(groups);
5812
5813     if(error)
5814         dest = dest_beg;
5815     else if(dest_empty)
5816         *dest++ = '0';
5817     *dest = '\0';
5818
5819     return (base==22 ? 16 : base);
5820 }
5821
5822 /* ?_Hexdig@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABEHD000@Z */
5823 /* ?_Hexdig@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHD000@Z */
5824 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_char__Hexdig, 20)
5825 int __thiscall MSVCP_num_get_char__Hexdig(num_get *this, char dig, char e0, char al, char au)
5826 {
5827     FIXME("(%p %c %c %c %c) stub\n", this, dig, e0, al, au);
5828     return -1;
5829 }
5830
5831 /* ?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 */
5832 /* ?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 */
5833 #define call_num_get_char_do_get_void(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 4, istreambuf_iterator_char*, \
5834         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, void**), \
5835         (this, ret, first, last, base, state, pval))
5836 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_void,36)
5837 istreambuf_iterator_char *__thiscall num_get_char_do_get_void(const num_get *this, istreambuf_iterator_char *ret,
5838     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
5839 {
5840     unsigned __int64 v;
5841     char tmp[25], *end;
5842     int err;
5843
5844     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5845
5846     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
5847                 &first, &last, FMTFLAG_hex, base->loc), &err);
5848     if(v!=(unsigned __int64)((INT_PTR)v))
5849         *state |= IOSTATE_failbit;
5850     else if(end!=tmp && !err)
5851         *pval = (void*)((INT_PTR)v);
5852     else
5853         *state |= IOSTATE_failbit;
5854
5855     if(!first.strbuf)
5856         *state |= IOSTATE_eofbit;
5857
5858     *ret = first;
5859     return ret;
5860 }
5861
5862 /* ?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 */
5863 /* ?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 */
5864 DEFINE_THISCALL_WRAPPER(num_get_char_get_void,36)
5865 istreambuf_iterator_char *__thiscall num_get_char_get_void(const num_get *this, istreambuf_iterator_char *ret,
5866     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
5867 {
5868     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5869     return call_num_get_char_do_get_void(this, ret, first, last, base, state, pval);
5870 }
5871
5872 /* ?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 */
5873 /* ?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 */
5874 /* ?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 */
5875 /* ?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 */
5876 #define call_num_get_char_do_get_ldouble(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 8, istreambuf_iterator_char*, \
5877         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
5878         (this, ret, first, last, base, state, pval))
5879 #define call_num_get_char_do_get_double(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 12, istreambuf_iterator_char*, \
5880         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
5881         (this, ret, first, last, base, state, pval))
5882 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_double,36)
5883 istreambuf_iterator_char *__thiscall num_get_char_do_get_double(const num_get *this, istreambuf_iterator_char *ret,
5884     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5885 {
5886     double v;
5887     char tmp[32], *end;
5888     int err;
5889
5890     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5891
5892     v = _Stodx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
5893     if(end!=tmp && !err)
5894         *pval = v;
5895     else
5896         *state |= IOSTATE_failbit;
5897
5898     if(!first.strbuf)
5899         *state |= IOSTATE_eofbit;
5900
5901     *ret = first;
5902     return ret;
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@AAHAAO@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@AEAHAEAO@Z */
5907 DEFINE_THISCALL_WRAPPER(num_get_char_get_ldouble,36)
5908 istreambuf_iterator_char *__thiscall num_get_char_get_ldouble(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_ldouble(this, ret, first, last, base, state, pval);
5913 }
5914
5915 /* ?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 */
5916 /* ?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 */
5917 DEFINE_THISCALL_WRAPPER(num_get_char_get_double,36)
5918 istreambuf_iterator_char *__thiscall num_get_char_get_double(const num_get *this, istreambuf_iterator_char *ret,
5919     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5920 {
5921     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5922     return call_num_get_char_do_get_double(this, ret, first, last, base, state, pval);
5923 }
5924
5925 /* ?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 */
5926 /* ?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 */
5927 #define call_num_get_char_do_get_float(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 16, istreambuf_iterator_char*, \
5928         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, float*), \
5929         (this, ret, first, last, base, state, pval))
5930 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_float,36)
5931 istreambuf_iterator_char *__thiscall num_get_char_do_get_float(const num_get *this, istreambuf_iterator_char *ret,
5932     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
5933 {
5934     float v;
5935     char tmp[32], *end;
5936     int err;
5937
5938     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5939
5940     v = _Stofx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
5941     if(end!=tmp && !err)
5942         *pval = v;
5943     else
5944         *state |= IOSTATE_failbit;
5945
5946     if(!first.strbuf)
5947         *state |= IOSTATE_eofbit;
5948
5949     *ret = first;
5950     return ret;
5951 }
5952
5953 /* ?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 */
5954 /* ?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 */
5955 DEFINE_THISCALL_WRAPPER(num_get_char_get_float,36)
5956 istreambuf_iterator_char *__thiscall num_get_char_get_float(const num_get *this, istreambuf_iterator_char *ret,
5957     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
5958 {
5959     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5960     return call_num_get_char_do_get_float(this, ret, first, last, base, state, pval);
5961 }
5962
5963 /* ?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 */
5964 /* ?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 */
5965 #define call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 20, istreambuf_iterator_char*, \
5966         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONGLONG*), \
5967         (this, ret, first, last, base, state, pval))
5968 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint64,36)
5969 istreambuf_iterator_char *__thiscall num_get_char_do_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5970     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5971 {
5972     unsigned __int64 v;
5973     char tmp[25], *end;
5974     int err;
5975
5976     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5977
5978     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
5979                 &first, &last, base->fmtfl, base->loc), &err);
5980     if(end!=tmp && !err)
5981         *pval = v;
5982     else
5983         *state |= IOSTATE_failbit;
5984
5985     if(!first.strbuf)
5986         *state |= IOSTATE_eofbit;
5987
5988     *ret = first;
5989     return ret;
5990 }
5991
5992 /* ?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 */
5993 /* ?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 */
5994 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint64,36)
5995 istreambuf_iterator_char *__thiscall num_get_char_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5996     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5997 {
5998     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5999     return call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval);
6000 }
6001
6002 /* ?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 */
6003 /* ?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 */
6004 #define call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 24, istreambuf_iterator_char*, \
6005         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONGLONG*), \
6006         (this, ret, first, last, base, state, pval))
6007 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_int64,36)
6008 istreambuf_iterator_char *__thiscall num_get_char_do_get_int64(const num_get *this, istreambuf_iterator_char *ret,
6009     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
6010 {
6011     __int64 v;
6012     char tmp[25], *end;
6013     int err;
6014
6015     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6016
6017     v = _Stollx(tmp, &end, num_get_char__Getifld(this, tmp,
6018                 &first, &last, base->fmtfl, base->loc), &err);
6019     if(end!=tmp && !err)
6020         *pval = v;
6021     else
6022         *state |= IOSTATE_failbit;
6023
6024     if(!first.strbuf)
6025         *state |= IOSTATE_eofbit;
6026
6027     *ret = first;
6028     return ret;
6029 }
6030
6031 /* ?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 */
6032 /* ?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 */
6033 DEFINE_THISCALL_WRAPPER(num_get_char_get_int64,36)
6034 istreambuf_iterator_char *__thiscall num_get_char_get_int64(const num_get *this, istreambuf_iterator_char *ret,
6035     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
6036 {
6037     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6038     return call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval);
6039 }
6040
6041 /* ?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 */
6042 /* ?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 */
6043 #define call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 28, istreambuf_iterator_char*, \
6044         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONG*), \
6045         (this, ret, first, last, base, state, pval))
6046 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ulong,36)
6047 istreambuf_iterator_char *__thiscall num_get_char_do_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
6048     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
6049 {
6050     ULONG v;
6051     char tmp[25], *end;
6052     int err;
6053
6054     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6055
6056     v = _Stoulx(tmp, &end, num_get_char__Getifld(this, tmp,
6057                 &first, &last, base->fmtfl, base->loc), &err);
6058     if(end!=tmp && !err)
6059         *pval = v;
6060     else
6061         *state |= IOSTATE_failbit;
6062
6063     if(!first.strbuf)
6064         *state |= IOSTATE_eofbit;
6065
6066     *ret = first;
6067     return ret;
6068 }
6069
6070 /* ?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 */
6071 /* ?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 */
6072 DEFINE_THISCALL_WRAPPER(num_get_char_get_ulong,36)
6073 istreambuf_iterator_char *__thiscall num_get_char_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
6074     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
6075 {
6076     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6077     return call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
6078 }
6079
6080 /* ?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 */
6081 /* ?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 */
6082 #define call_num_get_char_do_get_long(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 32, istreambuf_iterator_char*, \
6083         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONG*), \
6084         (this, ret, first, last, base, state, pval))
6085 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_long,36)
6086 istreambuf_iterator_char *__thiscall num_get_char_do_get_long(const num_get *this, istreambuf_iterator_char *ret,
6087     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
6088 {
6089     LONG v;
6090     char tmp[25], *end;
6091     int err;
6092
6093     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6094
6095     v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
6096                 &first, &last, base->fmtfl, base->loc), &err);
6097     if(end!=tmp && !err)
6098         *pval = v;
6099     else
6100         *state |= IOSTATE_failbit;
6101
6102     if(!first.strbuf)
6103         *state |= IOSTATE_eofbit;
6104
6105     *ret = first;
6106     return ret;
6107 }
6108
6109 /* ?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 */
6110 /* ?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 */
6111 DEFINE_THISCALL_WRAPPER(num_get_char_get_long,36)
6112 istreambuf_iterator_char *__thiscall num_get_char_get_long(const num_get *this, istreambuf_iterator_char *ret,
6113     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
6114 {
6115     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6116     return call_num_get_char_do_get_long(this, ret, first, last, base, state, pval);
6117 }
6118
6119 /* ?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 */
6120 /* ?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 */
6121 #define call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 36, istreambuf_iterator_char*, \
6122         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned int*), \
6123         (this, ret, first, last, base, state, pval))
6124 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint,36)
6125 istreambuf_iterator_char *__thiscall num_get_char_do_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 num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
6130 }
6131
6132 /* ?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 */
6133 /* ?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 */
6134 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint,36)
6135 istreambuf_iterator_char *__thiscall num_get_char_get_uint(const num_get *this, istreambuf_iterator_char *ret,
6136     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned int *pval)
6137 {
6138     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6139     return call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval);
6140 }
6141
6142 /* ?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 */
6143 /* ?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 */
6144 #define call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 40, istreambuf_iterator_char*, \
6145         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned short*), \
6146         (this, ret, first, last, base, state, pval))
6147 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ushort,36)
6148 istreambuf_iterator_char *__thiscall num_get_char_do_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
6149     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
6150 {
6151     ULONG v;
6152     char tmp[25], *beg, *end;
6153     int err, b;
6154
6155     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6156
6157     b = num_get_char__Getifld(this, tmp,
6158             &first, &last, base->fmtfl, base->loc);
6159     beg = tmp + (tmp[0]=='-' ? 1 : 0);
6160     v = _Stoulx(beg, &end, b, &err);
6161
6162     if(v != (ULONG)((unsigned short)v))
6163         *state |= IOSTATE_failbit;
6164     else if(end!=beg && !err)
6165         *pval = (tmp[0]=='-' ? -((unsigned short)v) : v);
6166     else
6167         *state |= IOSTATE_failbit;
6168
6169     if(!first.strbuf)
6170         *state |= IOSTATE_eofbit;
6171
6172     *ret = first;
6173     return ret;
6174 }
6175
6176 /* ?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 */
6177 /* ?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 */
6178 DEFINE_THISCALL_WRAPPER(num_get_char_get_ushort,36)
6179 istreambuf_iterator_char *__thiscall num_get_char_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
6180     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
6181 {
6182     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6183     return call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval);
6184 }
6185
6186 /* ?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 */
6187 /* ?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 */
6188 #define call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 44, istreambuf_iterator_char*, \
6189         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, MSVCP_bool*), \
6190         (this, ret, first, last, base, state, pval))
6191 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_bool,36)
6192 istreambuf_iterator_char *__thiscall num_get_char_do_get_bool(const num_get *this, istreambuf_iterator_char *ret,
6193     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
6194 {
6195     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6196
6197     if(base->fmtfl & FMTFLAG_boolalpha) {
6198         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6199         basic_string_char false_bstr, true_bstr;
6200         const char *pfalse, *ptrue;
6201
6202         numpunct_char_falsename(numpunct, &false_bstr);
6203         numpunct_char_truename(numpunct, &true_bstr);
6204         pfalse = MSVCP_basic_string_char_c_str(&false_bstr);
6205         ptrue = MSVCP_basic_string_char_c_str(&true_bstr);
6206
6207         for(istreambuf_iterator_char_val(&first); first.strbuf;
6208                 istreambuf_iterator_char_inc(&first)) {
6209             if(pfalse && *pfalse && first.val!=*pfalse)
6210                 pfalse = NULL;
6211             if(ptrue && *ptrue && first.val!=*ptrue)
6212                 ptrue = NULL;
6213
6214             if(pfalse && *pfalse && ptrue && !*ptrue)
6215                 ptrue = NULL;
6216             if(ptrue && *ptrue && pfalse && !*pfalse)
6217                 pfalse = NULL;
6218
6219             if(pfalse)
6220                 pfalse++;
6221             if(ptrue)
6222                 ptrue++;
6223
6224             if((!pfalse || !*pfalse) && (!ptrue || !*ptrue))
6225                 break;
6226         }
6227
6228         if(ptrue)
6229             *pval = TRUE;
6230         else if(pfalse)
6231             *pval = FALSE;
6232         else
6233             *state |= IOSTATE_failbit;
6234
6235         MSVCP_basic_string_char_dtor(&false_bstr);
6236         MSVCP_basic_string_char_dtor(&true_bstr);
6237     }else {
6238         char tmp[25], *end;
6239         int err;
6240         LONG v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
6241                     &first, &last, base->fmtfl, base->loc), &err);
6242
6243         if(end!=tmp && err==0 && (v==0 || v==1))
6244             *pval = v;
6245         else
6246             *state |= IOSTATE_failbit;
6247     }
6248
6249     if(!first.strbuf)
6250         *state |= IOSTATE_eofbit;
6251     memcpy(ret, &first, sizeof(first));
6252     return ret;
6253 }
6254
6255 /* ?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 */
6256 /* ?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 */
6257 DEFINE_THISCALL_WRAPPER(num_get_char_get_bool,36)
6258 istreambuf_iterator_char *__thiscall num_get_char_get_bool(const num_get *this, istreambuf_iterator_char *ret,
6259     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
6260 {
6261     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
6262     return call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval);
6263 }
6264
6265 /* ?id@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
6266 locale_id num_put_char_id = {0};
6267
6268 /* num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
6269 extern const vtable_ptr MSVCP_num_put_char_vtable;
6270
6271 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
6272 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
6273 DEFINE_THISCALL_WRAPPER(num_put_char__Init, 8)
6274 void __thiscall num_put_char__Init(num_put *this, const _Locinfo *locinfo)
6275 {
6276     TRACE("(%p %p)\n", this, locinfo);
6277     _Locinfo__Getcvt(locinfo, &this->cvt);
6278 }
6279
6280 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6281 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6282 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_locinfo, 12)
6283 num_put* __thiscall num_put_char_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6284 {
6285     TRACE("(%p %p %ld)\n", this, locinfo, refs);
6286
6287     locale_facet_ctor_refs(&this->facet, refs);
6288     this->facet.vtable = &MSVCP_num_put_char_vtable;
6289
6290     num_put_char__Init(this, locinfo);
6291     return this;
6292 }
6293
6294 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
6295 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
6296 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_refs, 8)
6297 num_put* __thiscall num_put_char_ctor_refs(num_put *this, MSVCP_size_t refs)
6298 {
6299      _Locinfo locinfo;
6300
6301      TRACE("(%p %lu)\n", this, refs);
6302
6303      _Locinfo_ctor(&locinfo);
6304      num_put_char_ctor_locinfo(this, &locinfo, refs);
6305      _Locinfo_dtor(&locinfo);
6306      return this;
6307 }
6308
6309 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
6310 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
6311 DEFINE_THISCALL_WRAPPER(num_put_char_ctor, 4)
6312 num_put* __thiscall num_put_char_ctor(num_put *this)
6313 {
6314     return num_put_char_ctor_refs(this, 0);
6315 }
6316
6317 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
6318 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
6319 DEFINE_THISCALL_WRAPPER(num_put_char_dtor, 4)
6320 void __thiscall num_put_char_dtor(num_put *this)
6321 {
6322     TRACE("(%p)\n", this);
6323     locale_facet_dtor(&this->facet);
6324 }
6325
6326 DEFINE_THISCALL_WRAPPER(MSVCP_num_put_char_vector_dtor, 8)
6327 num_put* __thiscall MSVCP_num_put_char_vector_dtor(num_put *this, unsigned int flags)
6328 {
6329     TRACE("(%p %x)\n", this, flags);
6330     if(flags & 2) {
6331         /* we have an array, with the number of elements stored before the first object */
6332         int i, *ptr = (int *)this-1;
6333
6334         for(i=*ptr-1; i>=0; i--)
6335             num_put_char_dtor(this+i);
6336         MSVCRT_operator_delete(ptr);
6337     } else {
6338         num_put_char_dtor(this);
6339         if(flags & 1)
6340             MSVCRT_operator_delete(this);
6341     }
6342
6343     return this;
6344 }
6345
6346 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
6347 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
6348 unsigned int __cdecl num_put_char__Getcat(const locale_facet **facet, const locale *loc)
6349 {
6350     TRACE("(%p %p)\n", facet, loc);
6351
6352     if(facet && !*facet) {
6353         _Locinfo locinfo;
6354
6355         *facet = MSVCRT_operator_new(sizeof(num_put));
6356         if(!*facet) {
6357             ERR("Out of memory\n");
6358             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6359             return 0;
6360         }
6361
6362         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
6363         num_put_char_ctor_locinfo((num_put*)*facet, &locinfo, 0);
6364         _Locinfo_dtor(&locinfo);
6365     }
6366
6367     return LC_NUMERIC;
6368 }
6369
6370 num_put* num_put_char_use_facet(const locale *loc)
6371 {
6372     static num_put *obj = NULL;
6373
6374     _Lockit lock;
6375     const locale_facet *fac;
6376
6377     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
6378     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_char_id));
6379     if(fac) {
6380         _Lockit_dtor(&lock);
6381         return (num_put*)fac;
6382     }
6383
6384     if(obj) {
6385         _Lockit_dtor(&lock);
6386         return obj;
6387     }
6388
6389     num_put_char__Getcat(&fac, loc);
6390     obj = (num_put*)fac;
6391     locale_facet__Incref(&obj->facet);
6392     locale_facet_register(&obj->facet);
6393     _Lockit_dtor(&lock);
6394
6395     return obj;
6396 }
6397
6398 /* ?_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 */
6399 /* ?_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 */
6400 ostreambuf_iterator_char* __cdecl num_put_char__Put(const num_put *this, ostreambuf_iterator_char *ret,
6401         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count)
6402 {
6403     TRACE("(%p %p %p %ld)\n", this, ret, ptr, count);
6404
6405     for(; count>0; count--)
6406         ostreambuf_iterator_char_put(&dest, *ptr++);
6407
6408     *ret = dest;
6409     return ret;
6410 }
6411
6412 /* ?_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 */
6413 /* ?_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 */
6414 ostreambuf_iterator_char* __cdecl num_put_char__Putc(const num_put *this, ostreambuf_iterator_char *ret,
6415         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count)
6416 {
6417     TRACE("(%p %p %p %ld)\n", this, ret, ptr, count);
6418
6419     for(; count>0; count--)
6420         ostreambuf_iterator_char_put(&dest, *ptr++);
6421
6422     *ret = dest;
6423     return ret;
6424 }
6425
6426 /* ?_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 */
6427 /* ?_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 */
6428 ostreambuf_iterator_char* __cdecl num_put_char__Putgrouped(const num_put *this, ostreambuf_iterator_char *ret,
6429         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count, char delim)
6430 {
6431     FIXME("(%p %p %p %ld %d) stub\n", this, ret, ptr, count, delim);
6432     return NULL;
6433 }
6434
6435 /* ?_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 */
6436 /* ?_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 */
6437 ostreambuf_iterator_char* __cdecl num_put_char__Rep(const num_put *this, ostreambuf_iterator_char *ret,
6438         ostreambuf_iterator_char dest, char c, MSVCP_size_t count)
6439 {
6440     TRACE("(%p %p %d %ld)\n", this, ret, c, count);
6441
6442     for(; count>0; count--)
6443         ostreambuf_iterator_char_put(&dest, c);
6444
6445     *ret = dest;
6446     return ret;
6447 }
6448
6449 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADDH@Z */
6450 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADDH@Z */
6451 char* __cdecl num_put_char__Ffmt(const num_put *this, char *fmt, char spec, int fmtfl)
6452 {
6453     int type = fmtfl & FMTFLAG_floatfield;
6454     char *p = fmt;
6455
6456     TRACE("(%p %p %d %d)\n", this, fmt, spec, fmtfl);
6457
6458     *p++ = '%';
6459     if(fmtfl & FMTFLAG_showpos)
6460         *p++ = '+';
6461     if(fmtfl & FMTFLAG_showbase)
6462         *p++ = '#';
6463     *p++ = '.';
6464     *p++ = '*';
6465     if(spec)
6466         *p++ = spec;
6467
6468     if(type == FMTFLAG_fixed)
6469         *p++ = 'f';
6470     else if(type == FMTFLAG_scientific)
6471         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'E' : 'e';
6472     else if(type == (FMTFLAG_fixed|FMTFLAG_scientific))
6473         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'A' : 'a';
6474     else
6475         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'G' : 'g';
6476
6477     *p++ = '\0';
6478     return fmt;
6479 }
6480
6481 /* ?_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 */
6482 /* ?_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 */
6483 ostreambuf_iterator_char* __cdecl num_put_char__Fput(const num_put *this, ostreambuf_iterator_char *ret,
6484         ostreambuf_iterator_char dest, ios_base *base, char fill, const char *buf, MSVCP_size_t bef_point,
6485         MSVCP_size_t aft_point, MSVCP_size_t trailing, MSVCP_size_t count)
6486 {
6487     FIXME("(%p %p %p %d %p %ld %ld %ld %ld) stub\n", this, ret, base,
6488             fill, buf, bef_point, aft_point, trailing, count);
6489     return NULL;
6490 }
6491
6492 /* TODO: This function should be removed when num_put_char__Fput is implemented */
6493 static ostreambuf_iterator_char* num_put_char_fput(const num_put *this, ostreambuf_iterator_char *ret,
6494         ostreambuf_iterator_char dest, ios_base *base, char fill, char *buf, MSVCP_size_t count)
6495 {
6496     numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6497     basic_string_char grouping_bstr;
6498     const char *grouping;
6499     char *p, sep = *localeconv()->decimal_point;
6500     int cur_group = 0, group_size = 0;
6501     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
6502     MSVCP_size_t pad;
6503
6504     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
6505
6506     /* Change decimal point */
6507     for(p=buf; p<buf+count; p++) {
6508         if(*p == sep) {
6509             *p = numpunct_char_decimal_point(numpunct);
6510             break;
6511         }
6512     }
6513     p--;
6514
6515     /* Add separators to number */
6516     numpunct_char_grouping(numpunct, &grouping_bstr);
6517     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
6518     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
6519
6520     for(; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
6521         group_size++;
6522         if(group_size == grouping[cur_group]) {
6523             group_size = 0;
6524             if(grouping[cur_group+1])
6525                 cur_group++;
6526
6527             memmove(p+1, p, buf+count-p);
6528             *p = sep;
6529             count++;
6530         }
6531     }
6532     MSVCP_basic_string_char_dtor(&grouping_bstr);
6533
6534     /* Display number with padding */
6535     if(count >= base->wide)
6536         pad = 0;
6537     else
6538         pad = base->wide-count;
6539     base->wide = 0;
6540
6541     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
6542         num_put_char__Putc(this, &dest, dest, buf, 1);
6543         buf++;
6544     }
6545     if(adjustfield != FMTFLAG_left) {
6546         num_put_char__Rep(this, ret, dest, fill, pad);
6547         pad = 0;
6548     }
6549     num_put_char__Putc(this, &dest, dest, buf, count);
6550     return num_put_char__Rep(this, ret, dest, fill, pad);
6551 }
6552
6553 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADPBDH@Z */
6554 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
6555 char* __cdecl num_put_char__Ifmt(const num_put *this, char *fmt, const char *spec, int fmtfl)
6556 {
6557     int base = fmtfl & FMTFLAG_basefield;
6558     char *p = fmt;
6559
6560     TRACE("(%p %p %p %d)\n", this, fmt, spec, fmtfl);
6561
6562     *p++ = '%';
6563     if(fmtfl & FMTFLAG_showpos)
6564         *p++ = '+';
6565     if(fmtfl & FMTFLAG_showbase)
6566         *p++ = '#';
6567
6568     *p++ = *spec++;
6569     if(*spec == 'l')
6570         *p++ = *spec++;
6571
6572     if(base == FMTFLAG_oct)
6573         *p++ = 'o';
6574     else if(base == FMTFLAG_hex)
6575         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'X' : 'x';
6576     else
6577         *p++ = *spec;
6578
6579     *p++ = '\0';
6580     return fmt;
6581 }
6582
6583 /* ?_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 */
6584 /* ?_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 */
6585 ostreambuf_iterator_char* __cdecl num_put_char__Iput(const num_put *this, ostreambuf_iterator_char *ret,
6586         ostreambuf_iterator_char dest, ios_base *base, char fill, char *buf, MSVCP_size_t count)
6587 {
6588     numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6589     basic_string_char grouping_bstr;
6590     const char *grouping;
6591     char *p, sep;
6592     int cur_group = 0, group_size = 0;
6593     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
6594     MSVCP_size_t pad;
6595
6596     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
6597
6598     /* Add separators to number */
6599     numpunct_char_grouping(numpunct, &grouping_bstr);
6600     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
6601     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
6602
6603     for(p=buf+count-1; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
6604         group_size++;
6605         if(group_size == grouping[cur_group]) {
6606             group_size = 0;
6607             if(grouping[cur_group+1])
6608                 cur_group++;
6609
6610             memmove(p+1, p, buf+count-p);
6611             *p = sep;
6612             count++;
6613         }
6614     }
6615     MSVCP_basic_string_char_dtor(&grouping_bstr);
6616
6617     /* Display number with padding */
6618     if(count >= base->wide)
6619         pad = 0;
6620     else
6621         pad = base->wide-count;
6622     base->wide = 0;
6623
6624     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
6625         num_put_char__Putc(this, &dest, dest, buf, 1);
6626         buf++;
6627     }else if((adjustfield & FMTFLAG_internal) && (buf[1]=='x' || buf[1]=='X')) {
6628         num_put_char__Putc(this, &dest, dest, buf, 2);
6629         buf += 2;
6630     }
6631     if(adjustfield != FMTFLAG_left) {
6632         num_put_char__Rep(this, ret, dest, fill, pad);
6633         pad = 0;
6634     }
6635     num_put_char__Putc(this, &dest, dest, buf, count);
6636     return num_put_char__Rep(this, ret, dest, fill, pad);
6637 }
6638
6639 /* ?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 */
6640 /* ?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 */
6641 #define call_num_put_char_do_put_long(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 28, ostreambuf_iterator_char*, \
6642         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, LONG), \
6643         (this, ret, dest, base, fill, v))
6644 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_long, 28)
6645 ostreambuf_iterator_char* __thiscall num_put_char_do_put_long(const num_put *this, ostreambuf_iterator_char *ret,
6646         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
6647 {
6648     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6649     char fmt[7]; /* strlen("%+#lld")+1 */
6650
6651     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6652
6653     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6654             sprintf(tmp, num_put_char__Ifmt(this, fmt, "ld", base->fmtfl), v));
6655 }
6656
6657 /* ?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 */
6658 /* ?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 */
6659 DEFINE_THISCALL_WRAPPER(num_put_char_put_long, 28)
6660 ostreambuf_iterator_char* __thiscall num_put_char_put_long(const num_put *this, ostreambuf_iterator_char *ret,
6661         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
6662 {
6663     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6664     return call_num_put_char_do_put_long(this, ret, dest, base, fill, v);
6665 }
6666
6667 /* ?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 */
6668 /* ?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 */
6669 #define call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 24, ostreambuf_iterator_char*, \
6670         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, ULONG), \
6671         (this, ret, dest, base, fill, v))
6672 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ulong, 28)
6673 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
6674         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
6675 {
6676     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6677     char fmt[7]; /* strlen("%+#lld")+1 */
6678
6679     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6680
6681     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6682             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lu", base->fmtfl), v));
6683 }
6684
6685 /* ?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 */
6686 /* ?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 */
6687 DEFINE_THISCALL_WRAPPER(num_put_char_put_ulong, 28)
6688 ostreambuf_iterator_char* __thiscall num_put_char_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
6689         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
6690 {
6691     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6692     return call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v);
6693 }
6694
6695 /* ?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 */
6696 /* ?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 */
6697 /* ?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 */
6698 /* ?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 */
6699 #define call_num_put_char_do_put_double(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 12, ostreambuf_iterator_char*, \
6700         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
6701         (this, ret, dest, base, fill, v))
6702 #define call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 8, ostreambuf_iterator_char*, \
6703         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
6704         (this, ret, dest, base, fill, v))
6705 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_double, 32)
6706 ostreambuf_iterator_char* __thiscall num_put_char_do_put_double(const num_put *this, ostreambuf_iterator_char *ret,
6707         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6708 {
6709     char *tmp;
6710     char fmt[8]; /* strlen("%+#.*lg")+1 */
6711     int size;
6712
6713     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6714
6715     num_put_char__Ffmt(this, fmt, '\0', base->fmtfl);
6716     size = _scprintf(fmt, base->prec, v);
6717
6718     /* TODO: don't use dynamic allocation */
6719     tmp = MSVCRT_operator_new(size*2);
6720     if(!tmp) {
6721         ERR("Out of memory\n");
6722         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6723     }
6724     num_put_char_fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, base->prec, v));
6725     MSVCRT_operator_delete(tmp);
6726     return ret;
6727 }
6728
6729 /* ?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 */
6730 /* ?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 */
6731 DEFINE_THISCALL_WRAPPER(num_put_char_put_double, 32)
6732 ostreambuf_iterator_char* __thiscall num_put_char_put_double(const num_put *this, ostreambuf_iterator_char *ret,
6733         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6734 {
6735     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6736     return call_num_put_char_do_put_double(this, ret, dest, base, fill, v);
6737 }
6738
6739 /* ?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 */
6740 /* ?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 */
6741 DEFINE_THISCALL_WRAPPER(num_put_char_put_ldouble, 32)
6742 ostreambuf_iterator_char* __thiscall num_put_char_put_ldouble(const num_put *this, ostreambuf_iterator_char *ret,
6743         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6744 {
6745     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6746     return call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v);
6747 }
6748
6749 /* ?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 */
6750 /* ?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 */
6751 #define call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 4, ostreambuf_iterator_char*, \
6752         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, const void*), \
6753         (this, ret, dest, base, fill, v))
6754 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ptr, 28)
6755 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
6756         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
6757 {
6758     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
6759
6760     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
6761
6762     return num_put_char__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
6763 }
6764
6765 /* ?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 */
6766 /* ?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 */
6767 DEFINE_THISCALL_WRAPPER(num_put_char_put_ptr, 28)
6768 ostreambuf_iterator_char* __thiscall num_put_char_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
6769         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
6770 {
6771     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
6772     return call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v);
6773 }
6774
6775 /* ?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 */
6776 /* ?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 */
6777 #define call_num_put_char_do_put_int64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 20, ostreambuf_iterator_char*, \
6778         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, __int64), \
6779         (this, ret, dest, base, fill, v))
6780 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_int64, 32)
6781 ostreambuf_iterator_char* __thiscall num_put_char_do_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
6782         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
6783 {
6784     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6785     char fmt[7]; /* strlen("%+#lld")+1 */
6786
6787     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6788
6789     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6790             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lld", base->fmtfl), v));
6791 }
6792
6793 /* ?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 */
6794 /* ?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 */
6795 DEFINE_THISCALL_WRAPPER(num_put_char_put_int64, 32)
6796 ostreambuf_iterator_char* __thiscall num_put_char_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
6797         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
6798 {
6799     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6800     return call_num_put_char_do_put_int64(this, ret, dest, base, fill, v);
6801 }
6802
6803 /* ?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 */
6804 /* ?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 */
6805 #define call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 16, ostreambuf_iterator_char*, \
6806         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, unsigned __int64), \
6807         (this, ret, dest, base, fill, v))
6808 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_uint64, 32)
6809 ostreambuf_iterator_char* __thiscall num_put_char_do_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
6810         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
6811 {
6812     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6813     char fmt[7]; /* strlen("%+#lld")+1 */
6814
6815     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6816
6817     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6818             sprintf(tmp, num_put_char__Ifmt(this, fmt, "llu", base->fmtfl), v));
6819 }
6820
6821 /* ?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 */
6822 /* ?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 */
6823 DEFINE_THISCALL_WRAPPER(num_put_char_put_uint64, 32)
6824 ostreambuf_iterator_char* __thiscall num_put_char_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
6825         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
6826 {
6827     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6828     return call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v);
6829 }
6830
6831 /* ?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 */
6832 /* ?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 */
6833 #define call_num_put_char_do_put_bool(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 32, ostreambuf_iterator_char*, \
6834         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, MSVCP_bool), \
6835         (this, ret, dest, base, fill, v))
6836 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_bool, 28)
6837 ostreambuf_iterator_char* __thiscall num_put_char_do_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
6838         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
6839 {
6840     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6841
6842     if(base->fmtfl & FMTFLAG_boolalpha) {
6843         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6844         basic_string_char str;
6845         MSVCP_size_t pad, len;
6846
6847         if(v)
6848             numpunct_char_truename(numpunct, &str);
6849         else
6850             numpunct_char_falsename(numpunct, &str);
6851
6852         len = MSVCP_basic_string_char_length(&str);
6853         pad = (len>base->wide ? 0 : base->wide-len);
6854         base->wide = 0;
6855
6856         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
6857             num_put_char__Rep(this, &dest, dest, fill, pad);
6858             pad = 0;
6859         }
6860         num_put_char__Putc(this, &dest, dest, MSVCP_basic_string_char_c_str(&str), len);
6861         MSVCP_basic_string_char_dtor(&str);
6862         return num_put_char__Rep(this, ret, dest, fill, pad);
6863     }
6864
6865     return num_put_char_put_long(this, ret, dest, base, fill, v);
6866 }
6867
6868 /* ?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 */
6869 /* ?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 */
6870 DEFINE_THISCALL_WRAPPER(num_put_char_put_bool, 28)
6871 ostreambuf_iterator_char* __thiscall num_put_char_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
6872         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
6873 {
6874     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6875     return call_num_put_char_do_put_bool(this, ret, dest, base, fill, v);
6876 }
6877
6878 /* ?id@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
6879 locale_id num_put_wchar_id = {0};
6880 /* ?id@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@2V0locale@2@A */
6881 locale_id num_put_short_id = {0};
6882
6883 /* num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
6884 extern const vtable_ptr MSVCP_num_put_wchar_vtable;
6885 /* num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@6B@ */
6886 extern const vtable_ptr MSVCP_num_put_short_vtable;
6887
6888 /* ?_Init@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
6889 /* ?_Init@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
6890 DEFINE_THISCALL_WRAPPER(num_put_wchar__Init, 8)
6891 void __thiscall num_put_wchar__Init(num_put *this, const _Locinfo *locinfo)
6892 {
6893     TRACE("(%p %p)\n", this, locinfo);
6894     _Locinfo__Getcvt(locinfo, &this->cvt);
6895 }
6896
6897 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6898 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6899 DEFINE_THISCALL_WRAPPER(num_put_wchar_ctor_locinfo, 12)
6900 num_put* __thiscall num_put_wchar_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6901 {
6902     TRACE("(%p %p %ld)\n", this, locinfo, refs);
6903
6904     locale_facet_ctor_refs(&this->facet, refs);
6905     this->facet.vtable = &MSVCP_num_put_wchar_vtable;
6906
6907     num_put_wchar__Init(this, locinfo);
6908     return this;
6909 }
6910
6911 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6912 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6913 DEFINE_THISCALL_WRAPPER(num_put_short_ctor_locinfo, 12)
6914 num_put* __thiscall num_put_short_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6915 {
6916     num_put_wchar_ctor_locinfo(this, locinfo, refs);
6917     this->facet.vtable = &MSVCP_num_put_short_vtable;
6918     return this;
6919 }
6920
6921 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
6922 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
6923 DEFINE_THISCALL_WRAPPER(num_put_wchar_ctor_refs, 8)
6924 num_put* __thiscall num_put_wchar_ctor_refs(num_put *this, MSVCP_size_t refs)
6925 {
6926     _Locinfo locinfo;
6927
6928     TRACE("(%p %lu)\n", this, refs);
6929
6930     _Locinfo_ctor(&locinfo);
6931     num_put_wchar_ctor_locinfo(this, &locinfo, refs);
6932     _Locinfo_dtor(&locinfo);
6933     return this;
6934 }
6935
6936 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@I@Z */
6937 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@_K@Z */
6938 DEFINE_THISCALL_WRAPPER(num_put_short_ctor_refs, 8)
6939 num_put* __thiscall num_put_short_ctor_refs(num_put *this, MSVCP_size_t refs)
6940 {
6941     num_put_wchar_ctor_refs(this, refs);
6942     this->facet.vtable = &MSVCP_num_put_short_vtable;
6943     return this;
6944 }
6945
6946 /* ??_F?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
6947 /* ??_F?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
6948 DEFINE_THISCALL_WRAPPER(num_put_wchar_ctor, 4)
6949 num_put* __thiscall num_put_wchar_ctor(num_put *this)
6950 {
6951     return num_put_wchar_ctor_refs(this, 0);
6952 }
6953
6954 /* ??_F?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAEXXZ */
6955 /* ??_F?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAAXXZ */
6956 DEFINE_THISCALL_WRAPPER(num_put_short_ctor, 4)
6957 num_put* __thiscall num_put_short_ctor(num_put *this)
6958 {
6959     return num_put_short_ctor_refs(this, 0);
6960 }
6961
6962 /* ??1?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
6963 /* ??1?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
6964 /* ??1?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MAE@XZ */
6965 /* ??1?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEAA@XZ */
6966 DEFINE_THISCALL_WRAPPER(num_put_wchar_dtor, 4)
6967 void __thiscall num_put_wchar_dtor(num_put *this)
6968 {
6969     TRACE("(%p)\n", this);
6970     locale_facet_dtor(&this->facet);
6971 }
6972
6973 DEFINE_THISCALL_WRAPPER(MSVCP_num_put_wchar_vector_dtor, 8)
6974 num_put* __thiscall MSVCP_num_put_wchar_vector_dtor(num_put *this, unsigned int flags)
6975 {
6976     TRACE("(%p %x)\n", this, flags);
6977     if(flags & 2) {
6978         /* we have an array, with the number of elements stored before the first object */
6979         int i, *ptr = (int *)this-1;
6980
6981         for(i=*ptr-1; i>=0; i--)
6982             num_put_wchar_dtor(this+i);
6983         MSVCRT_operator_delete(ptr);
6984     } else {
6985         num_put_wchar_dtor(this);
6986         if(flags & 1)
6987             MSVCRT_operator_delete(this);
6988     }
6989
6990     return this;
6991 }
6992
6993 DEFINE_THISCALL_WRAPPER(MSVCP_num_put_short_vector_dtor, 8)
6994 num_put* __thiscall MSVCP_num_put_short_vector_dtor(num_put *this, unsigned int flags)
6995 {
6996     return MSVCP_num_put_wchar_vector_dtor(this, flags);
6997 }
6998
6999 /* ?_Getcat@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
7000 /* ?_Getcat@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
7001 unsigned int __cdecl num_put_wchar__Getcat(const locale_facet **facet, const locale *loc)
7002 {
7003     TRACE("(%p %p)\n", facet, loc);
7004
7005     if(facet && !*facet) {
7006         _Locinfo locinfo;
7007
7008         *facet = MSVCRT_operator_new(sizeof(num_put));
7009         if(!*facet) {
7010             ERR("Out of memory\n");
7011             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7012             return 0;
7013         }
7014
7015         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
7016         num_put_wchar_ctor_locinfo((num_put*)*facet, &locinfo, 0);
7017         _Locinfo_dtor(&locinfo);
7018     }
7019
7020     return LC_NUMERIC;
7021 }
7022
7023 /* ?_Getcat@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
7024 /* ?_Getcat@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
7025 unsigned int __cdecl num_put_short__Getcat(const locale_facet **facet, const locale *loc)
7026 {
7027     TRACE("(%p %p)\n", facet, loc);
7028
7029     if(facet && !*facet) {
7030         _Locinfo locinfo;
7031
7032         *facet = MSVCRT_operator_new(sizeof(num_put));
7033         if(!*facet) {
7034             ERR("Out of memory\n");
7035             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7036             return 0;
7037         }
7038
7039         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
7040         num_put_short_ctor_locinfo((num_put*)*facet, &locinfo, 0);
7041         _Locinfo_dtor(&locinfo);
7042     }
7043
7044     return LC_NUMERIC;
7045 }
7046
7047 num_put* num_put_wchar_use_facet(const locale *loc)
7048 {
7049     static num_put *obj = NULL;
7050
7051     _Lockit lock;
7052     const locale_facet *fac;
7053
7054     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7055     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_wchar_id));
7056     if(fac) {
7057         _Lockit_dtor(&lock);
7058         return (num_put*)fac;
7059     }
7060
7061     if(obj) {
7062         _Lockit_dtor(&lock);
7063         return obj;
7064     }
7065
7066     num_put_wchar__Getcat(&fac, loc);
7067     obj = (num_put*)fac;
7068     locale_facet__Incref(&obj->facet);
7069     locale_facet_register(&obj->facet);
7070     _Lockit_dtor(&lock);
7071
7072     return obj;
7073 }
7074
7075 static num_put* num_put_short_use_facet(const locale *loc)
7076 {
7077     static num_put *obj = NULL;
7078
7079     _Lockit lock;
7080     const locale_facet *fac;
7081
7082     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7083     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_short_id));
7084     if(fac) {
7085         _Lockit_dtor(&lock);
7086         return (num_put*)fac;
7087     }
7088
7089     if(obj) {
7090         _Lockit_dtor(&lock);
7091         return obj;
7092     }
7093
7094     num_put_short__Getcat(&fac, loc);
7095     obj = (num_put*)fac;
7096     locale_facet__Incref(&obj->facet);
7097     locale_facet_register(&obj->facet);
7098     _Lockit_dtor(&lock);
7099
7100     return obj;
7101 }
7102
7103 /* ?_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 */
7104 /* ?_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 */
7105 /* ?_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 */
7106 /* ?_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 */
7107 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Put(const num_put *this, ostreambuf_iterator_wchar *ret,
7108         ostreambuf_iterator_wchar dest, const wchar_t *ptr, MSVCP_size_t count)
7109 {
7110     TRACE("(%p %p %s %ld)\n", this, ret, debugstr_wn(ptr, count), count);
7111
7112     for(; count>0; count--)
7113         ostreambuf_iterator_wchar_put(&dest, *ptr++);
7114
7115     *ret = dest;
7116     return ret;
7117 }
7118
7119 /* ?_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 */
7120 /* ?_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 */
7121 /* ?_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 */
7122 /* ?_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 */
7123 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Putc(const num_put *this, ostreambuf_iterator_wchar *ret,
7124         ostreambuf_iterator_wchar dest, const char *ptr, MSVCP_size_t count)
7125 {
7126     int state = 0;
7127     wchar_t ch;
7128
7129     TRACE("(%p %p %s %ld)\n", this, ret, debugstr_an(ptr, count), count);
7130
7131     for(; count>0; count--) {
7132         if(_Mbrtowc(&ch, ptr++, 1, &state, &this->cvt) == 1)
7133             ostreambuf_iterator_wchar_put(&dest, ch);
7134     }
7135
7136     *ret = dest;
7137     return ret;
7138 }
7139
7140 /* ?_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 */
7141 /* ?_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 */
7142 /* ?_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 */
7143 /* ?_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 */
7144 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Putgrouped(const num_put *this, ostreambuf_iterator_wchar *ret,
7145         ostreambuf_iterator_wchar dest, const char *ptr, MSVCP_size_t count, wchar_t delim)
7146 {
7147     FIXME("(%p %p %p %ld %d) stub\n", this, ret, ptr, count, delim);
7148     return NULL;
7149 }
7150
7151 /* ?_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 */
7152 /* ?_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 */
7153 /* ?_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 */
7154 /* ?_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 */
7155 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Rep(const num_put *this, ostreambuf_iterator_wchar *ret,
7156         ostreambuf_iterator_wchar dest, wchar_t c, MSVCP_size_t count)
7157 {
7158     TRACE("(%p %p %d %ld)\n", this, ret, c, count);
7159
7160     for(; count>0; count--)
7161         ostreambuf_iterator_wchar_put(&dest, c);
7162
7163     *ret = dest;
7164     return ret;
7165 }
7166
7167 /* ?_Ffmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAPADPADDH@Z */
7168 /* ?_Ffmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAPEADPEADDH@Z */
7169 /* ?_Ffmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAPADPADDH@Z */
7170 /* ?_Ffmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAPEADPEADDH@Z */
7171 char* __cdecl num_put_wchar__Ffmt(const num_put *this, char *fmt, char spec, int fmtfl)
7172 {
7173     int type = fmtfl & FMTFLAG_floatfield;
7174     char *p = fmt;
7175
7176     TRACE("(%p %p %d %d)\n", this, fmt, spec, fmtfl);
7177
7178     *p++ = '%';
7179     if(fmtfl & FMTFLAG_showpos)
7180         *p++ = '+';
7181     if(fmtfl & FMTFLAG_showbase)
7182         *p++ = '#';
7183     *p++ = '.';
7184     *p++ = '*';
7185     if(spec)
7186         *p++ = spec;
7187
7188     if(type == FMTFLAG_fixed)
7189         *p++ = 'f';
7190     else if(type == FMTFLAG_scientific)
7191         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'E' : 'e';
7192     else if(type == (FMTFLAG_fixed|FMTFLAG_scientific))
7193         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'A' : 'a';
7194     else
7195         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'G' : 'g';
7196
7197     *p++ = '\0';
7198     return fmt;
7199 }
7200
7201 /* ?_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 */
7202 /* ?_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 */
7203 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Fput(const num_put *this, ostreambuf_iterator_wchar *ret,
7204         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const char *buf, MSVCP_size_t bef_point,
7205         MSVCP_size_t aft_point, MSVCP_size_t trailing, MSVCP_size_t count)
7206 {
7207     FIXME("(%p %p %p %d %p %ld %ld %ld %ld) stub\n", this, ret, base,
7208             fill, buf, bef_point, aft_point, trailing, count);
7209     return NULL;
7210 }
7211
7212 /* ?_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 */
7213 /* ?_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 */
7214 ostreambuf_iterator_wchar* __cdecl num_put_short__Fput(const num_put *this, ostreambuf_iterator_wchar *ret,
7215         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const char *buf, MSVCP_size_t bef_point,
7216         MSVCP_size_t aft_point, MSVCP_size_t trailing, MSVCP_size_t count)
7217 {
7218     FIXME("(%p %p %p %d %p %ld %ld %ld %ld) stub\n", this, ret, base,
7219             fill, buf, bef_point, aft_point, trailing, count);
7220     return NULL;
7221 }
7222
7223 /* TODO: This function should be removed when num_put_wchar__Fput is implemented */
7224 static ostreambuf_iterator_wchar* num_put__fput(const num_put *this, ostreambuf_iterator_wchar *ret,
7225         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf,
7226         MSVCP_size_t count, numpunct_wchar *numpunct)
7227 {
7228     basic_string_char grouping_bstr;
7229     const char *grouping;
7230     char *p, dec_point = *localeconv()->decimal_point;
7231     wchar_t sep;
7232     int cur_group = 0, group_size = 0;
7233     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
7234     MSVCP_size_t i, pad;
7235
7236     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
7237
7238     for(p=buf; p<buf+count; p++) {
7239         if(*p == dec_point)
7240             break;
7241     }
7242     p--;
7243
7244     /* Add separators to number */
7245     numpunct_wchar_grouping(numpunct, &grouping_bstr);
7246     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
7247     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
7248
7249     for(; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
7250         group_size++;
7251         if(group_size == grouping[cur_group]) {
7252             group_size = 0;
7253             if(grouping[cur_group+1])
7254                 cur_group++;
7255
7256             memmove(p+1, p, buf+count-p);
7257             *p = '\0'; /* mark thousands separator positions */
7258             count++;
7259         }
7260     }
7261     MSVCP_basic_string_char_dtor(&grouping_bstr);
7262
7263     /* Display number with padding */
7264     if(count >= base->wide)
7265         pad = 0;
7266     else
7267         pad = base->wide-count;
7268     base->wide = 0;
7269
7270     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
7271         num_put_wchar__Putc(this, &dest, dest, buf, 1);
7272         buf++;
7273     }
7274     if(adjustfield != FMTFLAG_left) {
7275         num_put_wchar__Rep(this, ret, dest, fill, pad);
7276         pad = 0;
7277     }
7278
7279     for(i=0; i<count; i++) {
7280         if(buf[i] == dec_point)
7281             num_put_wchar__Rep(this, &dest, dest, numpunct_wchar_decimal_point(numpunct), 1);
7282         else if(!buf[i])
7283             num_put_wchar__Rep(this, &dest, dest, sep, 1);
7284         else
7285             num_put_wchar__Putc(this, &dest, dest, buf+i, 1);
7286     }
7287
7288     return num_put_wchar__Rep(this, ret, dest, fill, pad);
7289 }
7290
7291 /* ?_Ifmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAPADPADPBDH@Z */
7292 /* ?_Ifmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
7293 /* ?_Ifmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAPADPADPBDH@Z */
7294 /* ?_Ifmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
7295 char* __cdecl num_put_wchar__Ifmt(const num_put *this, char *fmt, const char *spec, int fmtfl)
7296 {
7297     int base = fmtfl & FMTFLAG_basefield;
7298     char *p = fmt;
7299
7300     TRACE("(%p %p %p %d)\n", this, fmt, spec, fmtfl);
7301
7302     *p++ = '%';
7303     if(fmtfl & FMTFLAG_showpos)
7304         *p++ = '+';
7305     if(fmtfl & FMTFLAG_showbase)
7306         *p++ = '#';
7307
7308     *p++ = *spec++;
7309     if(*spec == 'l')
7310         *p++ = *spec++;
7311
7312     if(base == FMTFLAG_oct)
7313         *p++ = 'o';
7314     else if(base == FMTFLAG_hex)
7315         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'X' : 'x';
7316     else
7317         *p++ = *spec;
7318
7319     *p++ = '\0';
7320     return fmt;
7321 }
7322
7323 ostreambuf_iterator_wchar* __cdecl num_put__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
7324         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf,
7325         MSVCP_size_t count, numpunct_wchar *numpunct)
7326 {
7327     basic_string_char grouping_bstr;
7328     const char *grouping;
7329     char *p;
7330     wchar_t sep;
7331     int cur_group = 0, group_size = 0;
7332     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
7333     MSVCP_size_t i, pad;
7334
7335     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
7336
7337     /* Add separators to number */
7338     numpunct_wchar_grouping(numpunct, &grouping_bstr);
7339     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
7340     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
7341
7342     for(p=buf+count-1; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
7343         group_size++;
7344         if(group_size == grouping[cur_group]) {
7345             group_size = 0;
7346             if(grouping[cur_group+1])
7347                 cur_group++;
7348
7349             memmove(p+1, p, buf+count-p);
7350             *p = '\0'; /* mark thousands separator positions */
7351             count++;
7352         }
7353     }
7354     MSVCP_basic_string_char_dtor(&grouping_bstr);
7355
7356     /* Display number with padding */
7357     if(count >= base->wide)
7358         pad = 0;
7359     else
7360         pad = base->wide-count;
7361     base->wide = 0;
7362
7363     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
7364         num_put_wchar__Putc(this, &dest, dest, buf, 1);
7365         buf++;
7366     }else if((adjustfield & FMTFLAG_internal) && (buf[1]=='x' || buf[1]=='X')) {
7367         num_put_wchar__Putc(this, &dest, dest, buf, 2);
7368         buf += 2;
7369     }
7370     if(adjustfield != FMTFLAG_left) {
7371         num_put_wchar__Rep(this, ret, dest, fill, pad);
7372         pad = 0;
7373     }
7374
7375     for(i=0; i<count; i++) {
7376         if(!buf[i])
7377             num_put_wchar__Rep(this, &dest, dest, sep, 1);
7378         else
7379             num_put_wchar__Putc(this, &dest, dest, buf+i, 1);
7380     }
7381
7382     return num_put_wchar__Rep(this, ret, dest, fill, pad);
7383 }
7384
7385 /* ?_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 */
7386 /* ?_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 */
7387 ostreambuf_iterator_wchar* __cdecl num_put_wchar__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
7388         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf, MSVCP_size_t count)
7389 {
7390     return num_put__Iput(this, ret, dest, base, fill, buf, count, numpunct_wchar_use_facet(base->loc));
7391 }
7392
7393 /* ?_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 */
7394 /* ?_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 */
7395 ostreambuf_iterator_wchar* __cdecl num_put_short__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
7396         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf, MSVCP_size_t count)
7397 {
7398     return num_put__Iput(this, ret, dest, base, fill, buf, count, numpunct_short_use_facet(base->loc));
7399 }
7400
7401 /* ?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 */
7402 /* ?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 */
7403 #define call_num_put_wchar_do_put_long(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 28, ostreambuf_iterator_wchar*, \
7404         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, LONG), \
7405         (this, ret, dest, base, fill, v))
7406 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_long, 28)
7407 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
7408         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
7409 {
7410     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7411     char fmt[7]; /* strlen("%+#lld")+1 */
7412
7413     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7414
7415     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7416             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "ld", base->fmtfl), v));
7417 }
7418
7419 /* ?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 */
7420 /* ?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 */
7421 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_long, 28)
7422 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
7423         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
7424 {
7425     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7426     char fmt[7]; /* strlen("%+#lld")+1 */
7427
7428     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7429
7430     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7431             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "ld", base->fmtfl), v));
7432 }
7433
7434 /* ?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 */
7435 /* ?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 */
7436 /* ?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 */
7437 /* ?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 */
7438 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_long, 28)
7439 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
7440         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
7441 {
7442     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7443     return call_num_put_wchar_do_put_long(this, ret, dest, base, fill, v);
7444 }
7445
7446 /* ?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 */
7447 /* ?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 */
7448 #define call_num_put_wchar_do_put_ulong(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 24, ostreambuf_iterator_wchar*, \
7449         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, ULONG), \
7450         (this, ret, dest, base, fill, v))
7451 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_ulong, 28)
7452 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
7453         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
7454 {
7455     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7456     char fmt[7]; /* strlen("%+#lld")+1 */
7457
7458     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7459
7460     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7461             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lu", base->fmtfl), v));
7462 }
7463
7464 /* ?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 */
7465 /* ?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 */
7466 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_ulong, 28)
7467 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
7468         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
7469 {
7470     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7471     char fmt[7]; /* strlen("%+#lld")+1 */
7472
7473     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7474
7475     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7476             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lu", base->fmtfl), v));
7477 }
7478
7479 /* ?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 */
7480 /* ?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 */
7481 /* ?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 */
7482 /* ?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 */
7483 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ulong, 28)
7484 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
7485         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
7486 {
7487     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7488     return call_num_put_wchar_do_put_ulong(this, ret, dest, base, fill, v);
7489 }
7490
7491 /* ?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 */
7492 /* ?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 */
7493 /* ?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 */
7494 /* ?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 */
7495 #define call_num_put_wchar_do_put_double(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 12, ostreambuf_iterator_wchar*, \
7496         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, double), \
7497         (this, ret, dest, base, fill, v))
7498 #define call_num_put_wchar_do_put_ldouble(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 8, ostreambuf_iterator_wchar*, \
7499         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, double), \
7500         (this, ret, dest, base, fill, v))
7501 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_double, 32)
7502 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
7503         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7504 {
7505     char *tmp;
7506     char fmt[8]; /* strlen("%+#.*lg")+1 */
7507     int size;
7508
7509     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7510
7511     num_put_wchar__Ffmt(this, fmt, '\0', base->fmtfl);
7512     size = _scprintf(fmt, base->prec, v);
7513
7514     /* TODO: don't use dynamic allocation */
7515     tmp = MSVCRT_operator_new(size*2);
7516     if(!tmp) {
7517         ERR("Out of memory\n");
7518         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7519     }
7520     num_put__fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, base->prec, v),
7521             numpunct_wchar_use_facet(base->loc));
7522     MSVCRT_operator_delete(tmp);
7523     return ret;
7524 }
7525
7526 /* ?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 */
7527 /* ?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 */
7528 /* ?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 */
7529 /* ?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 */
7530 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_double, 32)
7531 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
7532         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7533 {
7534     char *tmp;
7535     char fmt[8]; /* strlen("%+#.*lg")+1 */
7536     int size;
7537
7538     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7539
7540     num_put_wchar__Ffmt(this, fmt, '\0', base->fmtfl);
7541     size = _scprintf(fmt, base->prec, v);
7542
7543     /* TODO: don't use dynamic allocation */
7544     tmp = MSVCRT_operator_new(size*2);
7545     if(!tmp) {
7546         ERR("Out of memory\n");
7547         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7548     }
7549     num_put__fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, base->prec, v),
7550             numpunct_short_use_facet(base->loc));
7551     MSVCRT_operator_delete(tmp);
7552     return ret;
7553 }
7554
7555 /* ?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 */
7556 /* ?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 */
7557 /* ?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 */
7558 /* ?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 */
7559 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_double, 32)
7560 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
7561         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7562 {
7563     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7564     return call_num_put_wchar_do_put_double(this, ret, dest, base, fill, v);
7565 }
7566
7567 /* ?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 */
7568 /* ?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 */
7569 /* ?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 */
7570 /* ?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 */
7571 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ldouble, 32)
7572 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ldouble(const num_put *this, ostreambuf_iterator_wchar *ret,
7573         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
7574 {
7575     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
7576     return call_num_put_wchar_do_put_ldouble(this, ret, dest, base, fill, v);
7577 }
7578
7579 /* ?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 */
7580 /* ?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 */
7581 #define call_num_put_wchar_do_put_ptr(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 4, ostreambuf_iterator_wchar*, \
7582         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, const void*), \
7583         (this, ret, dest, base, fill, v))
7584 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_ptr, 28)
7585 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
7586         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
7587 {
7588     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
7589
7590     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7591
7592     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
7593 }
7594
7595 /* ?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 */
7596 /* ?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 */
7597 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_ptr, 28)
7598 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
7599         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
7600 {
7601     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
7602
7603     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7604
7605     return num_put_short__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
7606 }
7607
7608 /* ?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 */
7609 /* ?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 */
7610 /* ?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 */
7611 /* ?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 */
7612 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ptr, 28)
7613 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
7614         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
7615 {
7616     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7617     return call_num_put_wchar_do_put_ptr(this, ret, dest, base, fill, v);
7618 }
7619
7620 /* ?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 */
7621 /* ?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 */
7622 #define call_num_put_wchar_do_put_int64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 20, ostreambuf_iterator_wchar*, \
7623         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, __int64), \
7624         (this, ret, dest, base, fill, v))
7625 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_int64, 32)
7626 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7627         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7628 {
7629     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7630     char fmt[7]; /* strlen("%+#lld")+1 */
7631
7632     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7633
7634     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7635             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lld", base->fmtfl), v));
7636 }
7637
7638 /* ?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 */
7639 /* ?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 */
7640 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_int64, 32)
7641 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7642         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7643 {
7644     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7645     char fmt[7]; /* strlen("%+#lld")+1 */
7646
7647     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7648
7649     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7650             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lld", base->fmtfl), v));
7651 }
7652
7653 /* ?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 */
7654 /* ?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 */
7655 /* ?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 */
7656 /* ?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 */
7657 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_int64, 32)
7658 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7659         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7660 {
7661     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7662     return call_num_put_wchar_do_put_int64(this, ret, dest, base, fill, v);
7663 }
7664
7665 /* ?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 */
7666 /* ?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 */
7667 #define call_num_put_wchar_do_put_uint64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 16, ostreambuf_iterator_wchar*, \
7668         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, unsigned __int64), \
7669         (this, ret, dest, base, fill, v))
7670 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_uint64, 32)
7671 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7672         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7673 {
7674     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7675     char fmt[7]; /* strlen("%+#lld")+1 */
7676
7677     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7678
7679     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7680             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "llu", base->fmtfl), v));
7681 }
7682
7683 /* ?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 */
7684 /* ?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 */
7685 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_uint64, 32)
7686 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7687         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7688 {
7689     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7690     char fmt[7]; /* strlen("%+#lld")+1 */
7691
7692     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7693
7694     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7695             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "llu", base->fmtfl), v));
7696 }
7697
7698 /* ?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 */
7699 /* ?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 */
7700 /* ?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 */
7701 /* ?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 */
7702 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_uint64, 32)
7703 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7704         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7705 {
7706     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7707     return call_num_put_wchar_do_put_uint64(this, ret, dest, base, fill, v);
7708 }
7709
7710 /* ?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 */
7711 /* ?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 */
7712 #define call_num_put_wchar_do_put_bool(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 32, ostreambuf_iterator_wchar*, \
7713         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, MSVCP_bool), \
7714         (this, ret, dest, base, fill, v))
7715 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_bool, 28)
7716 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7717         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7718 {
7719     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7720
7721     if(base->fmtfl & FMTFLAG_boolalpha) {
7722         numpunct_wchar *numpunct = numpunct_wchar_use_facet(base->loc);
7723         basic_string_wchar str;
7724         MSVCP_size_t pad, len;
7725
7726         if(v)
7727             numpunct_wchar_truename(numpunct, &str);
7728         else
7729             numpunct_wchar_falsename(numpunct, &str);
7730
7731         len = MSVCP_basic_string_wchar_length(&str);
7732         pad = (len>base->wide ? 0 : base->wide-len);
7733         base->wide = 0;
7734
7735         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
7736             num_put_wchar__Rep(this, &dest, dest, fill, pad);
7737             pad = 0;
7738         }
7739         num_put_wchar__Put(this, &dest, dest, MSVCP_basic_string_wchar_c_str(&str), len);
7740         MSVCP_basic_string_wchar_dtor(&str);
7741         return num_put_wchar__Rep(this, ret, dest, fill, pad);
7742     }
7743
7744     return num_put_wchar_put_long(this, ret, dest, base, fill, v);
7745 }
7746
7747 /* ?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 */
7748 /* ?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 */
7749 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_bool, 28)
7750 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7751         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7752 {
7753     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7754
7755     if(base->fmtfl & FMTFLAG_boolalpha) {
7756         numpunct_wchar *numpunct = numpunct_short_use_facet(base->loc);
7757         basic_string_wchar str;
7758         MSVCP_size_t pad, len;
7759
7760         if(v)
7761             numpunct_wchar_truename(numpunct, &str);
7762         else
7763             numpunct_wchar_falsename(numpunct, &str);
7764
7765         len = MSVCP_basic_string_wchar_length(&str);
7766         pad = (len>base->wide ? 0 : base->wide-len);
7767         base->wide = 0;
7768
7769         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
7770             num_put_wchar__Rep(this, &dest, dest, fill, pad);
7771             pad = 0;
7772         }
7773         num_put_wchar__Put(this, &dest, dest, MSVCP_basic_string_wchar_c_str(&str), len);
7774         MSVCP_basic_string_wchar_dtor(&str);
7775         return num_put_wchar__Rep(this, ret, dest, fill, pad);
7776     }
7777
7778     return num_put_wchar_put_long(this, ret, dest, base, fill, v);
7779 }
7780
7781 /* ?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 */
7782 /* ?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 */
7783 /* ?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 */
7784 /* ?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 */
7785 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_bool, 28)
7786 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7787         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7788 {
7789     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7790     return call_num_put_wchar_do_put_bool(this, ret, dest, base, fill, v);
7791 }
7792
7793 /* ??0_Locimp@locale@std@@AAE@_N@Z */
7794 /* ??0_Locimp@locale@std@@AEAA@_N@Z */
7795 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor_transparent, 8)
7796 locale__Locimp* __thiscall locale__Locimp_ctor_transparent(locale__Locimp *this, MSVCP_bool transparent)
7797 {
7798     TRACE("(%p %d)\n", this, transparent);
7799
7800     memset(this, 0, sizeof(locale__Locimp));
7801     locale_facet_ctor_refs(&this->facet, 1);
7802     this->transparent = transparent;
7803     MSVCP_basic_string_char_ctor_cstr(&this->name, "*");
7804     return this;
7805 }
7806
7807 /* ??_F_Locimp@locale@std@@QAEXXZ */
7808 /* ??_F_Locimp@locale@std@@QEAAXXZ */
7809 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor, 4)
7810 locale__Locimp* __thiscall locale__Locimp_ctor(locale__Locimp *this)
7811 {
7812     return locale__Locimp_ctor_transparent(this, FALSE);
7813 }
7814
7815 /* ??0_Locimp@locale@std@@AAE@ABV012@@Z */
7816 /* ??0_Locimp@locale@std@@AEAA@AEBV012@@Z */
7817 DEFINE_THISCALL_WRAPPER(locale__Locimp_copy_ctor, 8)
7818 locale__Locimp* __thiscall locale__Locimp_copy_ctor(locale__Locimp *this, const locale__Locimp *copy)
7819 {
7820     _Lockit lock;
7821     MSVCP_size_t i;
7822
7823     TRACE("(%p %p)\n", this, copy);
7824
7825     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7826     memcpy(this, copy, sizeof(locale__Locimp));
7827     locale_facet_ctor_refs(&this->facet, 1);
7828     if(copy->facetvec) {
7829         this->facetvec = MSVCRT_operator_new(copy->facet_cnt*sizeof(locale_facet*));
7830         if(!this->facetvec) {
7831             _Lockit_dtor(&lock);
7832             ERR("Out of memory\n");
7833             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7834             return NULL;
7835         }
7836         for(i=0; i<this->facet_cnt; i++)
7837             if(this->facetvec[i])
7838                 locale_facet__Incref(this->facetvec[i]);
7839     }
7840     MSVCP_basic_string_char_copy_ctor(&this->name, &copy->name);
7841     _Lockit_dtor(&lock);
7842     return this;
7843 }
7844
7845 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPAV123@ABV123@@Z */
7846 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPEAV123@AEBV123@@Z */
7847 locale__Locimp* __cdecl locale__Locimp__Locimp_ctor(locale__Locimp *this, const locale__Locimp *copy)
7848 {
7849     return locale__Locimp_copy_ctor(this, copy);
7850 }
7851
7852 /* ??1_Locimp@locale@std@@MAE@XZ */
7853 /* ??1_Locimp@locale@std@@MEAA@XZ */
7854 DEFINE_THISCALL_WRAPPER(locale__Locimp_dtor, 4)
7855 void __thiscall locale__Locimp_dtor(locale__Locimp *this)
7856 {
7857     TRACE("(%p)\n", this);
7858
7859     if(locale_facet__Decref(&this->facet)) {
7860         MSVCP_size_t i;
7861         for(i=0; i<this->facet_cnt; i++)
7862             if(this->facetvec[i] && locale_facet__Decref(this->facetvec[i]))
7863                 call_locale_facet_vector_dtor(this->facetvec[i], 0);
7864
7865         MSVCRT_operator_delete(this->facetvec);
7866         MSVCP_basic_string_char_dtor(&this->name);
7867     }
7868 }
7869
7870 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPAV123@@Z */
7871 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPEAV123@@Z */
7872 void __cdecl locale__Locimp__Locimp_dtor(locale__Locimp *this)
7873 {
7874     locale__Locimp_dtor(this);
7875 }
7876
7877 DEFINE_THISCALL_WRAPPER(MSVCP_locale__Locimp_vector_dtor, 8)
7878 locale__Locimp* __thiscall MSVCP_locale__Locimp_vector_dtor(locale__Locimp *this, unsigned int flags)
7879 {
7880     TRACE("(%p %x)\n", this, flags);
7881     if(flags & 2) {
7882         /* we have an array, with the number of elements stored before the first object */
7883         int i, *ptr = (int *)this-1;
7884
7885         for(i=*ptr-1; i>=0; i--)
7886             locale__Locimp_dtor(this+i);
7887         MSVCRT_operator_delete(ptr);
7888     } else {
7889         locale__Locimp_dtor(this);
7890         if(flags & 1)
7891             MSVCRT_operator_delete(this);
7892     }
7893
7894     return this;
7895 }
7896
7897 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPAV123@PAVfacet@23@I@Z */
7898 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPEAV123@PEAVfacet@23@_K@Z */
7899 void __cdecl locale__Locimp__Locimp_Addfac(locale__Locimp *locimp, locale_facet *facet, MSVCP_size_t id)
7900 {
7901     _Lockit lock;
7902
7903     TRACE("(%p %p %lu)\n", locimp, facet, id);
7904
7905     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7906     if(id >= locimp->facet_cnt) {
7907         MSVCP_size_t new_size = id+1;
7908         locale_facet **new_facetvec;
7909
7910         if(new_size < locale_id__Id_cnt+1)
7911             new_size = locale_id__Id_cnt+1;
7912
7913         new_facetvec = MSVCRT_operator_new(sizeof(locale_facet*)*new_size);
7914         if(!new_facetvec) {
7915             _Lockit_dtor(&lock);
7916             ERR("Out of memory\n");
7917             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7918             return;
7919         }
7920
7921         memset(new_facetvec, 0, sizeof(locale_facet*)*new_size);
7922         memcpy(new_facetvec, locimp->facetvec, sizeof(locale_facet*)*locimp->facet_cnt);
7923         MSVCRT_operator_delete(locimp->facetvec);
7924         locimp->facetvec = new_facetvec;
7925         locimp->facet_cnt = new_size;
7926     }
7927
7928     if(locimp->facetvec[id] && locale_facet__Decref(locimp->facetvec[id]))
7929         call_locale_facet_vector_dtor(locimp->facetvec[id], 0);
7930
7931     locimp->facetvec[id] = facet;
7932     if(facet)
7933         locale_facet__Incref(facet);
7934     _Lockit_dtor(&lock);
7935 }
7936
7937 /* ?_Addfac@_Locimp@locale@std@@AAEXPAVfacet@23@I@Z */
7938 /* ?_Addfac@_Locimp@locale@std@@AEAAXPEAVfacet@23@_K@Z */
7939 DEFINE_THISCALL_WRAPPER(locale__Locimp__Addfac, 12)
7940 void __thiscall locale__Locimp__Addfac(locale__Locimp *this, locale_facet *facet, MSVCP_size_t id)
7941 {
7942     locale__Locimp__Locimp_Addfac(this, facet, id);
7943 }
7944
7945 /* ?_Clocptr_func@_Locimp@locale@std@@CAAAPAV123@XZ */
7946 /* ?_Clocptr_func@_Locimp@locale@std@@CAAEAPEAV123@XZ */
7947 locale__Locimp** __cdecl locale__Locimp__Clocptr_func(void)
7948 {
7949     FIXME("stub\n");
7950     return NULL;
7951 }
7952
7953 /* ?_Makeushloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
7954 /* ?_Makeushloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
7955 /* List of missing facets:
7956  * num_put, collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
7957  */
7958 void __cdecl locale__Locimp__Makeushloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
7959 {
7960     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
7961
7962     if(cat & (1<<(ctype_short__Getcat(NULL, NULL)-1))) {
7963         ctype_wchar *ctype;
7964
7965         if(loc) {
7966             ctype = ctype_short_use_facet(loc);
7967         }else {
7968             ctype = MSVCRT_operator_new(sizeof(ctype_wchar));
7969             if(!ctype) {
7970                 ERR("Out of memory\n");
7971                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7972             }
7973             ctype_short_ctor_locinfo(ctype, locinfo, 0);
7974         }
7975         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_short_id));
7976     }
7977
7978     if(cat & (1<<(num_get_short__Getcat(NULL, NULL)-1))) {
7979         num_get *numget;
7980
7981         if(loc) {
7982             numget = num_get_short_use_facet(loc);
7983         }else {
7984             numget = MSVCRT_operator_new(sizeof(num_get));
7985             if(!numget) {
7986                 ERR("Out of memory\n");
7987                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7988             }
7989             num_get_short_ctor_locinfo(numget, locinfo, 0);
7990         }
7991         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_short_id));
7992     }
7993
7994     if(cat & (1<<(num_put_short__Getcat(NULL, NULL)-1))) {
7995         num_put *numput;
7996
7997         if(loc) {
7998             numput = num_put_short_use_facet(loc);
7999         }else {
8000             numput = MSVCRT_operator_new(sizeof(num_put));
8001             if(!numput) {
8002                 ERR("Out of memory\n");
8003                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8004             }
8005             num_put_short_ctor_locinfo(numput, locinfo, 0);
8006         }
8007         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_short_id));
8008     }
8009
8010     if(cat & (1<<(numpunct_short__Getcat(NULL, NULL)-1))) {
8011         numpunct_wchar *numpunct;
8012
8013         if(loc) {
8014             numpunct = numpunct_short_use_facet(loc);
8015         }else {
8016             numpunct = MSVCRT_operator_new(sizeof(numpunct_wchar));
8017             if(!numpunct) {
8018                 ERR("Out of memory\n");
8019                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8020             }
8021             numpunct_short_ctor_locinfo(numpunct, locinfo, 0, FALSE);
8022         }
8023         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_short_id));
8024     }
8025
8026     if(cat & (1<<(codecvt_short__Getcat(NULL, NULL)-1))) {
8027         codecvt_wchar *codecvt;
8028
8029         if(loc) {
8030             codecvt = codecvt_short_use_facet(loc);
8031         }else {
8032             codecvt = MSVCRT_operator_new(sizeof(codecvt_wchar));
8033             if(!codecvt) {
8034                 ERR("Out of memory\n");
8035                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8036             }
8037             codecvt_short_ctor_locinfo(codecvt, locinfo, 0);
8038         }
8039         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_short_id));
8040     }
8041 }
8042
8043 /* ?_Makewloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
8044 /* ?_Makewloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
8045 /* List of missing facets:
8046  * collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
8047  */
8048 void __cdecl locale__Locimp__Makewloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
8049 {
8050     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
8051
8052     if(cat & (1<<(ctype_wchar__Getcat(NULL, NULL)-1))) {
8053         ctype_wchar *ctype;
8054
8055         if(loc) {
8056             ctype = ctype_wchar_use_facet(loc);
8057         }else {
8058             ctype = MSVCRT_operator_new(sizeof(ctype_wchar));
8059             if(!ctype) {
8060                 ERR("Out of memory\n");
8061                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8062             }
8063             ctype_wchar_ctor_locinfo(ctype, locinfo, 0);
8064         }
8065         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_wchar_id));
8066     }
8067
8068     if(cat & (1<<(num_get_wchar__Getcat(NULL, NULL)-1))) {
8069         num_get *numget;
8070
8071         if(loc) {
8072             numget = num_get_wchar_use_facet(loc);
8073         }else {
8074             numget = MSVCRT_operator_new(sizeof(num_get));
8075             if(!numget) {
8076                 ERR("Out of memory\n");
8077                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8078             }
8079             num_get_wchar_ctor_locinfo(numget, locinfo, 0);
8080         }
8081         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_wchar_id));
8082     }
8083
8084     if(cat & (1<<(num_put_wchar__Getcat(NULL, NULL)-1))) {
8085         num_put *numput;
8086
8087         if(loc) {
8088             numput = num_put_wchar_use_facet(loc);
8089         }else {
8090             numput = MSVCRT_operator_new(sizeof(num_put));
8091             if(!numput) {
8092                 ERR("Out of memory\n");
8093                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8094             }
8095             num_put_wchar_ctor_locinfo(numput, locinfo, 0);
8096         }
8097         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_wchar_id));
8098     }
8099
8100     if(cat & (1<<(numpunct_wchar__Getcat(NULL, NULL)-1))) {
8101         numpunct_wchar *numpunct;
8102
8103         if(loc) {
8104             numpunct = numpunct_wchar_use_facet(loc);
8105         }else {
8106             numpunct = MSVCRT_operator_new(sizeof(numpunct_wchar));
8107             if(!numpunct) {
8108                 ERR("Out of memory\n");
8109                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8110             }
8111             numpunct_wchar_ctor_locinfo(numpunct, locinfo, 0, FALSE);
8112         }
8113         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_wchar_id));
8114     }
8115
8116     if(cat & (1<<(codecvt_wchar__Getcat(NULL, NULL)-1))) {
8117         codecvt_wchar *codecvt;
8118
8119         if(loc) {
8120             codecvt = codecvt_wchar_use_facet(loc);
8121         }else {
8122             codecvt = MSVCRT_operator_new(sizeof(codecvt_wchar));
8123             if(!codecvt) {
8124                 ERR("Out of memory\n");
8125                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8126             }
8127             codecvt_wchar_ctor_locinfo(codecvt, locinfo, 0);
8128         }
8129         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_wchar_id));
8130     }
8131 }
8132
8133 /* ?_Makexloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
8134 /* ?_Makexloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
8135 /* List of missing facets:
8136  * collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
8137  */
8138 void __cdecl locale__Locimp__Makexloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
8139 {
8140     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
8141
8142     if(cat & (1<<(ctype_char__Getcat(NULL, NULL)-1))) {
8143         ctype_char *ctype;
8144
8145         if(loc) {
8146             ctype = ctype_char_use_facet(loc);
8147         }else {
8148             ctype = MSVCRT_operator_new(sizeof(ctype_char));
8149             if(!ctype) {
8150                 ERR("Out of memory\n");
8151                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8152             }
8153             ctype_char_ctor_locinfo(ctype, locinfo, 0);
8154         }
8155         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_char_id));
8156     }
8157
8158     if(cat & (1<<(num_get_char__Getcat(NULL, NULL)-1))) {
8159         num_get *numget;
8160
8161         if(loc) {
8162             numget = num_get_char_use_facet(loc);
8163         }else {
8164             numget = MSVCRT_operator_new(sizeof(num_get));
8165             if(!numget) {
8166                 ERR("Out of memory\n");
8167                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8168             }
8169             num_get_char_ctor_locinfo(numget, locinfo, 0);
8170         }
8171         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_char_id));
8172     }
8173
8174     if(cat & (1<<(num_put_char__Getcat(NULL, NULL)-1))) {
8175         num_put *numput;
8176
8177         if(loc) {
8178             numput = num_put_char_use_facet(loc);
8179         }else {
8180             numput = MSVCRT_operator_new(sizeof(num_put));
8181             if(!numput) {
8182                 ERR("Out of memory\n");
8183                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8184             }
8185             num_put_char_ctor_locinfo(numput, locinfo, 0);
8186         }
8187         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_char_id));
8188     }
8189
8190     if(cat & (1<<(numpunct_char__Getcat(NULL, NULL)-1))) {
8191         numpunct_char *numpunct;
8192
8193         if(loc) {
8194             numpunct = numpunct_char_use_facet(loc);
8195         }else {
8196             numpunct = MSVCRT_operator_new(sizeof(numpunct_char));
8197             if(!numpunct) {
8198                 ERR("Out of memory\n");
8199                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8200             }
8201             numpunct_char_ctor_locinfo(numpunct, locinfo, 0, FALSE);
8202         }
8203         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_char_id));
8204     }
8205
8206     if(cat & (1<<(codecvt_char__Getcat(NULL, NULL)-1))) {
8207         codecvt_char *codecvt;
8208
8209         if(loc) {
8210             codecvt = codecvt_char_use_facet(loc);
8211         }else {
8212             codecvt = MSVCRT_operator_new(sizeof(codecvt_char));
8213             if(!codecvt) {
8214                 ERR("Out of memory\n");
8215                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8216             }
8217             codecvt_char_ctor_locinfo(codecvt, locinfo, 0);
8218         }
8219         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_char_id));
8220     }
8221 }
8222
8223 /* ?_Makeloc@_Locimp@locale@std@@CAPAV123@ABV_Locinfo@3@HPAV123@PBV23@@Z */
8224 /* ?_Makeloc@_Locimp@locale@std@@CAPEAV123@AEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
8225 locale__Locimp* __cdecl locale__Locimp__Makeloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
8226 {
8227     TRACE("(%p %d %p %p)\n", locinfo, cat, locimp, loc);
8228
8229     locale__Locimp__Makexloc(locinfo, cat, locimp, loc);
8230     locale__Locimp__Makewloc(locinfo, cat, locimp, loc);
8231     locale__Locimp__Makeushloc(locinfo, cat, locimp, loc);
8232
8233     locimp->catmask |= cat;
8234     MSVCP_basic_string_char_copy_ctor(&locimp->name, &locinfo->newlocname);
8235     return locimp;
8236 }
8237
8238 /* ??_7_Locimp@locale@std@@6B@ */
8239 const vtable_ptr MSVCP_locale__Locimp_vtable[] = {
8240     (vtable_ptr)THISCALL_NAME(MSVCP_locale__Locimp_vector_dtor)
8241 };
8242
8243 /* ??0locale@std@@AAE@PAV_Locimp@01@@Z */
8244 /* ??0locale@std@@AEAA@PEAV_Locimp@01@@Z */
8245 DEFINE_THISCALL_WRAPPER(locale_ctor_locimp, 8)
8246 locale* __thiscall locale_ctor_locimp(locale *this, locale__Locimp *locimp)
8247 {
8248     TRACE("(%p %p)\n", this, locimp);
8249     /* Don't change locimp reference counter */
8250     this->ptr = locimp;
8251     return this;
8252 }
8253
8254 /* ?_Init@locale@std@@CAPAV_Locimp@12@XZ */
8255 /* ?_Init@locale@std@@CAPEAV_Locimp@12@XZ */
8256 locale__Locimp* __cdecl locale__Init(void)
8257 {
8258     _Lockit lock;
8259
8260     TRACE("\n");
8261
8262     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
8263     if(global_locale) {
8264         _Lockit_dtor(&lock);
8265         return global_locale;
8266     }
8267
8268     global_locale = MSVCRT_operator_new(sizeof(locale__Locimp));
8269     if(!global_locale) {
8270         _Lockit_dtor(&lock);
8271         ERR("Out of memory\n");
8272         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8273         return NULL;
8274     }
8275
8276     locale__Locimp_ctor(global_locale);
8277     global_locale->catmask = (1<<(LC_MAX+1))-1;
8278     MSVCP_basic_string_char_dtor(&global_locale->name);
8279     MSVCP_basic_string_char_ctor_cstr(&global_locale->name, "C");
8280
8281     locale__Locimp__Clocptr = global_locale;
8282     global_locale->facet.refs++;
8283     locale_ctor_locimp(&classic_locale, locale__Locimp__Clocptr);
8284     _Lockit_dtor(&lock);
8285
8286     return global_locale;
8287 }
8288
8289 /* ??0locale@std@@QAE@ABV01@0H@Z */
8290 /* ??0locale@std@@QEAA@AEBV01@0H@Z */
8291 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_locale, 16)
8292 locale* __thiscall locale_ctor_locale_locale(locale *this, const locale *loc, const locale *other, category cat)
8293 {
8294     FIXME("(%p %p %p %d) stub\n", this, loc, other, cat);
8295     return NULL;
8296 }
8297
8298 /* ??0locale@std@@QAE@ABV01@@Z */
8299 /* ??0locale@std@@QEAA@AEBV01@@Z */
8300 DEFINE_THISCALL_WRAPPER(locale_copy_ctor, 8)
8301 locale* __thiscall locale_copy_ctor(locale *this, const locale *copy)
8302 {
8303     TRACE("(%p %p)\n", this, copy);
8304     this->ptr = copy->ptr;
8305     locale_facet__Incref(&this->ptr->facet);
8306     return this;
8307 }
8308
8309 /* ??0locale@std@@QAE@ABV01@PBDH@Z */
8310 /* ??0locale@std@@QEAA@AEBV01@PEBDH@Z */
8311 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_cstr, 16)
8312 locale* __thiscall locale_ctor_locale_cstr(locale *this, const locale *loc, const char *locname, category cat)
8313 {
8314     FIXME("(%p %p %s %d) stub\n", this, loc, locname, cat);
8315     return NULL;
8316 }
8317
8318 /* ??0locale@std@@QAE@PBDH@Z */
8319 /* ??0locale@std@@QEAA@PEBDH@Z */
8320 DEFINE_THISCALL_WRAPPER(locale_ctor_cstr, 12)
8321 locale* __thiscall locale_ctor_cstr(locale *this, const char *locname, category cat)
8322 {
8323     _Locinfo locinfo;
8324
8325     TRACE("(%p %s %d)\n", this, locname, cat);
8326
8327     this->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
8328     if(!this->ptr) {
8329         ERR("Out of memory\n");
8330         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8331     }
8332     this->ptr = locale__Init();
8333
8334     _Locinfo_ctor_cat_cstr(&locinfo, cat, locname);
8335     if(!memcmp(MSVCP_basic_string_char_c_str(&locinfo.newlocname), "*", 2)) {
8336         _Locinfo_dtor(&locinfo);
8337         MSVCRT_operator_delete(this->ptr);
8338         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
8339     }
8340
8341     locale__Locimp__Makeloc(&locinfo, cat, this->ptr, NULL);
8342     _Locinfo_dtor(&locinfo);
8343
8344     return this;
8345 }
8346
8347 /* ??0locale@std@@QAE@W4_Uninitialized@1@@Z */
8348 /* ??0locale@std@@QEAA@W4_Uninitialized@1@@Z */
8349 DEFINE_THISCALL_WRAPPER(locale_ctor_uninitialized, 8)
8350 locale* __thiscall locale_ctor_uninitialized(locale *this, int uninitialized)
8351 {
8352     TRACE("(%p)\n", this);
8353     this->ptr = NULL;
8354     return this;
8355 }
8356
8357 /* ??0locale@std@@QAE@XZ */
8358 /* ??0locale@std@@QEAA@XZ */
8359 DEFINE_THISCALL_WRAPPER(locale_ctor, 4)
8360 locale* __thiscall locale_ctor(locale *this)
8361 {
8362     TRACE("(%p)\n", this);
8363     this->ptr = locale__Init();
8364     locale_facet__Incref(&this->ptr->facet);
8365     return this;
8366 }
8367
8368 /* ??1locale@std@@QAE@XZ */
8369 /* ??1locale@std@@QEAA@XZ */
8370 DEFINE_THISCALL_WRAPPER(locale_dtor, 4)
8371 void __thiscall locale_dtor(locale *this)
8372 {
8373     TRACE("(%p)\n", this);
8374     if(this->ptr)
8375         locale__Locimp_dtor(this->ptr);
8376 }
8377
8378 DEFINE_THISCALL_WRAPPER(MSVCP_locale_vector_dtor, 8)
8379 locale* __thiscall MSVCP_locale_vector_dtor(locale *this, unsigned int flags)
8380 {
8381     TRACE("(%p %x)\n", this, flags);
8382     if(flags & 2) {
8383         /* we have an array, with the number of elements stored before the first object */
8384         int i, *ptr = (int *)this-1;
8385
8386         for(i=*ptr-1; i>=0; i--)
8387             locale_dtor(this+i);
8388         MSVCRT_operator_delete(ptr);
8389     } else {
8390         locale_dtor(this);
8391         if(flags & 1)
8392             MSVCRT_operator_delete(this);
8393     }
8394
8395     return this;
8396 }
8397
8398 /* ??4locale@std@@QAEAAV01@ABV01@@Z */
8399 /* ??4locale@std@@QEAAAEAV01@AEBV01@@Z */
8400 DEFINE_THISCALL_WRAPPER(locale_operator_assign, 8)
8401 locale* __thiscall locale_operator_assign(locale *this, const locale *loc)
8402 {
8403     FIXME("(%p %p) stub\n", this, loc);
8404     return NULL;
8405 }
8406
8407 /* ??8locale@std@@QBE_NABV01@@Z */
8408 /* ??8locale@std@@QEBA_NAEBV01@@Z */
8409 DEFINE_THISCALL_WRAPPER(locale_operator_equal, 8)
8410 MSVCP_bool __thiscall locale_operator_equal(const locale *this, const locale *loc)
8411 {
8412     FIXME("(%p %p) stub\n", this, loc);
8413     return 0;
8414 }
8415
8416 /* ??9locale@std@@QBE_NABV01@@Z */
8417 /* ??9locale@std@@QEBA_NAEBV01@@Z */
8418 DEFINE_THISCALL_WRAPPER(locale_operator_not_equal, 8)
8419 MSVCP_bool __thiscall locale_operator_not_equal(const locale *this, locale const *loc)
8420 {
8421     FIXME("(%p %p) stub\n", this, loc);
8422     return 0;
8423 }
8424
8425 /* ?_Addfac@locale@std@@QAEAAV12@PAVfacet@12@II@Z */
8426 /* ?_Addfac@locale@std@@QEAAAEAV12@PEAVfacet@12@_K1@Z */
8427 DEFINE_THISCALL_WRAPPER(locale__Addfac, 16)
8428 locale* __thiscall locale__Addfac(locale *this, locale_facet *facet, MSVCP_size_t id, MSVCP_size_t catmask)
8429 {
8430     TRACE("(%p %p %lu %lu)\n", this, facet, id, catmask);
8431
8432     if(this->ptr->facet.refs > 1) {
8433         locale__Locimp *new_ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
8434         if(!new_ptr) {
8435             ERR("Out of memory\n");
8436             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8437             return NULL;
8438         }
8439         locale__Locimp_copy_ctor(new_ptr, this->ptr);
8440         locale_facet__Decref(&this->ptr->facet);
8441         this->ptr = new_ptr;
8442     }
8443
8444     locale__Locimp__Addfac(this->ptr, facet, id);
8445
8446     if(catmask) {
8447         MSVCP_basic_string_char_dtor(&this->ptr->name);
8448         MSVCP_basic_string_char_ctor_cstr(&this->ptr->name, "*");
8449     }
8450     return this;
8451 }
8452
8453 /* ?_Getfacet@locale@std@@QBEPBVfacet@12@I@Z */
8454 /* ?_Getfacet@locale@std@@QEBAPEBVfacet@12@_K@Z */
8455 DEFINE_THISCALL_WRAPPER(locale__Getfacet, 8)
8456 const locale_facet* __thiscall locale__Getfacet(const locale *this, MSVCP_size_t id)
8457 {
8458     locale_facet *fac;
8459
8460     TRACE("(%p %lu)\n", this, id);
8461
8462     fac = id < this->ptr->facet_cnt ? this->ptr->facetvec[id] : NULL;
8463     if(fac || !this->ptr->transparent)
8464         return fac;
8465
8466     return id < global_locale->facet_cnt ? global_locale->facetvec[id] : NULL;
8467 }
8468
8469 /* ?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ */
8470 /* ?_Getgloballocale@locale@std@@CAPEAV_Locimp@12@XZ */
8471 locale__Locimp* __cdecl locale__Getgloballocale(void)
8472 {
8473     TRACE("\n");
8474     return global_locale;
8475 }
8476
8477 /* ?_Setgloballocale@locale@std@@CAXPAX@Z */
8478 /* ?_Setgloballocale@locale@std@@CAXPEAX@Z */
8479 void __cdecl locale__Setgloballocale(void *locimp)
8480 {
8481     TRACE("(%p)\n", locimp);
8482     global_locale = locimp;
8483 }
8484
8485 /* ?classic@locale@std@@SAABV12@XZ */
8486 /* ?classic@locale@std@@SAAEBV12@XZ */
8487 const locale* __cdecl locale_classic(void)
8488 {
8489     TRACE("\n");
8490     locale__Init();
8491     return &classic_locale;
8492 }
8493
8494 /* ?empty@locale@std@@SA?AV12@XZ */
8495 locale* __cdecl locale_empty(locale *ret)
8496 {
8497     TRACE("\n");
8498
8499     locale__Init();
8500
8501     ret->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
8502     if(!ret->ptr) {
8503         ERR("Out of memory\n");
8504         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
8505     }
8506     locale__Locimp_ctor_transparent(ret->ptr, TRUE);
8507     return ret;
8508 }
8509
8510 /* ?name@locale@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
8511 /* ?name@locale@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
8512 DEFINE_THISCALL_WRAPPER(locale_name, 8)
8513 basic_string_char* __thiscall locale_name(const locale *this, basic_string_char *ret)
8514 {
8515     TRACE( "(%p)\n", this);
8516     MSVCP_basic_string_char_copy_ctor(ret, &this->ptr->name);
8517     return ret;
8518 }
8519
8520 /* ?global@locale@std@@SA?AV12@ABV12@@Z */
8521 /* ?global@locale@std@@SA?AV12@AEBV12@@Z */
8522 locale* __cdecl locale_global(locale *ret, const locale *loc)
8523 {
8524     _Lockit lock;
8525     int i;
8526
8527     TRACE("(%p %p)\n", loc, ret);
8528
8529     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
8530     locale_ctor(ret);
8531
8532     if(loc->ptr != global_locale) {
8533         locale_facet__Decref(&global_locale->facet);
8534         global_locale = loc->ptr;
8535         locale_facet__Incref(&global_locale->facet);
8536
8537         for(i=LC_ALL+1; i<=LC_MAX; i++) {
8538             if((global_locale->catmask & (1<<(i-1))) == 0)
8539                 continue;
8540             setlocale(i, MSVCP_basic_string_char_c_str(&global_locale->name));
8541         }
8542     }
8543     _Lockit_dtor(&lock);
8544     return ret;
8545 }
8546
8547 DEFINE_RTTI_DATA0(locale_facet, 0, ".?AVfacet@locale@std@@");
8548 DEFINE_RTTI_DATA1(collate_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@D@std@@");
8549 DEFINE_RTTI_DATA1(collate_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@_W@std@@");
8550 DEFINE_RTTI_DATA1(collate_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@G@std@@");
8551 DEFINE_RTTI_DATA1(ctype_base, 0, &locale_facet_rtti_base_descriptor, ".?AUctype_base@std@@");
8552 DEFINE_RTTI_DATA2(ctype_char, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@D@std@@");
8553 DEFINE_RTTI_DATA2(ctype_wchar, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@_W@std@@");
8554 DEFINE_RTTI_DATA2(ctype_short, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@G@std@@");
8555 DEFINE_RTTI_DATA1(codecvt_base, 0, &locale_facet_rtti_base_descriptor, ".?AVcodecvt_base@std@@");
8556 DEFINE_RTTI_DATA2(codecvt_char, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@DDH@std@@");
8557 DEFINE_RTTI_DATA2(codecvt_wchar, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@_WDH@std@@");
8558 DEFINE_RTTI_DATA2(codecvt_short, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@GDH@std@@");
8559 DEFINE_RTTI_DATA1(numpunct_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@D@std@@");
8560 DEFINE_RTTI_DATA1(numpunct_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@_W@std@@");
8561 DEFINE_RTTI_DATA1(numpunct_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@G@std@@");
8562 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@@");
8563 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@@");
8564 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@@");
8565 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@@");
8566 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@@");
8567 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@@");
8568
8569 #ifndef __GNUC__
8570 void __asm_dummy_vtables(void) {
8571 #endif
8572     __ASM_VTABLE(locale_facet, "");
8573     __ASM_VTABLE(collate_char,
8574             VTABLE_ADD_FUNC(collate_char_do_compare)
8575             VTABLE_ADD_FUNC(collate_char_do_transform)
8576             VTABLE_ADD_FUNC(collate_char_do_hash));
8577     __ASM_VTABLE(collate_wchar,
8578             VTABLE_ADD_FUNC(collate_wchar_do_compare)
8579             VTABLE_ADD_FUNC(collate_wchar_do_transform)
8580             VTABLE_ADD_FUNC(collate_wchar_do_hash));
8581     __ASM_VTABLE(collate_short,
8582             VTABLE_ADD_FUNC(collate_wchar_do_compare)
8583             VTABLE_ADD_FUNC(collate_wchar_do_transform)
8584             VTABLE_ADD_FUNC(collate_wchar_do_hash));
8585     __ASM_VTABLE(ctype_base, "");
8586     __ASM_VTABLE(ctype_char,
8587             VTABLE_ADD_FUNC(ctype_char_do_tolower)
8588             VTABLE_ADD_FUNC(ctype_char_do_tolower_ch)
8589             VTABLE_ADD_FUNC(ctype_char_do_toupper)
8590             VTABLE_ADD_FUNC(ctype_char_do_toupper_ch)
8591             VTABLE_ADD_FUNC(ctype_char_do_widen)
8592             VTABLE_ADD_FUNC(ctype_char_do_widen_ch)
8593             VTABLE_ADD_FUNC(ctype_char__Do_widen_s)
8594             VTABLE_ADD_FUNC(ctype_char_do_narrow)
8595             VTABLE_ADD_FUNC(ctype_char_do_narrow_ch)
8596             VTABLE_ADD_FUNC(ctype_char__Do_narrow_s));
8597     __ASM_VTABLE(ctype_wchar,
8598             VTABLE_ADD_FUNC(ctype_wchar_do_is)
8599             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
8600             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
8601             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
8602             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
8603             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
8604             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
8605             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
8606             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
8607             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
8608             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
8609             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
8610             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
8611             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
8612     __ASM_VTABLE(ctype_short,
8613             VTABLE_ADD_FUNC(ctype_wchar_do_is)
8614             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
8615             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
8616             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
8617             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
8618             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
8619             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
8620             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
8621             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
8622             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
8623             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
8624             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
8625             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
8626             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
8627     __ASM_VTABLE(codecvt_base,
8628             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
8629             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
8630             VTABLE_ADD_FUNC(codecvt_base_do_encoding));
8631     __ASM_VTABLE(codecvt_char,
8632             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
8633             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
8634             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8635             VTABLE_ADD_FUNC(codecvt_char_do_in)
8636             VTABLE_ADD_FUNC(codecvt_char_do_out)
8637             VTABLE_ADD_FUNC(codecvt_char_do_unshift)
8638             VTABLE_ADD_FUNC(codecvt_char_do_length));
8639     __ASM_VTABLE(codecvt_wchar,
8640             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
8641             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
8642             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8643             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
8644             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
8645             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
8646             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
8647     __ASM_VTABLE(codecvt_short,
8648             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
8649             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
8650             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8651             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
8652             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
8653             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
8654             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
8655     __ASM_VTABLE(numpunct_char,
8656             VTABLE_ADD_FUNC(numpunct_char_do_decimal_point)
8657             VTABLE_ADD_FUNC(numpunct_char_do_thousands_sep)
8658             VTABLE_ADD_FUNC(numpunct_char_do_grouping)
8659             VTABLE_ADD_FUNC(numpunct_char_do_falsename)
8660             VTABLE_ADD_FUNC(numpunct_char_do_truename));
8661     __ASM_VTABLE(numpunct_wchar,
8662             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
8663             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
8664             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
8665             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
8666             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
8667     __ASM_VTABLE(numpunct_short,
8668             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
8669             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
8670             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
8671             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
8672             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
8673     __ASM_VTABLE(num_get_char,
8674             VTABLE_ADD_FUNC(num_get_char_do_get_void)
8675             VTABLE_ADD_FUNC(num_get_char_do_get_double)
8676             VTABLE_ADD_FUNC(num_get_char_do_get_double)
8677             VTABLE_ADD_FUNC(num_get_char_do_get_float)
8678             VTABLE_ADD_FUNC(num_get_char_do_get_uint64)
8679             VTABLE_ADD_FUNC(num_get_char_do_get_int64)
8680             VTABLE_ADD_FUNC(num_get_char_do_get_ulong)
8681             VTABLE_ADD_FUNC(num_get_char_do_get_long)
8682             VTABLE_ADD_FUNC(num_get_char_do_get_uint)
8683             VTABLE_ADD_FUNC(num_get_char_do_get_ushort)
8684             VTABLE_ADD_FUNC(num_get_char_do_get_bool));
8685     __ASM_VTABLE(num_get_short,
8686             VTABLE_ADD_FUNC(num_get_short_do_get_void)
8687             VTABLE_ADD_FUNC(num_get_short_do_get_double)
8688             VTABLE_ADD_FUNC(num_get_short_do_get_double)
8689             VTABLE_ADD_FUNC(num_get_short_do_get_float)
8690             VTABLE_ADD_FUNC(num_get_short_do_get_uint64)
8691             VTABLE_ADD_FUNC(num_get_short_do_get_int64)
8692             VTABLE_ADD_FUNC(num_get_short_do_get_ulong)
8693             VTABLE_ADD_FUNC(num_get_short_do_get_long)
8694             VTABLE_ADD_FUNC(num_get_short_do_get_uint)
8695             VTABLE_ADD_FUNC(num_get_short_do_get_ushort)
8696             VTABLE_ADD_FUNC(num_get_short_do_get_bool));
8697     __ASM_VTABLE(num_get_wchar,
8698             VTABLE_ADD_FUNC(num_get_wchar_do_get_void)
8699             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
8700             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
8701             VTABLE_ADD_FUNC(num_get_wchar_do_get_float)
8702             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint64)
8703             VTABLE_ADD_FUNC(num_get_wchar_do_get_int64)
8704             VTABLE_ADD_FUNC(num_get_wchar_do_get_ulong)
8705             VTABLE_ADD_FUNC(num_get_wchar_do_get_long)
8706             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint)
8707             VTABLE_ADD_FUNC(num_get_wchar_do_get_ushort)
8708             VTABLE_ADD_FUNC(num_get_wchar_do_get_bool));
8709     __ASM_VTABLE(num_put_char,
8710             VTABLE_ADD_FUNC(num_put_char_do_put_ptr)
8711             VTABLE_ADD_FUNC(num_put_char_do_put_double)
8712             VTABLE_ADD_FUNC(num_put_char_do_put_double)
8713             VTABLE_ADD_FUNC(num_put_char_do_put_uint64)
8714             VTABLE_ADD_FUNC(num_put_char_do_put_int64)
8715             VTABLE_ADD_FUNC(num_put_char_do_put_ulong)
8716             VTABLE_ADD_FUNC(num_put_char_do_put_long)
8717             VTABLE_ADD_FUNC(num_put_char_do_put_bool));
8718     __ASM_VTABLE(num_put_wchar,
8719             VTABLE_ADD_FUNC(num_put_wchar_do_put_ptr)
8720             VTABLE_ADD_FUNC(num_put_wchar_do_put_double)
8721             VTABLE_ADD_FUNC(num_put_wchar_do_put_double)
8722             VTABLE_ADD_FUNC(num_put_wchar_do_put_uint64)
8723             VTABLE_ADD_FUNC(num_put_wchar_do_put_int64)
8724             VTABLE_ADD_FUNC(num_put_wchar_do_put_ulong)
8725             VTABLE_ADD_FUNC(num_put_wchar_do_put_long)
8726             VTABLE_ADD_FUNC(num_put_wchar_do_put_bool));
8727     __ASM_VTABLE(num_put_short,
8728             VTABLE_ADD_FUNC(num_put_short_do_put_ptr)
8729             VTABLE_ADD_FUNC(num_put_short_do_put_double)
8730             VTABLE_ADD_FUNC(num_put_short_do_put_double)
8731             VTABLE_ADD_FUNC(num_put_short_do_put_uint64)
8732             VTABLE_ADD_FUNC(num_put_short_do_put_int64)
8733             VTABLE_ADD_FUNC(num_put_short_do_put_ulong)
8734             VTABLE_ADD_FUNC(num_put_short_do_put_long)
8735             VTABLE_ADD_FUNC(num_put_short_do_put_bool));
8736 #ifndef __GNUC__
8737 }
8738 #endif
8739
8740 void free_locale(void)
8741 {
8742     facets_elem *iter, *safe;
8743
8744     if(global_locale) {
8745         locale__Locimp_dtor(global_locale);
8746         locale_dtor(&classic_locale);
8747     }
8748
8749     LIST_FOR_EACH_ENTRY_SAFE(iter, safe, &lazy_facets, facets_elem, entry) {
8750         list_remove(&iter->entry);
8751         if(locale_facet__Decref(iter->fac))
8752             call_locale_facet_vector_dtor(iter->fac, 1);
8753         MSVCRT_operator_delete(iter);
8754     }
8755 }