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