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