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