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