msvcp90: Added num_put<char>::put(bool) implementation.
[wine] / dlls / msvcp90 / locale.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #include "msvcp90.h"
24 #include "locale.h"
25 #include "errno.h"
26 #include "limits.h"
27 #include "math.h"
28 #include "stdio.h"
29
30 #include "wine/list.h"
31
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winnls.h"
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
38
39 char* __cdecl _Getdays(void);
40 char* __cdecl _Getmonths(void);
41 void* __cdecl _Gettnames(void);
42 unsigned int __cdecl ___lc_codepage_func(void);
43 LCID* __cdecl ___lc_handle_func(void);
44 const locale_facet* __thiscall locale__Getfacet(const locale*, MSVCP_size_t);
45
46 typedef int category;
47
48 typedef struct {
49     MSVCP_size_t id;
50 } locale_id;
51
52 typedef struct _locale__Locimp {
53     locale_facet facet;
54     locale_facet **facetvec;
55     MSVCP_size_t facet_cnt;
56     category catmask;
57     MSVCP_bool transparent;
58     basic_string_char name;
59 } locale__Locimp;
60
61 typedef struct {
62     void *timeptr;
63 } _Timevec;
64
65 typedef struct {
66     _Lockit lock;
67     basic_string_char days;
68     basic_string_char months;
69     basic_string_char oldlocname;
70     basic_string_char newlocname;
71 } _Locinfo;
72
73 typedef struct {
74     LCID handle;
75     unsigned page;
76 } _Collvec;
77
78 typedef struct {
79     locale_facet facet;
80     _Collvec coll;
81 } collate;
82
83 typedef struct {
84     locale_facet facet;
85     const char *grouping;
86     char dp;
87     char sep;
88     const char *false_name;
89     const char *true_name;
90 } numpunct_char;
91
92 typedef struct {
93     locale_facet facet;
94     const char *grouping;
95     wchar_t dp;
96     wchar_t sep;
97     const wchar_t *false_name;
98     const wchar_t *true_name;
99 } numpunct_wchar;
100
101 typedef struct _istreambuf_iterator_wchar
102 {
103     basic_streambuf_wchar *strbuf;
104     MSVCP_bool      got;
105     wchar_t         val;
106 } istreambuf_iterator_wchar;
107
108 /* ?_Id_cnt@id@locale@std@@0HA */
109 int locale_id__Id_cnt = 0;
110
111 static locale__Locimp *global_locale;
112 static locale classic_locale;
113
114 /* ?_Clocptr@_Locimp@locale@std@@0PAV123@A */
115 /* ?_Clocptr@_Locimp@locale@std@@0PEAV123@EA */
116 locale__Locimp *locale__Locimp__Clocptr = NULL;
117
118 static char istreambuf_iterator_char_val(istreambuf_iterator_char *this)
119 {
120     if(this->strbuf && !this->got) {
121         int c = basic_streambuf_char_sgetc(this->strbuf);
122         if(c == EOF)
123             this->strbuf = NULL;
124         else
125             this->val = c;
126     }
127
128     this->got = TRUE;
129     return this->val;
130 }
131
132 static void istreambuf_iterator_char_inc(istreambuf_iterator_char *this)
133 {
134     if(!this->strbuf || basic_streambuf_char_sbumpc(this->strbuf)==EOF) {
135         this->strbuf = NULL;
136         this->got = TRUE;
137     }else {
138         this->got = FALSE;
139         istreambuf_iterator_char_val(this);
140     }
141 }
142
143 static void ostreambuf_iterator_char_put(ostreambuf_iterator_char *this, char ch)
144 {
145     if(this->failed || basic_streambuf_char_sputc(this->strbuf, ch)==EOF)
146         this->failed = TRUE;
147 }
148
149 /* ??1facet@locale@std@@UAE@XZ */
150 /* ??1facet@locale@std@@UEAA@XZ */
151 DEFINE_THISCALL_WRAPPER(locale_facet_dtor, 4)
152 void __thiscall locale_facet_dtor(locale_facet *this)
153 {
154     TRACE("(%p)\n", this);
155 }
156
157 DEFINE_THISCALL_WRAPPER(MSVCP_locale_facet_vector_dtor, 8)
158 #define call_locale_facet_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0, \
159         locale_facet*, (locale_facet*, unsigned int), (this, flags))
160 locale_facet* __thiscall MSVCP_locale_facet_vector_dtor(locale_facet *this, unsigned int flags)
161 {
162     TRACE("(%p %x)\n", this, flags);
163     if(flags & 2) {
164         /* we have an array, with the number of elements stored before the first object */
165         int i, *ptr = (int *)this-1;
166
167         for(i=*ptr-1; i>=0; i--)
168             locale_facet_dtor(this+i);
169         MSVCRT_operator_delete(ptr);
170     } else {
171         locale_facet_dtor(this);
172         if(flags & 1)
173             MSVCRT_operator_delete(this);
174     }
175
176     return this;
177 }
178
179 typedef struct
180 {
181     locale_facet *fac;
182     struct list entry;
183 } facets_elem;
184 static struct list lazy_facets = LIST_INIT(lazy_facets);
185
186 /* Not exported from msvcp90 */
187 /* ?facet_Register@facet@locale@std@@CAXPAV123@@Z */
188 /* ?facet_Register@facet@locale@std@@CAXPEAV123@@Z */
189 void __cdecl locale_facet_register(locale_facet *add)
190 {
191     facets_elem *head = MSVCRT_operator_new(sizeof(*head));
192     if(!head) {
193         ERR("Out of memory\n");
194         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
195     }
196
197     head->fac = add;
198     list_add_head(&lazy_facets, &head->entry);
199 }
200
201 /* Not exported from msvcp90 */
202 /* ??_7facet@locale@std@@6B@ */
203 extern const vtable_ptr MSVCP_locale_facet_vtable;
204
205 /* ??0id@locale@std@@QAE@I@Z */
206 /* ??0id@locale@std@@QEAA@_K@Z */
207 DEFINE_THISCALL_WRAPPER(locale_id_ctor_id, 8)
208 locale_id* __thiscall locale_id_ctor_id(locale_id *this, MSVCP_size_t id)
209 {
210     TRACE("(%p %lu)\n", this, id);
211
212     this->id = id;
213     return this;
214 }
215
216 /* ??_Fid@locale@std@@QAEXXZ */
217 /* ??_Fid@locale@std@@QEAAXXZ */
218 DEFINE_THISCALL_WRAPPER(locale_id_ctor, 4)
219 locale_id* __thiscall locale_id_ctor(locale_id *this)
220 {
221     TRACE("(%p)\n", this);
222
223     this->id = 0;
224     return this;
225 }
226
227 /* ??Bid@locale@std@@QAEIXZ */
228 /* ??Bid@locale@std@@QEAA_KXZ */
229 DEFINE_THISCALL_WRAPPER(locale_id_operator_size_t, 4)
230 MSVCP_size_t __thiscall locale_id_operator_size_t(locale_id *this)
231 {
232     _Lockit lock;
233
234     TRACE("(%p)\n", this);
235
236     if(!this->id) {
237         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
238         this->id = ++locale_id__Id_cnt;
239         _Lockit_dtor(&lock);
240     }
241
242     return this->id;
243 }
244
245 /* ?_Id_cnt_func@id@locale@std@@CAAAHXZ */
246 /* ?_Id_cnt_func@id@locale@std@@CAAEAHXZ */
247 int* __cdecl locale_id__Id_cnt_func(void)
248 {
249     TRACE("\n");
250     return &locale_id__Id_cnt;
251 }
252
253 /* ??_Ffacet@locale@std@@QAEXXZ */
254 /* ??_Ffacet@locale@std@@QEAAXXZ */
255 DEFINE_THISCALL_WRAPPER(locale_facet_ctor, 4)
256 locale_facet* __thiscall locale_facet_ctor(locale_facet *this)
257 {
258     TRACE("(%p)\n", this);
259     this->vtable = &MSVCP_locale_facet_vtable;
260     this->refs = 0;
261     return this;
262 }
263
264 /* ??0facet@locale@std@@IAE@I@Z */
265 /* ??0facet@locale@std@@IEAA@_K@Z */
266 DEFINE_THISCALL_WRAPPER(locale_facet_ctor_refs, 8)
267 locale_facet* __thiscall locale_facet_ctor_refs(locale_facet *this, MSVCP_size_t refs)
268 {
269     TRACE("(%p %lu)\n", this, refs);
270     this->vtable = &MSVCP_locale_facet_vtable;
271     this->refs = refs;
272     return this;
273 }
274
275 /* ?_Incref@facet@locale@std@@QAEXXZ */
276 /* ?_Incref@facet@locale@std@@QEAAXXZ */
277 DEFINE_THISCALL_WRAPPER(locale_facet__Incref, 4)
278 void __thiscall locale_facet__Incref(locale_facet *this)
279 {
280     _Lockit lock;
281
282     TRACE("(%p)\n", this);
283
284     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
285     this->refs++;
286     _Lockit_dtor(&lock);
287 }
288
289 /* ?_Decref@facet@locale@std@@QAEPAV123@XZ */
290 /* ?_Decref@facet@locale@std@@QEAAPEAV123@XZ */
291 DEFINE_THISCALL_WRAPPER(locale_facet__Decref, 4)
292 locale_facet* __thiscall locale_facet__Decref(locale_facet *this)
293 {
294     _Lockit lock;
295     locale_facet *ret;
296
297     TRACE("(%p)\n", this);
298
299     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
300     if(this->refs)
301         this->refs--;
302
303     ret = this->refs ? NULL : this;
304     _Lockit_dtor(&lock);
305
306     return ret;
307 }
308
309 /* ?_Getcat@facet@locale@std@@SAIPAPBV123@PBV23@@Z */
310 /* ?_Getcat@facet@locale@std@@SA_KPEAPEBV123@PEBV23@@Z */
311 MSVCP_size_t __cdecl locale_facet__Getcat(const locale_facet **facet, const locale *loc)
312 {
313     TRACE("(%p %p)\n", facet, loc);
314     return -1;
315 }
316
317 /* ??0_Timevec@std@@QAE@ABV01@@Z */
318 /* ??0_Timevec@std@@QEAA@AEBV01@@Z */
319 /* This copy constructor modifies copied object */
320 DEFINE_THISCALL_WRAPPER(_Timevec_copy_ctor, 8)
321 _Timevec* __thiscall _Timevec_copy_ctor(_Timevec *this, _Timevec *copy)
322 {
323     TRACE("(%p %p)\n", this, copy);
324     this->timeptr = copy->timeptr;
325     copy->timeptr = NULL;
326     return this;
327 }
328
329 /* ??0_Timevec@std@@QAE@PAX@Z */
330 /* ??0_Timevec@std@@QEAA@PEAX@Z */
331 DEFINE_THISCALL_WRAPPER(_Timevec_ctor_timeptr, 8)
332 _Timevec* __thiscall _Timevec_ctor_timeptr(_Timevec *this, void *timeptr)
333 {
334     TRACE("(%p %p)\n", this, timeptr);
335     this->timeptr = timeptr;
336     return this;
337 }
338
339 /* ??_F_Timevec@std@@QAEXXZ */
340 /* ??_F_Timevec@std@@QEAAXXZ */
341 DEFINE_THISCALL_WRAPPER(_Timevec_ctor, 4)
342 _Timevec* __thiscall _Timevec_ctor(_Timevec *this)
343 {
344     TRACE("(%p)\n", this);
345     this->timeptr = NULL;
346     return this;
347 }
348
349 /* ??1_Timevec@std@@QAE@XZ */
350 /* ??1_Timevec@std@@QEAA@XZ */
351 DEFINE_THISCALL_WRAPPER(_Timevec_dtor, 4)
352 void __thiscall _Timevec_dtor(_Timevec *this)
353 {
354     TRACE("(%p)\n", this);
355     free(this->timeptr);
356 }
357
358 /* ??4_Timevec@std@@QAEAAV01@ABV01@@Z */
359 /* ??4_Timevec@std@@QEAAAEAV01@AEBV01@@Z */
360 DEFINE_THISCALL_WRAPPER(_Timevec_op_assign, 8)
361 _Timevec* __thiscall _Timevec_op_assign(_Timevec *this, _Timevec *right)
362 {
363     TRACE("(%p %p)\n", this, right);
364     this->timeptr = right->timeptr;
365     right->timeptr = NULL;
366     return this;
367 }
368
369 /* ?_Getptr@_Timevec@std@@QBEPAXXZ */
370 /* ?_Getptr@_Timevec@std@@QEBAPEAXXZ */
371 DEFINE_THISCALL_WRAPPER(_Timevec__Getptr, 4)
372 void* __thiscall _Timevec__Getptr(_Timevec *this)
373 {
374     TRACE("(%p)\n", this);
375     return this->timeptr;
376 }
377
378 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@HPBD@Z */
379 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@HPEBD@Z */
380 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cat_cstr(_Locinfo *locinfo, int category, const char *locstr)
381 {
382     const char *locale = NULL;
383
384     /* This function is probably modifying more global objects */
385     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
386
387     if(!locstr)
388         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
389
390     _Lockit_ctor_locktype(&locinfo->lock, _LOCK_LOCALE);
391     MSVCP_basic_string_char_ctor_cstr(&locinfo->days, "");
392     MSVCP_basic_string_char_ctor_cstr(&locinfo->months, "");
393     MSVCP_basic_string_char_ctor_cstr(&locinfo->oldlocname, setlocale(LC_ALL, NULL));
394
395     if(category)
396         locale = setlocale(LC_ALL, locstr);
397     else
398         locale = setlocale(LC_ALL, NULL);
399
400     if(locale)
401         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
402     else
403         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
404
405     return locinfo;
406 }
407
408 /* ??0_Locinfo@std@@QAE@HPBD@Z */
409 /* ??0_Locinfo@std@@QEAA@HPEBD@Z */
410 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cat_cstr, 12)
411 _Locinfo* __thiscall _Locinfo_ctor_cat_cstr(_Locinfo *this, int category, const char *locstr)
412 {
413     return _Locinfo__Locinfo_ctor_cat_cstr(this, category, locstr);
414 }
415
416 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
417 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
418 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_bstr(_Locinfo *locinfo, const basic_string_char *locstr)
419 {
420     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
421 }
422
423 /* ??0_Locinfo@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
424 /* ??0_Locinfo@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
425 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_bstr, 8)
426 _Locinfo* __thiscall _Locinfo_ctor_bstr(_Locinfo *this, const basic_string_char *locstr)
427 {
428     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
429 }
430
431 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@PBD@Z */
432 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@PEBD@Z */
433 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cstr(_Locinfo *locinfo, const char *locstr)
434 {
435     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, locstr);
436 }
437
438 /* ??0_Locinfo@std@@QAE@PBD@Z */
439 /* ??0_Locinfo@std@@QEAA@PEBD@Z */
440 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cstr, 8)
441 _Locinfo* __thiscall _Locinfo_ctor_cstr(_Locinfo *this, const char *locstr)
442 {
443     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, locstr);
444 }
445
446 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z */
447 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPEAV12@@Z */
448 void __cdecl _Locinfo__Locinfo_dtor(_Locinfo *locinfo)
449 {
450     TRACE("(%p)\n", locinfo);
451
452     setlocale(LC_ALL, MSVCP_basic_string_char_c_str(&locinfo->oldlocname));
453     MSVCP_basic_string_char_dtor(&locinfo->days);
454     MSVCP_basic_string_char_dtor(&locinfo->months);
455     MSVCP_basic_string_char_dtor(&locinfo->oldlocname);
456     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
457     _Lockit_dtor(&locinfo->lock);
458 }
459
460 /* ??_F_Locinfo@std@@QAEXXZ */
461 /* ??_F_Locinfo@std@@QEAAXXZ */
462 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor, 4)
463 _Locinfo* __thiscall _Locinfo_ctor(_Locinfo *this)
464 {
465     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, "C");
466 }
467
468 /* ??1_Locinfo@std@@QAE@XZ */
469 /* ??1_Locinfo@std@@QEAA@XZ */
470 DEFINE_THISCALL_WRAPPER(_Locinfo_dtor, 4)
471 void __thiscall _Locinfo_dtor(_Locinfo *this)
472 {
473     _Locinfo__Locinfo_dtor(this);
474 }
475
476 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAAV12@PAV12@HPBD@Z */
477 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAEAV12@PEAV12@HPEBD@Z */
478 _Locinfo* __cdecl _Locinfo__Locinfo_Addcats(_Locinfo *locinfo, int category, const char *locstr)
479 {
480     const char *locale = NULL;
481
482     /* This function is probably modifying more global objects */
483     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
484     if(!locstr)
485         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
486
487     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
488
489     if(category)
490         locale = setlocale(LC_ALL, locstr);
491     else
492         locale = setlocale(LC_ALL, NULL);
493
494     if(locale)
495         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
496     else
497         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
498
499     return locinfo;
500 }
501
502 /* ?_Addcats@_Locinfo@std@@QAEAAV12@HPBD@Z */
503 /* ?_Addcats@_Locinfo@std@@QEAAAEAV12@HPEBD@Z */
504 DEFINE_THISCALL_WRAPPER(_Locinfo__Addcats, 12)
505 _Locinfo* __thiscall _Locinfo__Addcats(_Locinfo *this, int category, const char *locstr)
506 {
507     return _Locinfo__Locinfo_Addcats(this, category, locstr);
508 }
509
510 /* _Getcoll */
511 _Collvec __cdecl _Getcoll(void)
512 {
513     _Collvec ret;
514     _locale_t locale = _get_current_locale();
515
516     TRACE("\n");
517
518     ret.page = locale->locinfo->lc_collate_cp;
519     ret.handle = locale->locinfo->lc_handle[LC_COLLATE];
520     _free_locale(locale);
521     return ret;
522 }
523
524 /* ?_Getcoll@_Locinfo@std@@QBE?AU_Collvec@@XZ */
525 /* ?_Getcoll@_Locinfo@std@@QEBA?AU_Collvec@@XZ */
526 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcoll, 8)
527 _Collvec* __thiscall _Locinfo__Getcoll(const _Locinfo *this, _Collvec *ret)
528 {
529     *ret = _Getcoll();
530     return ret;
531 }
532
533 /* _Getctype */
534 _Ctypevec __cdecl _Getctype(void)
535 {
536     _Ctypevec ret;
537     _locale_t locale = _get_current_locale();
538     short *table;
539
540     TRACE("\n");
541
542     ret.page = locale->locinfo->lc_codepage;
543     ret.handle = locale->locinfo->lc_handle[LC_COLLATE];
544     ret.delfl = TRUE;
545     table = malloc(sizeof(short[256]));
546     if(!table) {
547         _free_locale(locale);
548         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
549     }
550     memcpy(table, locale->locinfo->pctype, sizeof(short[256]));
551     ret.table = table;
552     _free_locale(locale);
553     return ret;
554 }
555
556 /* ?_Getctype@_Locinfo@std@@QBE?AU_Ctypevec@@XZ */
557 /* ?_Getctype@_Locinfo@std@@QEBA?AU_Ctypevec@@XZ */
558 DEFINE_THISCALL_WRAPPER(_Locinfo__Getctype, 8)
559 _Ctypevec* __thiscall _Locinfo__Getctype(const _Locinfo *this, _Ctypevec *ret)
560 {
561     *ret = _Getctype();
562     return ret;
563 }
564
565 /* _Getcvt */
566 _Cvtvec __cdecl _Getcvt(void)
567 {
568     _Cvtvec ret;
569     _locale_t locale = _get_current_locale();
570
571     TRACE("\n");
572
573     ret.page = locale->locinfo->lc_codepage;
574     ret.handle = locale->locinfo->lc_handle[LC_CTYPE];
575     _free_locale(locale);
576     return ret;
577 }
578
579 /* ?_Getcvt@_Locinfo@std@@QBE?AU_Cvtvec@@XZ */
580 /* ?_Getcvt@_Locinfo@std@@QEBA?AU_Cvtvec@@XZ */
581 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcvt, 8)
582 _Cvtvec* __thiscall _Locinfo__Getcvt(const _Locinfo *this, _Cvtvec *ret)
583 {
584     *ret = _Getcvt();
585     return ret;
586 }
587
588 /* ?_Getdateorder@_Locinfo@std@@QBEHXZ */
589 /* ?_Getdateorder@_Locinfo@std@@QEBAHXZ */
590 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdateorder, 4)
591 int __thiscall _Locinfo__Getdateorder(const _Locinfo *this)
592 {
593     FIXME("(%p) stub\n", this);
594     return 0;
595 }
596
597 /* ?_Getdays@_Locinfo@std@@QBEPBDXZ */
598 /* ?_Getdays@_Locinfo@std@@QEBAPEBDXZ */
599 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdays, 4)
600 const char* __thiscall _Locinfo__Getdays(_Locinfo *this)
601 {
602     char *days = _Getdays();
603
604     TRACE("(%p)\n", this);
605
606     if(days) {
607         MSVCP_basic_string_char_dtor(&this->days);
608         MSVCP_basic_string_char_ctor_cstr(&this->days, days);
609         free(days);
610     }
611
612     return this->days.size ? MSVCP_basic_string_char_c_str(&this->days) :
613         ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
614 }
615
616 /* ?_Getmonths@_Locinfo@std@@QBEPBDXZ */
617 /* ?_Getmonths@_Locinfo@std@@QEBAPEBDXZ */
618 DEFINE_THISCALL_WRAPPER(_Locinfo__Getmonths, 4)
619 const char* __thiscall _Locinfo__Getmonths(_Locinfo *this)
620 {
621     char *months = _Getmonths();
622
623     TRACE("(%p)\n", this);
624
625     if(months) {
626         MSVCP_basic_string_char_dtor(&this->months);
627         MSVCP_basic_string_char_ctor_cstr(&this->months, months);
628         free(months);
629     }
630
631     return this->months.size ? MSVCP_basic_string_char_c_str(&this->months) :
632         ":Jan:January:Feb:February:Mar:March:Apr:April:May:May:Jun:June:Jul:July"
633         ":Aug:August:Sep:September:Oct:October:Nov:November:Dec:December";
634 }
635
636 /* ?_Getfalse@_Locinfo@std@@QBEPBDXZ */
637 /* ?_Getfalse@_Locinfo@std@@QEBAPEBDXZ */
638 DEFINE_THISCALL_WRAPPER(_Locinfo__Getfalse, 4)
639 const char* __thiscall _Locinfo__Getfalse(const _Locinfo *this)
640 {
641     TRACE("(%p)\n", this);
642     return "false";
643 }
644
645 /* ?_Gettrue@_Locinfo@std@@QBEPBDXZ */
646 /* ?_Gettrue@_Locinfo@std@@QEBAPEBDXZ */
647 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettrue, 4)
648 const char* __thiscall _Locinfo__Gettrue(const _Locinfo *this)
649 {
650     TRACE("(%p)\n", this);
651     return "true";
652 }
653
654 /* ?_Getlconv@_Locinfo@std@@QBEPBUlconv@@XZ */
655 /* ?_Getlconv@_Locinfo@std@@QEBAPEBUlconv@@XZ */
656 DEFINE_THISCALL_WRAPPER(_Locinfo__Getlconv, 4)
657 const struct lconv* __thiscall _Locinfo__Getlconv(const _Locinfo *this)
658 {
659     TRACE("(%p)\n", this);
660     return localeconv();
661 }
662
663 /* ?_Getname@_Locinfo@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
664 /* ?_Getname@_Locinfo@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
665 DEFINE_THISCALL_WRAPPER(_Locinfo__Getname, 8)
666 basic_string_char* __thiscall _Locinfo__Getname(const _Locinfo *this, basic_string_char *ret)
667 {
668     TRACE("(%p)\n", this);
669
670     MSVCP_basic_string_char_copy_ctor(ret, &this->newlocname);
671     return ret;
672 }
673
674 /* ?_Gettnames@_Locinfo@std@@QBE?AV_Timevec@2@XZ */
675 /* ?_Gettnames@_Locinfo@std@@QEBA?AV_Timevec@2@XZ */
676 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettnames, 8)
677 _Timevec*__thiscall _Locinfo__Gettnames(const _Locinfo *this, _Timevec *ret)
678 {
679     TRACE("(%p)\n", this);
680
681     _Timevec_ctor_timeptr(ret, _Gettnames());
682     return ret;
683 }
684
685 /* ?id@?$collate@D@std@@2V0locale@2@A */
686 locale_id collate_char_id = {0};
687
688 /* ??_7?$collate@D@std@@6B@ */
689 extern const vtable_ptr MSVCP_collate_char_vtable;
690
691 /* ?_Init@?$collate@D@std@@IAEXABV_Locinfo@2@@Z */
692 /* ?_Init@?$collate@D@std@@IEAAXAEBV_Locinfo@2@@Z */
693 DEFINE_THISCALL_WRAPPER(collate_char__Init, 8)
694 void __thiscall collate_char__Init(collate *this, const _Locinfo *locinfo)
695 {
696     TRACE("(%p %p)\n", this, locinfo);
697     _Locinfo__Getcoll(locinfo, &this->coll);
698 }
699
700 /* ??0?$collate@D@std@@IAE@PBDI@Z */
701 /* ??0?$collate@D@std@@IEAA@PEBD_K@Z */
702 DEFINE_THISCALL_WRAPPER(collate_char_ctor_name, 12)
703 collate* __thiscall collate_char_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
704 {
705     _Locinfo locinfo;
706
707     TRACE("(%p %s %lu)\n", this, name, refs);
708
709     locale_facet_ctor_refs(&this->facet, refs);
710     this->facet.vtable = &MSVCP_collate_char_vtable;
711
712     _Locinfo_ctor_cstr(&locinfo, name);
713     collate_char__Init(this, &locinfo);
714     _Locinfo_dtor(&locinfo);
715     return this;
716 }
717
718 /* ??0?$collate@D@std@@QAE@ABV_Locinfo@1@I@Z */
719 /* ??0?$collate@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
720 DEFINE_THISCALL_WRAPPER(collate_char_ctor_locinfo, 12)
721 collate* __thiscall collate_char_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
722 {
723     TRACE("(%p %p %lu)\n", this, locinfo, refs);
724
725     locale_facet_ctor_refs(&this->facet, refs);
726     this->facet.vtable = &MSVCP_collate_char_vtable;
727     collate_char__Init(this, locinfo);
728     return this;
729 }
730
731 /* ??0?$collate@D@std@@QAE@I@Z */
732 /* ??0?$collate@D@std@@QEAA@_K@Z */
733 DEFINE_THISCALL_WRAPPER(collate_char_ctor_refs, 8)
734 collate* __thiscall collate_char_ctor_refs(collate *this, MSVCP_size_t refs)
735 {
736     return collate_char_ctor_name(this, "C", refs);
737 }
738
739 /* ??1?$collate@D@std@@MAE@XZ */
740 /* ??1?$collate@D@std@@MEAA@XZ */
741 DEFINE_THISCALL_WRAPPER(collate_char_dtor, 4)
742 void __thiscall collate_char_dtor(collate *this)
743 {
744     TRACE("(%p)\n", this);
745 }
746
747 DEFINE_THISCALL_WRAPPER(MSVCP_collate_char_vector_dtor, 8)
748 collate* __thiscall MSVCP_collate_char_vector_dtor(collate *this, unsigned int flags)
749 {
750     TRACE("(%p %x)\n", this, flags);
751     if(flags & 2) {
752         /* we have an array, with the number of elements stored before the first object */
753         int i, *ptr = (int *)this-1;
754
755         for(i=*ptr-1; i>=0; i--)
756             collate_char_dtor(this+i);
757         MSVCRT_operator_delete(ptr);
758     } else {
759         collate_char_dtor(this);
760         if(flags & 1)
761             MSVCRT_operator_delete(this);
762     }
763
764     return this;
765 }
766
767 /* ??_F?$collate@D@std@@QAEXXZ */
768 /* ??_F?$collate@D@std@@QEAAXXZ */
769 DEFINE_THISCALL_WRAPPER(collate_char_ctor, 4)
770 collate* __thiscall collate_char_ctor(collate *this)
771 {
772     return collate_char_ctor_name(this, "C", 0);
773 }
774
775 /* ?_Getcat@?$collate@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
776 /* ?_Getcat@?$collate@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
777 MSVCP_size_t __cdecl collate_char__Getcat(const locale_facet **facet, const locale *loc)
778 {
779     TRACE("(%p %p)\n", facet, loc);
780
781     if(facet && !*facet) {
782         *facet = MSVCRT_operator_new(sizeof(collate));
783         if(!*facet) {
784             ERR("Out of memory\n");
785             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
786             return 0;
787         }
788         collate_char_ctor_name((collate*)*facet,
789                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
790     }
791
792     return LC_COLLATE;
793 }
794
795 /* _Strcoll */
796 int __cdecl _Strcoll(const char *first1, const char *last1, const char *first2,
797         const char *last2, const _Collvec *coll)
798 {
799     LCID lcid;
800
801     TRACE("(%s %s)\n", debugstr_an(first1, last1-first1), debugstr_an(first2, last2-first2));
802
803     if(coll)
804         lcid = coll->handle;
805     else
806         lcid = ___lc_handle_func()[LC_COLLATE];
807     return CompareStringA(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
808 }
809
810 /* ?do_compare@?$collate@D@std@@MBEHPBD000@Z */
811 /* ?do_compare@?$collate@D@std@@MEBAHPEBD000@Z */
812 DEFINE_THISCALL_WRAPPER(collate_char_do_compare, 20)
813 #define call_collate_char_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
814         (const collate*, const char*, const char*, const char*, const char*), \
815         (this, first1, last1, first2, last2))
816 int __thiscall collate_char_do_compare(const collate *this, const char *first1,
817         const char *last1, const char *first2, const char *last2)
818 {
819     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
820     return _Strcoll(first1, last1, first2, last2, &this->coll);
821 }
822
823 /* ?compare@?$collate@D@std@@QBEHPBD000@Z */
824 /* ?compare@?$collate@D@std@@QEBAHPEBD000@Z */
825 DEFINE_THISCALL_WRAPPER(collate_char_compare, 20)
826 int __thiscall collate_char_compare(const collate *this, const char *first1,
827         const char *last1, const char *first2, const char *last2)
828 {
829     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
830     return call_collate_char_do_compare(this, first1, last1, first2, last2);
831 }
832
833 /* ?do_hash@?$collate@D@std@@MBEJPBD0@Z */
834 /* ?do_hash@?$collate@D@std@@MEBAJPEBD0@Z */
835 DEFINE_THISCALL_WRAPPER(collate_char_do_hash, 12)
836 #define call_collate_char_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
837         (const collate*, const char*, const char*), (this, first, last))
838 LONG __thiscall collate_char_do_hash(const collate *this,
839         const char *first, const char *last)
840 {
841     ULONG ret = 0;
842
843     TRACE("(%p %p %p)\n", this, first, last);
844
845     for(; first<last; first++)
846         ret = (ret<<8 | ret>>24) + *first;
847     return ret;
848 }
849
850 /* ?hash@?$collate@D@std@@QBEJPBD0@Z */
851 /* ?hash@?$collate@D@std@@QEBAJPEBD0@Z */
852 DEFINE_THISCALL_WRAPPER(collate_char_hash, 12)
853 LONG __thiscall collate_char_hash(const collate *this,
854         const char *first, const char *last)
855 {
856     TRACE("(%p %p %p)\n", this, first, last);
857     return call_collate_char_do_hash(this, first, last);
858 }
859
860 /* ?do_transform@?$collate@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
861 /* ?do_transform@?$collate@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
862 DEFINE_THISCALL_WRAPPER(collate_char_do_transform, 16)
863 basic_string_char* __thiscall collate_char_do_transform(const collate *this,
864         basic_string_char *ret, const char *first, const char *last)
865 {
866     FIXME("(%p %p %p) stub\n", this, first, last);
867     return ret;
868 }
869
870 /* ?transform@?$collate@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
871 /* ?transform@?$collate@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
872 DEFINE_THISCALL_WRAPPER(collate_char_transform, 16)
873 basic_string_char* __thiscall collate_char_transform(const collate *this,
874         basic_string_char *ret, const char *first, const char *last)
875 {
876     FIXME("(%p %p %p) stub\n", this, first, last);
877     return ret;
878 }
879
880 /* ?id@?$collate@_W@std@@2V0locale@2@A */
881 locale_id collate_wchar_id = {0};
882 /* ?id@?$collate@G@std@@2V0locale@2@A */
883 locale_id collate_short_id = {0};
884
885 /* ??_7?$collate@_W@std@@6B@ */
886 extern const vtable_ptr MSVCP_collate_wchar_vtable;
887 /* ??_7?$collate@G@std@@6B@ */
888 extern const vtable_ptr MSVCP_collate_short_vtable;
889
890 /* ?_Init@?$collate@_W@std@@IAEXABV_Locinfo@2@@Z */
891 /* ?_Init@?$collate@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
892 /* ?_Init@?$collate@G@std@@IAEXABV_Locinfo@2@@Z */
893 /* ?_Init@?$collate@G@std@@IEAAXAEBV_Locinfo@2@@Z */
894 DEFINE_THISCALL_WRAPPER(collate_wchar__Init, 8)
895 void __thiscall collate_wchar__Init(collate *this, const _Locinfo *locinfo)
896 {
897     TRACE("(%p %p)\n", this, locinfo);
898     _Locinfo__Getcoll(locinfo, &this->coll);
899 }
900
901 /* ??0?$collate@_W@std@@IAE@PBDI@Z */
902 /* ??0?$collate@_W@std@@IEAA@PEBD_K@Z */
903 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_name, 12)
904 collate* __thiscall collate_wchar_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
905 {
906     _Locinfo locinfo;
907
908     TRACE("(%p %s %lu)\n", this, name, refs);
909
910     locale_facet_ctor_refs(&this->facet, refs);
911     this->facet.vtable = &MSVCP_collate_wchar_vtable;
912
913     _Locinfo_ctor_cstr(&locinfo, name);
914     collate_wchar__Init(this, &locinfo);
915     _Locinfo_dtor(&locinfo);
916     return this;
917 }
918
919 /* ??0?$collate@G@std@@IAE@PBDI@Z */
920 /* ??0?$collate@G@std@@IEAA@PEBD_K@Z */
921 DEFINE_THISCALL_WRAPPER(collate_short_ctor_name, 12)
922 collate* __thiscall collate_short_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
923 {
924     collate *ret = collate_wchar_ctor_name(this, name, refs);
925     ret->facet.vtable = &MSVCP_collate_short_vtable;
926     return ret;
927 }
928
929 /* ??0?$collate@_W@std@@QAE@ABV_Locinfo@1@I@Z */
930 /* ??0?$collate@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
931 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_locinfo, 12)
932 collate* __thiscall collate_wchar_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
933 {
934     TRACE("(%p %p %lu)\n", this, locinfo, refs);
935
936     locale_facet_ctor_refs(&this->facet, refs);
937     this->facet.vtable = &MSVCP_collate_wchar_vtable;
938     collate_wchar__Init(this, locinfo);
939     return this;
940 }
941
942 /* ??0?$collate@G@std@@QAE@ABV_Locinfo@1@I@Z */
943 /* ??0?$collate@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
944 DEFINE_THISCALL_WRAPPER(collate_short_ctor_locinfo, 12)
945 collate* __thiscall collate_short_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
946 {
947     collate *ret = collate_wchar_ctor_locinfo(this, locinfo, refs);
948     ret->facet.vtable = &MSVCP_collate_short_vtable;
949     return ret;
950 }
951
952 /* ??0?$collate@_W@std@@QAE@I@Z */
953 /* ??0?$collate@_W@std@@QEAA@_K@Z */
954 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_refs, 8)
955 collate* __thiscall collate_wchar_ctor_refs(collate *this, MSVCP_size_t refs)
956 {
957     return collate_wchar_ctor_name(this, "C", refs);
958 }
959
960 /* ??0?$collate@G@std@@QAE@I@Z */
961 /* ??0?$collate@G@std@@QEAA@_K@Z */
962 DEFINE_THISCALL_WRAPPER(collate_short_ctor_refs, 8)
963 collate* __thiscall collate_short_ctor_refs(collate *this, MSVCP_size_t refs)
964 {
965     collate *ret = collate_wchar_ctor_refs(this, refs);
966     ret->facet.vtable = &MSVCP_collate_short_vtable;
967     return ret;
968 }
969
970 /* ??1?$collate@_W@std@@MAE@XZ */
971 /* ??1?$collate@_W@std@@MEAA@XZ */
972 /* ??1?$collate@G@std@@MAE@XZ */
973 /* ??1?$collate@G@std@@MEAA@XZ */
974 DEFINE_THISCALL_WRAPPER(collate_wchar_dtor, 4)
975 void __thiscall collate_wchar_dtor(collate *this)
976 {
977     TRACE("(%p)\n", this);
978 }
979
980 DEFINE_THISCALL_WRAPPER(MSVCP_collate_wchar_vector_dtor, 8)
981 collate* __thiscall MSVCP_collate_wchar_vector_dtor(collate *this, unsigned int flags)
982 {
983     TRACE("(%p %x)\n", this, flags);
984     if(flags & 2) {
985         /* we have an array, with the number of elements stored before the first object */
986         int i, *ptr = (int *)this-1;
987
988         for(i=*ptr-1; i>=0; i--)
989             collate_wchar_dtor(this+i);
990         MSVCRT_operator_delete(ptr);
991     } else {
992         collate_wchar_dtor(this);
993         if(flags & 1)
994             MSVCRT_operator_delete(this);
995     }
996
997     return this;
998 }
999
1000 DEFINE_THISCALL_WRAPPER(MSVCP_collate_short_vector_dtor, 8)
1001 collate* __thiscall MSVCP_collate_short_vector_dtor(collate *this, unsigned int flags)
1002 {
1003     return MSVCP_collate_wchar_vector_dtor(this, flags);
1004 }
1005
1006 /* ??_F?$collate@_W@std@@QAEXXZ */
1007 /* ??_F?$collate@_W@std@@QEAAXXZ */
1008 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor, 4)
1009 collate* __thiscall collate_wchar_ctor(collate *this)
1010 {
1011     return collate_wchar_ctor_name(this, "C", 0);
1012 }
1013
1014 /* ??_F?$collate@G@std@@QAEXXZ */
1015 /* ??_F?$collate@G@std@@QEAAXXZ */
1016 DEFINE_THISCALL_WRAPPER(collate_short_ctor, 4)
1017 collate* __thiscall collate_short_ctor(collate *this)
1018 {
1019     collate *ret = collate_wchar_ctor(this);
1020     ret->facet.vtable = &MSVCP_collate_short_vtable;
1021     return ret;
1022 }
1023
1024 /* ?_Getcat@?$collate@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1025 /* ?_Getcat@?$collate@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1026 MSVCP_size_t __cdecl collate_wchar__Getcat(const locale_facet **facet, const locale *loc)
1027 {
1028     TRACE("(%p %p)\n", facet, loc);
1029
1030     if(facet && !*facet) {
1031         *facet = MSVCRT_operator_new(sizeof(collate));
1032         if(!*facet) {
1033             ERR("Out of memory\n");
1034             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1035             return 0;
1036         }
1037         collate_wchar_ctor_name((collate*)*facet,
1038                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
1039     }
1040
1041     return LC_COLLATE;
1042 }
1043
1044 /* ?_Getcat@?$collate@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1045 /* ?_Getcat@?$collate@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1046 MSVCP_size_t __cdecl collate_short__Getcat(const locale_facet **facet, const locale *loc)
1047 {
1048     if(facet && !*facet) {
1049         collate_wchar__Getcat(facet, loc);
1050         (*(locale_facet**)facet)->vtable = &MSVCP_collate_short_vtable;
1051     }
1052
1053     return LC_COLLATE;
1054 }
1055
1056 /* _Wcscoll */
1057 int __cdecl _Wcscoll(const wchar_t *first1, const wchar_t *last1, const wchar_t *first2,
1058         const wchar_t *last2, const _Collvec *coll)
1059 {
1060     LCID lcid;
1061
1062     TRACE("(%s %s)\n", debugstr_wn(first1, last1-first1), debugstr_wn(first2, last2-first2));
1063
1064     if(coll)
1065         lcid = coll->handle;
1066     else
1067         lcid = ___lc_handle_func()[LC_COLLATE];
1068     return CompareStringW(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
1069 }
1070
1071 /* ?do_compare@?$collate@_W@std@@MBEHPB_W000@Z */
1072 /* ?do_compare@?$collate@_W@std@@MEBAHPEB_W000@Z */
1073 /* ?do_compare@?$collate@G@std@@MBEHPBG000@Z */
1074 /* ?do_compare@?$collate@G@std@@MEBAHPEBG000@Z */
1075 DEFINE_THISCALL_WRAPPER(collate_wchar_do_compare, 20)
1076 #define call_collate_wchar_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
1077         (const collate*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*), \
1078         (this, first1, last1, first2, last2))
1079 int __thiscall collate_wchar_do_compare(const collate *this, const wchar_t *first1,
1080         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1081 {
1082     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1083     return _Wcscoll(first1, last1, first2, last2, &this->coll);
1084 }
1085
1086 /* ?compare@?$collate@_W@std@@QBEHPB_W000@Z */
1087 /* ?compare@?$collate@_W@std@@QEBAHPEB_W000@Z */
1088 /* ?compare@?$collate@G@std@@QBEHPBG000@Z */
1089 /* ?compare@?$collate@G@std@@QEBAHPEBG000@Z */
1090 DEFINE_THISCALL_WRAPPER(collate_wchar_compare, 20)
1091 int __thiscall collate_wchar_compare(const collate *this, const wchar_t *first1,
1092         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1093 {
1094     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1095     return call_collate_wchar_do_compare(this, first1, last1, first2, last2);
1096 }
1097
1098 /* ?do_hash@?$collate@_W@std@@MBEJPB_W0@Z */
1099 /* ?do_hash@?$collate@_W@std@@MEBAJPEB_W0@Z */
1100 /* ?do_hash@?$collate@G@std@@MBEJPBG0@Z */
1101 /* ?do_hash@?$collate@G@std@@MEBAJPEBG0@Z */
1102 DEFINE_THISCALL_WRAPPER(collate_wchar_do_hash, 12)
1103 #define call_collate_wchar_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
1104         (const collate*, const wchar_t*, const wchar_t*), (this, first, last))
1105 LONG __thiscall collate_wchar_do_hash(const collate *this,
1106         const wchar_t *first, const wchar_t *last)
1107 {
1108     ULONG ret = 0;
1109
1110     TRACE("(%p %p %p)\n", this, first, last);
1111
1112     for(; first<last; first++)
1113         ret = (ret<<8 | ret>>24) + *first;
1114     return ret;
1115 }
1116
1117 /* ?hash@?$collate@_W@std@@QBEJPB_W0@Z */
1118 /* ?hash@?$collate@_W@std@@QEBAJPEB_W0@Z */
1119 /* ?hash@?$collate@G@std@@QBEJPBG0@Z */
1120 /* ?hash@?$collate@G@std@@QEBAJPEBG0@Z */
1121 DEFINE_THISCALL_WRAPPER(collate_wchar_hash, 12)
1122 LONG __thiscall collate_wchar_hash(const collate *this,
1123         const wchar_t *first, const wchar_t *last)
1124 {
1125     TRACE("(%p %p %p)\n", this, first, last);
1126     return call_collate_wchar_do_hash(this, first, last);
1127 }
1128
1129 /* ?do_transform@?$collate@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1130 /* ?do_transform@?$collate@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1131 /* ?do_transform@?$collate@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1132 /* ?do_transform@?$collate@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1133 DEFINE_THISCALL_WRAPPER(collate_wchar_do_transform, 16)
1134 basic_string_wchar* __thiscall collate_wchar_do_transform(const collate *this,
1135         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1136 {
1137     FIXME("(%p %p %p) stub\n", this, first, last);
1138     return ret;
1139 }
1140
1141 /* ?transform@?$collate@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1142 /* ?transform@?$collate@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1143 /* ?transform@?$collate@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1144 /* ?transform@?$collate@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1145 DEFINE_THISCALL_WRAPPER(collate_wchar_transform, 16)
1146 basic_string_wchar* __thiscall collate_wchar_transform(const collate *this,
1147         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1148 {
1149     FIXME("(%p %p %p) stub\n", this, first, last);
1150     return ret;
1151 }
1152
1153 /* ??_7ctype_base@std@@6B@ */
1154 extern const vtable_ptr MSVCP_ctype_base_vtable;
1155
1156 /* ??0ctype_base@std@@QAE@I@Z */
1157 /* ??0ctype_base@std@@QEAA@_K@Z */
1158 DEFINE_THISCALL_WRAPPER(ctype_base_ctor_refs, 8)
1159 ctype_base* __thiscall ctype_base_ctor_refs(ctype_base *this, MSVCP_size_t refs)
1160 {
1161     TRACE("(%p %lu)\n", this, refs);
1162     locale_facet_ctor_refs(&this->facet, refs);
1163     this->facet.vtable = &MSVCP_ctype_base_vtable;
1164     return this;
1165 }
1166
1167 /* ??_Fctype_base@std@@QAEXXZ */
1168 /* ??_Fctype_base@std@@QEAAXXZ */
1169 DEFINE_THISCALL_WRAPPER(ctype_base_ctor, 4)
1170 ctype_base* __thiscall ctype_base_ctor(ctype_base *this)
1171 {
1172     TRACE("(%p)\n", this);
1173     locale_facet_ctor_refs(&this->facet, 0);
1174     this->facet.vtable = &MSVCP_ctype_base_vtable;
1175     return this;
1176 }
1177
1178 /* ??1ctype_base@std@@UAE@XZ */
1179 /* ??1ctype_base@std@@UEAA@XZ */
1180 DEFINE_THISCALL_WRAPPER(ctype_base_dtor, 4)
1181 void __thiscall ctype_base_dtor(ctype_base *this)
1182 {
1183     TRACE("(%p)\n", this);
1184 }
1185
1186 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_base_vector_dtor, 8)
1187 ctype_base* __thiscall MSVCP_ctype_base_vector_dtor(ctype_base *this, unsigned int flags)
1188 {
1189     TRACE("(%p %x)\n", this, flags);
1190     if(flags & 2) {
1191         /* we have an array, with the number of elements stored before the first object */
1192         int i, *ptr = (int *)this-1;
1193
1194         for(i=*ptr-1; i>=0; i--)
1195             ctype_base_dtor(this+i);
1196         MSVCRT_operator_delete(ptr);
1197     } else {
1198         ctype_base_dtor(this);
1199         if(flags & 1)
1200             MSVCRT_operator_delete(this);
1201     }
1202
1203     return this;
1204 }
1205
1206 /* ?_Xran@ctype_base@std@@KAXXZ */
1207 void __cdecl ctype_base__Xran(void)
1208 {
1209     throw_exception(EXCEPTION_OUT_OF_RANGE, "out of range in ctype<T>");
1210 }
1211
1212 /* ?id@?$ctype@D@std@@2V0locale@2@A */
1213 locale_id ctype_char_id = {0};
1214 /* ?table_size@?$ctype@D@std@@2IB */
1215 /* ?table_size@?$ctype@D@std@@2_KB */
1216 MSVCP_size_t ctype_char_table_size = 256;
1217
1218 /* ??_7?$ctype@D@std@@6B@ */
1219 extern const vtable_ptr MSVCP_ctype_char_vtable;
1220
1221 /* ?_Id_func@?$ctype@D@std@@SAAAVid@locale@2@XZ */
1222 /* ?_Id_func@?$ctype@D@std@@SAAEAVid@locale@2@XZ */
1223 locale_id* __cdecl ctype_char__Id_func(void)
1224 {
1225     TRACE("()\n");
1226     return &ctype_char_id;
1227 }
1228
1229 /* ?_Init@?$ctype@D@std@@IAEXABV_Locinfo@2@@Z */
1230 /* ?_Init@?$ctype@D@std@@IEAAXAEBV_Locinfo@2@@Z */
1231 DEFINE_THISCALL_WRAPPER(ctype_char__Init, 8)
1232 void __thiscall ctype_char__Init(ctype_char *this, _Locinfo *locinfo)
1233 {
1234     TRACE("(%p %p)\n", this, locinfo);
1235     _Locinfo__Getctype(locinfo, &this->ctype);
1236 }
1237
1238 /* ?_Tidy@?$ctype@D@std@@IAEXXZ */
1239 /* ?_Tidy@?$ctype@D@std@@IEAAXXZ */
1240 DEFINE_THISCALL_WRAPPER(ctype_char__Tidy, 4)
1241 void __thiscall ctype_char__Tidy(ctype_char *this)
1242 {
1243     TRACE("(%p)\n", this);
1244
1245     if(this->ctype.delfl)
1246         free((short*)this->ctype.table);
1247 }
1248
1249 /* ?classic_table@?$ctype@D@std@@KAPBFXZ */
1250 /* ?classic_table@?$ctype@D@std@@KAPEBFXZ */
1251 const short* __cdecl ctype_char_classic_table(void)
1252 {
1253     TRACE("()\n");
1254     return &((short*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_ctype"))[1];
1255 }
1256
1257 /* ??0?$ctype@D@std@@QAE@ABV_Locinfo@1@I@Z */
1258 /* ??0?$ctype@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1259 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_locinfo, 12)
1260 ctype_char* __thiscall ctype_char_ctor_locinfo(ctype_char *this,
1261         _Locinfo *locinfo, MSVCP_size_t refs)
1262 {
1263     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1264     ctype_base_ctor_refs(&this->base, refs);
1265     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1266     ctype_char__Init(this, locinfo);
1267     return this;
1268 }
1269
1270 /* ??0?$ctype@D@std@@QAE@PBF_NI@Z */
1271 /* ??0?$ctype@D@std@@QEAA@PEBF_N_K@Z */
1272 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_table, 16)
1273 ctype_char* __thiscall ctype_char_ctor_table(ctype_char *this,
1274         const short *table, MSVCP_bool delete, MSVCP_size_t refs)
1275 {
1276     _Locinfo locinfo;
1277
1278     TRACE("(%p %p %d %lu)\n", this, table, delete, refs);
1279
1280     ctype_base_ctor_refs(&this->base, refs);
1281     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1282
1283     _Locinfo_ctor(&locinfo);
1284     ctype_char__Init(this, &locinfo);
1285     _Locinfo_dtor(&locinfo);
1286
1287     if(table) {
1288         ctype_char__Tidy(this);
1289         this->ctype.table = table;
1290         this->ctype.delfl = delete;
1291     }
1292     return this;
1293 }
1294
1295 /* ??_F?$ctype@D@std@@QAEXXZ */
1296 /* ??_F?$ctype@D@std@@QEAAXXZ */
1297 DEFINE_THISCALL_WRAPPER(ctype_char_ctor, 4)
1298 ctype_char* __thiscall ctype_char_ctor(ctype_char *this)
1299 {
1300     return ctype_char_ctor_table(this, NULL, FALSE, 0);
1301 }
1302
1303 /* ??1?$ctype@D@std@@MAE@XZ */
1304 /* ??1?$ctype@D@std@@MEAA@XZ */
1305 DEFINE_THISCALL_WRAPPER(ctype_char_dtor, 4)
1306 void __thiscall ctype_char_dtor(ctype_char *this)
1307 {
1308     TRACE("(%p)\n", this);
1309     ctype_char__Tidy(this);
1310 }
1311
1312 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_char_vector_dtor, 8)
1313 ctype_char* __thiscall MSVCP_ctype_char_vector_dtor(ctype_char *this, unsigned int flags)
1314 {
1315     TRACE("(%p %x)\n", this, flags);
1316     if(flags & 2) {
1317         /* we have an array, with the number of elements stored before the first object */
1318         int i, *ptr = (int *)this-1;
1319
1320         for(i=*ptr-1; i>=0; i--)
1321             ctype_char_dtor(this+i);
1322         MSVCRT_operator_delete(ptr);
1323     } else {
1324         ctype_char_dtor(this);
1325         if(flags & 1)
1326             MSVCRT_operator_delete(this);
1327     }
1328
1329     return this;
1330 }
1331
1332 /* ?do_narrow@?$ctype@D@std@@MBEDDD@Z */
1333 /* ?do_narrow@?$ctype@D@std@@MEBADDD@Z */
1334 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow_ch, 12)
1335 #define call_ctype_char_do_narrow_ch(this, ch, unused) CALL_VTBL_FUNC(this, 36, \
1336         char, (const ctype_char*, char, char), (this, ch, unused))
1337 char __thiscall ctype_char_do_narrow_ch(const ctype_char *this, char ch, char unused)
1338 {
1339     TRACE("(%p %c %c)\n", this, ch, unused);
1340     return ch;
1341 }
1342
1343 /* ?do_narrow@?$ctype@D@std@@MBEPBDPBD0DPAD@Z */
1344 /* ?do_narrow@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD@Z */
1345 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow, 20)
1346 #define call_ctype_char_do_narrow(this, first, last, unused, dest) CALL_VTBL_FUNC(this, 32, \
1347         const char*, (const ctype_char*, const char*, const char*, char, char*), \
1348         (this, first, last, unused, dest))
1349 const char* __thiscall ctype_char_do_narrow(const ctype_char *this,
1350         const char *first, const char *last, char unused, char *dest)
1351 {
1352     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1353     memcpy(dest, first, last-first);
1354     return last;
1355 }
1356
1357 /* ?_Do_narrow_s@?$ctype@D@std@@MBEPBDPBD0DPADI@Z */
1358 /* ?_Do_narrow_s@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD_K@Z */
1359 DEFINE_THISCALL_WRAPPER(ctype_char__Do_narrow_s, 24)
1360 #define call_ctype_char__Do_narrow_s(this, first, last, unused, dest, size) CALL_VTBL_FUNC(this, 40, \
1361         const char*, (const ctype_char*, const char*, const char*, char, char*, MSVCP_size_t), \
1362         (this, first, last, unused, dest, size))
1363 const char* __thiscall ctype_char__Do_narrow_s(const ctype_char *this, const char *first,
1364         const char *last, char unused, char *dest, MSVCP_size_t size)
1365 {
1366     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1367     memcpy_s(dest, size, first, last-first);
1368     return last;
1369 }
1370
1371 /* ?narrow@?$ctype@D@std@@QBEDDD@Z */
1372 /* ?narrow@?$ctype@D@std@@QEBADDD@Z */
1373 DEFINE_THISCALL_WRAPPER(ctype_char_narrow_ch, 12)
1374 char __thiscall ctype_char_narrow_ch(const ctype_char *this, char ch, char dflt)
1375 {
1376     TRACE("(%p %c %c)\n", this, ch, dflt);
1377     return call_ctype_char_do_narrow_ch(this, ch, dflt);
1378 }
1379
1380 /* ?narrow@?$ctype@D@std@@QBEPBDPBD0DPAD@Z */
1381 /* ?narrow@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD@Z */
1382 DEFINE_THISCALL_WRAPPER(ctype_char_narrow, 20)
1383 const char* __thiscall ctype_char_narrow(const ctype_char *this,
1384         const char *first, const char *last, char dflt, char *dest)
1385 {
1386     TRACE("(%p %p %p %c %p)\n", this, first, last, dflt, dest);
1387     return call_ctype_char_do_narrow(this, first, last, dflt, dest);
1388 }
1389
1390 /* ?_Narrow_s@?$ctype@D@std@@QBEPBDPBD0DPADI@Z */
1391 /* ?_Narrow_s@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD_K@Z */
1392 DEFINE_THISCALL_WRAPPER(ctype_char__Narrow_s, 24)
1393 const char* __thiscall ctype_char__Narrow_s(const ctype_char *this, const char *first,
1394         const char *last, char dflt, char *dest, MSVCP_size_t size)
1395 {
1396     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1397     return call_ctype_char__Do_narrow_s(this, first, last, dflt, dest, size);
1398 }
1399
1400 /* ?do_widen@?$ctype@D@std@@MBEDD@Z */
1401 /* ?do_widen@?$ctype@D@std@@MEBADD@Z */
1402 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen_ch, 8)
1403 #define call_ctype_char_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
1404         char, (const ctype_char*, char), (this, ch))
1405 char __thiscall ctype_char_do_widen_ch(const ctype_char *this, char ch)
1406 {
1407     TRACE("(%p %c)\n", this, ch);
1408     return ch;
1409 }
1410
1411 /* ?do_widen@?$ctype@D@std@@MBEPBDPBD0PAD@Z */
1412 /* ?do_widen@?$ctype@D@std@@MEBAPEBDPEBD0PEAD@Z */
1413 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen, 16)
1414 #define call_ctype_char_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 20, \
1415         const char*, (const ctype_char*, const char*, const char*, char*), \
1416         (this, first, last, dest))
1417 const char* __thiscall ctype_char_do_widen(const ctype_char *this,
1418         const char *first, const char *last, char *dest)
1419 {
1420     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1421     memcpy(dest, first, last-first);
1422     return last;
1423 }
1424
1425 /* ?_Do_widen_s@?$ctype@D@std@@MBEPBDPBD0PADI@Z */
1426 /* ?_Do_widen_s@?$ctype@D@std@@MEBAPEBDPEBD0PEAD_K@Z */
1427 DEFINE_THISCALL_WRAPPER(ctype_char__Do_widen_s, 20)
1428 #define call_ctype_char__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 28, \
1429         const char*, (const ctype_char*, const char*, const char*, char*, MSVCP_size_t), \
1430         (this, first, last, dest, size))
1431 const char* __thiscall ctype_char__Do_widen_s(const ctype_char *this,
1432         const char *first, const char *last, char *dest, MSVCP_size_t size)
1433 {
1434     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1435     memcpy_s(dest, size, first, last-first);
1436     return last;
1437 }
1438
1439 /* ?widen@?$ctype@D@std@@QBEDD@Z */
1440 /* ?widen@?$ctype@D@std@@QEBADD@Z */
1441 DEFINE_THISCALL_WRAPPER(ctype_char_widen_ch, 8)
1442 char __thiscall ctype_char_widen_ch(const ctype_char *this, char ch)
1443 {
1444     TRACE("(%p %c)\n", this, ch);
1445     return call_ctype_char_do_widen_ch(this, ch);
1446 }
1447
1448 /* ?widen@?$ctype@D@std@@QBEPBDPBD0PAD@Z */
1449 /* ?widen@?$ctype@D@std@@QEBAPEBDPEBD0PEAD@Z */
1450 DEFINE_THISCALL_WRAPPER(ctype_char_widen, 16)
1451 const char* __thiscall ctype_char_widen(const ctype_char *this,
1452         const char *first, const char *last, char *dest)
1453 {
1454     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1455     return call_ctype_char_do_widen(this, first, last, dest);
1456 }
1457
1458 /* ?_Widen_s@?$ctype@D@std@@QBEPBDPBD0PADI@Z */
1459 /* ?_Widen_s@?$ctype@D@std@@QEBAPEBDPEBD0PEAD_K@Z */
1460 DEFINE_THISCALL_WRAPPER(ctype_char__Widen_s, 20)
1461 const char* __thiscall ctype_char__Widen_s(const ctype_char *this,
1462         const char *first, const char *last, char *dest, MSVCP_size_t size)
1463 {
1464     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1465     return call_ctype_char__Do_widen_s(this, first, last, dest, size);
1466 }
1467
1468 /* ?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1469 /* ?_Getcat@?$ctype@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1470 MSVCP_size_t __cdecl ctype_char__Getcat(const locale_facet **facet, const locale *loc)
1471 {
1472     TRACE("(%p %p)\n", facet, loc);
1473
1474     if(facet && !*facet) {
1475         _Locinfo locinfo;
1476
1477         *facet = MSVCRT_operator_new(sizeof(ctype_char));
1478         if(!*facet) {
1479             ERR("Out of memory\n");
1480             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1481             return 0;
1482         }
1483
1484         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
1485         ctype_char_ctor_locinfo((ctype_char*)*facet, &locinfo, 0);
1486         _Locinfo_dtor(&locinfo);
1487     }
1488
1489     return LC_CTYPE;
1490 }
1491
1492 ctype_char* ctype_char_use_facet(const locale *loc)
1493 {
1494     static ctype_char *obj = NULL;
1495
1496     _Lockit lock;
1497     const locale_facet *fac;
1498
1499     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
1500     fac = locale__Getfacet(loc, ctype_char_id.id);
1501     if(fac) {
1502         _Lockit_dtor(&lock);
1503         return (ctype_char*)fac;
1504     }
1505
1506     if(obj)
1507         return obj;
1508
1509     ctype_char__Getcat(&fac, loc);
1510     obj = (ctype_char*)fac;
1511     locale_facet__Incref(&obj->base.facet);
1512     locale_facet_register(&obj->base.facet);
1513     _Lockit_dtor(&lock);
1514
1515     return obj;
1516 }
1517
1518 /* _Tolower */
1519 int __cdecl _Tolower(int ch, const _Ctypevec *ctype)
1520 {
1521     unsigned int cp;
1522
1523     TRACE("%d %p\n", ch, ctype);
1524
1525     if(ctype)
1526         cp = ctype->page;
1527     else
1528         cp = ___lc_codepage_func();
1529
1530     /* Don't convert to unicode in case of C locale */
1531     if(!cp) {
1532         if(ch>='A' && ch<='Z')
1533             ch = ch-'A'+'a';
1534         return ch;
1535     } else {
1536         WCHAR wide, lower;
1537         char str[2];
1538         int size;
1539
1540         if(ch > 255) {
1541             str[0] = (ch>>8) & 255;
1542             str[1] = ch & 255;
1543             size = 2;
1544         } else {
1545             str[0] = ch & 255;
1546             size = 1;
1547         }
1548
1549         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1550             return ch;
1551
1552         lower = tolowerW(wide);
1553         if(lower == wide)
1554             return ch;
1555
1556         WideCharToMultiByte(cp, 0, &lower, 1, str, 2, NULL, NULL);
1557
1558         return str[0] + (str[1]<<8);
1559     }
1560 }
1561
1562 /* ?do_tolower@?$ctype@D@std@@MBEDD@Z */
1563 /* ?do_tolower@?$ctype@D@std@@MEBADD@Z */
1564 #define call_ctype_char_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 8, \
1565         char, (const ctype_char*, char), (this, ch))
1566 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower_ch, 8)
1567 char __thiscall ctype_char_do_tolower_ch(const ctype_char *this, char ch)
1568 {
1569     TRACE("(%p %c)\n", this, ch);
1570     return _Tolower(ch, &this->ctype);
1571 }
1572
1573 /* ?do_tolower@?$ctype@D@std@@MBEPBDPADPBD@Z */
1574 /* ?do_tolower@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1575 #define call_ctype_char_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 4, \
1576         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1577 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower, 12)
1578 const char* __thiscall ctype_char_do_tolower(const ctype_char *this, char *first, const char *last)
1579 {
1580     TRACE("(%p %p %p)\n", this, first, last);
1581     for(; first<last; first++)
1582         *first = _Tolower(*first, &this->ctype);
1583     return last;
1584 }
1585
1586 /* ?tolower@?$ctype@D@std@@QBEDD@Z */
1587 /* ?tolower@?$ctype@D@std@@QEBADD@Z */
1588 DEFINE_THISCALL_WRAPPER(ctype_char_tolower_ch, 8)
1589 char __thiscall ctype_char_tolower_ch(const ctype_char *this, char ch)
1590 {
1591     TRACE("(%p %c)\n", this, ch);
1592     return call_ctype_char_do_tolower_ch(this, ch);
1593 }
1594
1595 /* ?tolower@?$ctype@D@std@@QBEPBDPADPBD@Z */
1596 /* ?tolower@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1597 DEFINE_THISCALL_WRAPPER(ctype_char_tolower, 12)
1598 const char* __thiscall ctype_char_tolower(const ctype_char *this, char *first, const char *last)
1599 {
1600     TRACE("(%p %p %p)\n", this, first, last);
1601     return call_ctype_char_do_tolower(this, first, last);
1602 }
1603
1604 /* _Toupper */
1605 int __cdecl _Toupper(int ch, const _Ctypevec *ctype)
1606 {
1607     unsigned int cp;
1608
1609     TRACE("%d %p\n", ch, ctype);
1610
1611     if(ctype)
1612         cp = ctype->page;
1613     else
1614         cp = ___lc_codepage_func();
1615
1616     /* Don't convert to unicode in case of C locale */
1617     if(!cp) {
1618         if(ch>='a' && ch<='z')
1619             ch = ch-'a'+'A';
1620         return ch;
1621     } else {
1622         WCHAR wide, upper;
1623         char str[2];
1624         int size;
1625
1626         if(ch > 255) {
1627             str[0] = (ch>>8) & 255;
1628             str[1] = ch & 255;
1629             size = 2;
1630         } else {
1631             str[0] = ch & 255;
1632             size = 1;
1633         }
1634
1635         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1636             return ch;
1637
1638         upper = toupperW(wide);
1639         if(upper == wide)
1640             return ch;
1641
1642         WideCharToMultiByte(cp, 0, &upper, 1, str, 2, NULL, NULL);
1643
1644         return str[0] + (str[1]<<8);
1645     }
1646 }
1647
1648 /* ?do_toupper@?$ctype@D@std@@MBEDD@Z */
1649 /* ?do_toupper@?$ctype@D@std@@MEBADD@Z */
1650 #define call_ctype_char_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 16, \
1651         char, (const ctype_char*, char), (this, ch))
1652 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper_ch, 8)
1653 char __thiscall ctype_char_do_toupper_ch(const ctype_char *this, char ch)
1654 {
1655     TRACE("(%p %c)\n", this, ch);
1656     return _Toupper(ch, &this->ctype);
1657 }
1658
1659 /* ?do_toupper@?$ctype@D@std@@MBEPBDPADPBD@Z */
1660 /* ?do_toupper@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1661 #define call_ctype_char_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 12, \
1662         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1663 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper, 12)
1664 const char* __thiscall ctype_char_do_toupper(const ctype_char *this,
1665         char *first, const char *last)
1666 {
1667     TRACE("(%p %p %p)\n", this, first, last);
1668     for(; first<last; first++)
1669         *first = _Toupper(*first, &this->ctype);
1670     return last;
1671 }
1672
1673 /* ?toupper@?$ctype@D@std@@QBEDD@Z */
1674 /* ?toupper@?$ctype@D@std@@QEBADD@Z */
1675 DEFINE_THISCALL_WRAPPER(ctype_char_toupper_ch, 8)
1676 char __thiscall ctype_char_toupper_ch(const ctype_char *this, char ch)
1677 {
1678     TRACE("(%p %c)\n", this, ch);
1679     return call_ctype_char_do_toupper_ch(this, ch);
1680 }
1681
1682 /* ?toupper@?$ctype@D@std@@QBEPBDPADPBD@Z */
1683 /* ?toupper@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1684 DEFINE_THISCALL_WRAPPER(ctype_char_toupper, 12)
1685 const char* __thiscall ctype_char_toupper(const ctype_char *this, char *first, const char *last)
1686 {
1687     TRACE("(%p %p %p)\n", this, first, last);
1688     return call_ctype_char_do_toupper(this, first, last);
1689 }
1690
1691 /* ?is@?$ctype@D@std@@QBE_NFD@Z */
1692 /* ?is@?$ctype@D@std@@QEBA_NFD@Z */
1693 DEFINE_THISCALL_WRAPPER(ctype_char_is_ch, 12)
1694 MSVCP_bool __thiscall ctype_char_is_ch(const ctype_char *this, short mask, char ch)
1695 {
1696     TRACE("(%p %x %c)\n", this, mask, ch);
1697     return (this->ctype.table[(unsigned char)ch] & mask) != 0;
1698 }
1699
1700 /* ?is@?$ctype@D@std@@QBEPBDPBD0PAF@Z */
1701 /* ?is@?$ctype@D@std@@QEBAPEBDPEBD0PEAF@Z */
1702 DEFINE_THISCALL_WRAPPER(ctype_char_is, 16)
1703 const char* __thiscall ctype_char_is(const ctype_char *this, const char *first, const char *last, short *dest)
1704 {
1705     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1706     for(; first<last; first++)
1707         *dest++ = this->ctype.table[(unsigned char)*first];
1708     return last;
1709 }
1710
1711 /* ?scan_is@?$ctype@D@std@@QBEPBDFPBD0@Z */
1712 /* ?scan_is@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1713 DEFINE_THISCALL_WRAPPER(ctype_char_scan_is, 16)
1714 const char* __thiscall ctype_char_scan_is(const ctype_char *this, short mask, const char *first, const char *last)
1715 {
1716     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1717     for(; first<last; first++)
1718         if(!ctype_char_is_ch(this, mask, *first))
1719             break;
1720     return first;
1721 }
1722
1723 /* ?scan_not@?$ctype@D@std@@QBEPBDFPBD0@Z */
1724 /* ?scan_not@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1725 DEFINE_THISCALL_WRAPPER(ctype_char_scan_not, 16)
1726 const char* __thiscall ctype_char_scan_not(const ctype_char *this, short mask, const char *first, const char *last)
1727 {
1728     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1729     for(; first<last; first++)
1730         if(ctype_char_is_ch(this, mask, *first))
1731             break;
1732     return first;
1733 }
1734
1735 /* ?table@?$ctype@D@std@@IBEPBFXZ */
1736 /* ?table@?$ctype@D@std@@IEBAPEBFXZ */
1737 DEFINE_THISCALL_WRAPPER(ctype_char_table, 4)
1738 const short* __thiscall ctype_char_table(const ctype_char *this)
1739 {
1740     TRACE("(%p)\n", this);
1741     return this->ctype.table;
1742 }
1743
1744 /* ?id@?$ctype@_W@std@@2V0locale@2@A */
1745 locale_id ctype_wchar_id = {0};
1746 /* ?id@?$ctype@G@std@@2V0locale@2@A */
1747 locale_id ctype_short_id = {0};
1748
1749 /* ??_7?$ctype@_W@std@@6B@ */
1750 extern const vtable_ptr MSVCP_ctype_wchar_vtable;
1751 /* ??_7?$ctype@G@std@@6B@ */
1752 extern const vtable_ptr MSVCP_ctype_short_vtable;
1753
1754 /* ?_Id_func@?$ctype@_W@std@@SAAAVid@locale@2@XZ */
1755 /* ?_Id_func@?$ctype@_W@std@@SAAEAVid@locale@2@XZ */
1756 locale_id* __cdecl ctype_wchar__Id_func(void)
1757 {
1758     TRACE("()\n");
1759     return &ctype_wchar_id;
1760 }
1761
1762 /* ?_Id_func@?$ctype@G@std@@SAAAVid@locale@2@XZ */
1763 /* ?_Id_func@?$ctype@G@std@@SAAEAVid@locale@2@XZ */
1764 locale_id* __cdecl ctype_short__Id_func(void)
1765 {
1766     TRACE("()\n");
1767     return &ctype_short_id;
1768 }
1769
1770 /* ?_Init@?$ctype@_W@std@@IAEXABV_Locinfo@2@@Z */
1771 /* ?_Init@?$ctype@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
1772 /* ?_Init@?$ctype@G@std@@IAEXABV_Locinfo@2@@Z */
1773 /* ?_Init@?$ctype@G@std@@IEAAXAEBV_Locinfo@2@@Z */
1774 DEFINE_THISCALL_WRAPPER(ctype_wchar__Init, 8)
1775 void __thiscall ctype_wchar__Init(ctype_wchar *this, _Locinfo *locinfo)
1776 {
1777     TRACE("(%p %p)\n", this, locinfo);
1778     _Locinfo__Getctype(locinfo, &this->ctype);
1779     _Locinfo__Getcvt(locinfo, &this->cvt);
1780 }
1781
1782 /* ??0?$ctype@_W@std@@QAE@ABV_Locinfo@1@I@Z */
1783 /* ??0?$ctype@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1784 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_locinfo, 12)
1785 ctype_wchar* __thiscall ctype_wchar_ctor_locinfo(ctype_wchar *this,
1786         _Locinfo *locinfo, MSVCP_size_t refs)
1787 {
1788     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1789     ctype_base_ctor_refs(&this->base, refs);
1790     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1791     ctype_wchar__Init(this, locinfo);
1792     return this;
1793 }
1794
1795 /* ??0?$ctype@G@std@@QAE@ABV_Locinfo@1@I@Z */
1796 /* ??0?$ctype@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1797 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_locinfo, 12)
1798 ctype_wchar* __thiscall ctype_short_ctor_locinfo(ctype_wchar *this,
1799         _Locinfo *locinfo, MSVCP_size_t refs)
1800 {
1801     ctype_wchar *ret = ctype_wchar_ctor_locinfo(this, locinfo, refs);
1802     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1803     return ret;
1804 }
1805
1806 /* ??0?$ctype@_W@std@@QAE@I@Z */
1807 /* ??0?$ctype@_W@std@@QEAA@_K@Z */
1808 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_refs, 8)
1809 ctype_wchar* __thiscall ctype_wchar_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1810 {
1811     _Locinfo locinfo;
1812
1813     TRACE("(%p %lu)\n", this, refs);
1814
1815     ctype_base_ctor_refs(&this->base, refs);
1816     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1817
1818     _Locinfo_ctor(&locinfo);
1819     ctype_wchar__Init(this, &locinfo);
1820     _Locinfo_dtor(&locinfo);
1821     return this;
1822 }
1823
1824 /* ??0?$ctype@G@std@@QAE@I@Z */
1825 /* ??0?$ctype@G@std@@QEAA@_K@Z */
1826 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_refs, 8)
1827 ctype_wchar* __thiscall ctype_short_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1828 {
1829     ctype_wchar *ret = ctype_wchar_ctor_refs(this, refs);
1830     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1831     return ret;
1832 }
1833
1834 /* ??0?$ctype@G@std@@IAE@PBDI@Z */
1835 /* ??0?$ctype@G@std@@IEAA@PEBD_K@Z */
1836 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_name, 12)
1837 ctype_wchar* __thiscall ctype_short_ctor_name(ctype_wchar *this,
1838     const char *name, MSVCP_size_t refs)
1839 {
1840     _Locinfo locinfo;
1841
1842     TRACE("(%p %s %lu)\n", this, debugstr_a(name), refs);
1843
1844     ctype_base_ctor_refs(&this->base, refs);
1845     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1846
1847     _Locinfo_ctor_cstr(&locinfo, name);
1848     ctype_wchar__Init(this, &locinfo);
1849     _Locinfo_dtor(&locinfo);
1850     return this;
1851 }
1852
1853 /* ??_F?$ctype@_W@std@@QAEXXZ */
1854 /* ??_F?$ctype@_W@std@@QEAAXXZ */
1855 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor, 4)
1856 ctype_wchar* __thiscall ctype_wchar_ctor(ctype_wchar *this)
1857 {
1858     TRACE("(%p)\n", this);
1859     return ctype_short_ctor_refs(this, 0);
1860 }
1861
1862 /* ??_F?$ctype@G@std@@QAEXXZ */
1863 /* ??_F?$ctype@G@std@@QEAAXXZ */
1864 DEFINE_THISCALL_WRAPPER(ctype_short_ctor, 4)
1865 ctype_wchar* __thiscall ctype_short_ctor(ctype_wchar *this)
1866 {
1867     ctype_wchar *ret = ctype_wchar_ctor(this);
1868     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1869     return ret;
1870 }
1871
1872 /* ??1?$ctype@_W@std@@MAE@XZ */
1873 /* ??1?$ctype@_W@std@@MEAA@XZ */
1874 /* ??1?$ctype@G@std@@MAE@XZ */
1875 /* ??1?$ctype@G@std@@MEAA@XZ */
1876 DEFINE_THISCALL_WRAPPER(ctype_wchar_dtor, 4)
1877 void __thiscall ctype_wchar_dtor(ctype_wchar *this)
1878 {
1879     TRACE("(%p)\n", this);
1880     if(this->ctype.delfl)
1881         free((void*)this->ctype.table);
1882 }
1883
1884 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_wchar_vector_dtor, 8)
1885 ctype_wchar* __thiscall MSVCP_ctype_wchar_vector_dtor(ctype_wchar *this, unsigned int flags)
1886 {
1887     TRACE("(%p %x)\n", this, flags);
1888     if(flags & 2) {
1889         /* we have an array, with the number of elements stored before the first object */
1890         int i, *ptr = (int *)this-1;
1891
1892         for(i=*ptr-1; i>=0; i--)
1893             ctype_wchar_dtor(this+i);
1894         MSVCRT_operator_delete(ptr);
1895     } else {
1896         ctype_wchar_dtor(this);
1897         if(flags & 1)
1898             MSVCRT_operator_delete(this);
1899     }
1900
1901     return this;
1902 }
1903
1904 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_short_vector_dtor, 8)
1905 ctype_wchar* __thiscall MSVCP_ctype_short_vector_dtor(ctype_wchar *this, unsigned int flags)
1906 {
1907     return MSVCP_ctype_wchar_vector_dtor(this, flags);
1908 }
1909
1910 /* _Wcrtomb */
1911 int __cdecl _Wcrtomb(char *s, wchar_t wch, int *state, const _Cvtvec *cvt)
1912 {
1913     int cp, size;
1914     BOOL def;
1915
1916     TRACE("%p %d %p %p\n", s, wch, state, cvt);
1917
1918     if(cvt)
1919         cp = cvt->page;
1920     else
1921         cp = ___lc_codepage_func();
1922
1923     if(!cp) {
1924         if(wch > 255) {
1925            *_errno() = EILSEQ;
1926            return -1;
1927         }
1928
1929         *s = wch & 255;
1930         return 1;
1931     }
1932
1933     size = WideCharToMultiByte(cp, 0, &wch, 1, s, MB_LEN_MAX, NULL, &def);
1934     if(!size || def) {
1935         *_errno() = EILSEQ;
1936         return -1;
1937     }
1938
1939     return size;
1940 }
1941
1942 /* ?_Donarrow@?$ctype@_W@std@@IBED_WD@Z */
1943 /* ?_Donarrow@?$ctype@_W@std@@IEBAD_WD@Z */
1944 /* ?_Donarrow@?$ctype@G@std@@IBEDGD@Z */
1945 /* ?_Donarrow@?$ctype@G@std@@IEBADGD@Z */
1946 DEFINE_THISCALL_WRAPPER(ctype_wchar__Donarrow, 12)
1947 char __thiscall ctype_wchar__Donarrow(const ctype_wchar *this, wchar_t ch, char dflt)
1948 {
1949     char buf[MB_LEN_MAX];
1950
1951     TRACE("(%p %d %d)\n", this, ch, dflt);
1952
1953     return _Wcrtomb(buf, ch, NULL, &this->cvt)==1 ? buf[0] : dflt;
1954 }
1955
1956 /* ?do_narrow@?$ctype@_W@std@@MBED_WD@Z */
1957 /* ?do_narrow@?$ctype@_W@std@@MEBAD_WD@Z */
1958 /* ?do_narrow@?$ctype@G@std@@MBEDGD@Z */
1959 /* ?do_narrow@?$ctype@G@std@@MEBADGD@Z */
1960 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow_ch, 12)
1961 #define call_ctype_wchar_do_narrow_ch(this, ch, dflt) CALL_VTBL_FUNC(this, 52, \
1962         char, (const ctype_wchar*, wchar_t, char), (this, ch, dflt))
1963 char __thiscall ctype_wchar_do_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
1964 {
1965     return ctype_wchar__Donarrow(this, ch, dflt);
1966 }
1967
1968 /* ?do_narrow@?$ctype@_W@std@@MBEPB_WPB_W0DPAD@Z */
1969 /* ?do_narrow@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD@Z */
1970 /* ?do_narrow@?$ctype@G@std@@MBEPBGPBG0DPAD@Z */
1971 /* ?do_narrow@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD@Z */
1972 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow, 20)
1973 #define call_ctype_wchar_do_narrow(this, first, last, dflt, dest) CALL_VTBL_FUNC(this, 48, \
1974         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*), \
1975         (this, first, last, dflt, dest))
1976 const wchar_t* __thiscall ctype_wchar_do_narrow(const ctype_wchar *this,
1977         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
1978 {
1979     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
1980     for(; first<last; first++)
1981         *dest++ = ctype_wchar__Donarrow(this, *first, dflt);
1982     return last;
1983 }
1984
1985 /* ?_Do_narrow_s@?$ctype@_W@std@@MBEPB_WPB_W0DPADI@Z */
1986 /* ?_Do_narrow_s@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD_K@Z */
1987 /* ?_Do_narrow_s@?$ctype@G@std@@MBEPBGPBG0DPADI@Z */
1988 /* ?_Do_narrow_s@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD_K@Z */
1989 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_narrow_s, 24)
1990 #define call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size) CALL_VTBL_FUNC(this, 56, \
1991         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*, MSVCP_size_t), \
1992         (this, first, last, dflt, dest, size))
1993 const wchar_t* __thiscall ctype_wchar__Do_narrow_s(const ctype_wchar *this,
1994         const wchar_t *first, const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
1995 {
1996     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
1997     /* This function converts all multi-byte characters to dflt,
1998      * thanks to it result size is known before converting */
1999     if(last-first > size)
2000         ctype_base__Xran();
2001     return ctype_wchar_do_narrow(this, first, last, dflt, dest);
2002 }
2003
2004 /* ?narrow@?$ctype@_W@std@@QBED_WD@Z */
2005 /* ?narrow@?$ctype@_W@std@@QEBAD_WD@Z */
2006 /* ?narrow@?$ctype@G@std@@QBEDGD@Z */
2007 /* ?narrow@?$ctype@G@std@@QEBADGD@Z */
2008 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow_ch, 12)
2009 char __thiscall ctype_wchar_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
2010 {
2011     TRACE("(%p %d %d)\n", this, ch, dflt);
2012     return call_ctype_wchar_do_narrow_ch(this, ch, dflt);
2013 }
2014
2015 /* ?narrow@?$ctype@_W@std@@QBEPB_WPB_W0DPAD@Z */
2016 /* ?narrow@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD@Z */
2017 /* ?narrow@?$ctype@G@std@@QBEPBGPBG0DPAD@Z */
2018 /* ?narrow@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD@Z */
2019 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow, 20)
2020 const wchar_t* __thiscall ctype_wchar_narrow(const ctype_wchar *this,
2021         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
2022 {
2023     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
2024     return call_ctype_wchar_do_narrow(this, first, last, dflt, dest);
2025 }
2026
2027 /* ?_Narrow_s@?$ctype@_W@std@@QBEPB_WPB_W0DPADI@Z */
2028 /* ?_Narrow_s@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD_K@Z */
2029 /* ?_Narrow_s@?$ctype@G@std@@QBEPBGPBG0DPADI@Z */
2030 /* ?_Narrow_s@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD_K@Z */
2031 DEFINE_THISCALL_WRAPPER(ctype_wchar__Narrow_s, 24)
2032 const wchar_t* __thiscall ctype_wchar__Narrow_s(const ctype_wchar *this, const wchar_t *first,
2033         const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
2034 {
2035     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
2036     return call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size);
2037 }
2038
2039 /* _Mbrtowc */
2040 int __cdecl _Mbrtowc(wchar_t *out, const char *in, MSVCP_size_t len, int *state, const _Cvtvec *cvt)
2041 {
2042     int i, cp;
2043     CPINFO cp_info;
2044     BOOL is_lead;
2045
2046     TRACE("(%p %p %lu %p %p)\n", out, in, len, state, cvt);
2047
2048     if(!len)
2049         return 0;
2050
2051     if(cvt)
2052         cp = cvt->page;
2053     else
2054         cp = ___lc_codepage_func();
2055
2056     if(!cp) {
2057         if(out)
2058             *out = (unsigned char)*in;
2059
2060         *state = 0;
2061         return *in ? 1 : 0;
2062     }
2063
2064     if(*state) {
2065         ((char*)state)[1] = *in;
2066
2067         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, (char*)state, 2, out, out ? 1 : 0)) {
2068             *state = 0;
2069             *_errno() = EILSEQ;
2070             return -1;
2071         }
2072
2073         *state = 0;
2074         return 2;
2075     }
2076
2077     GetCPInfo(cp, &cp_info);
2078     is_lead = FALSE;
2079     for(i=0; i<MAX_LEADBYTES; i+=2) {
2080         if(!cp_info.LeadByte[i+1])
2081             break;
2082         if((unsigned char)*in>=cp_info.LeadByte[i] && (unsigned char)*in<=cp_info.LeadByte[i+1]) {
2083             is_lead = TRUE;
2084             break;
2085         }
2086     }
2087
2088     if(is_lead) {
2089         if(len == 1) {
2090             *state = (unsigned char)*in;
2091             return -2;
2092         }
2093
2094         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 2, out, out ? 1 : 0)) {
2095             *_errno() = EILSEQ;
2096             return -1;
2097         }
2098         return 2;
2099     }
2100
2101     if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 1, out, out ? 1 : 0)) {
2102         *_errno() = EILSEQ;
2103         return -1;
2104     }
2105     return 1;
2106 }
2107
2108 /* ?_Dowiden@?$ctype@_W@std@@IBE_WD@Z */
2109 /* ?_Dowiden@?$ctype@_W@std@@IEBA_WD@Z */
2110 /* ?_Dowiden@?$ctype@G@std@@IBEGD@Z */
2111 /* ?_Dowiden@?$ctype@G@std@@IEBAGD@Z */
2112 DEFINE_THISCALL_WRAPPER(ctype_wchar__Dowiden, 8)
2113 wchar_t __thiscall ctype_wchar__Dowiden(const ctype_wchar *this, char ch)
2114 {
2115     wchar_t ret;
2116     int state = 0;
2117     TRACE("(%p %d)\n", this, ch);
2118     return _Mbrtowc(&ret, &ch, 1, &state, &this->cvt)<0 ? WEOF : ret;
2119 }
2120
2121 /* ?do_widen@?$ctype@_W@std@@MBE_WD@Z */
2122 /* ?do_widen@?$ctype@_W@std@@MEBA_WD@Z */
2123 /* ?do_widen@?$ctype@G@std@@MBEGD@Z */
2124 /* ?do_widen@?$ctype@G@std@@MEBAGD@Z */
2125 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen_ch, 8)
2126 #define call_ctype_wchar_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 40, \
2127         wchar_t, (const ctype_wchar*, char), (this, ch))
2128 wchar_t __thiscall ctype_wchar_do_widen_ch(const ctype_wchar *this, char ch)
2129 {
2130     return ctype_wchar__Dowiden(this, ch);
2131 }
2132
2133 /* ?do_widen@?$ctype@_W@std@@MBEPBDPBD0PA_W@Z */
2134 /* ?do_widen@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W@Z */
2135 /* ?do_widen@?$ctype@G@std@@MBEPBDPBD0PAG@Z */
2136 /* ?do_widen@?$ctype@G@std@@MEBAPEBDPEBD0PEAG@Z */
2137 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen, 16)
2138 #define call_ctype_wchar_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 36, \
2139         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*), \
2140         (this, first, last, dest))
2141 const char* __thiscall ctype_wchar_do_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     for(; first<last; first++)
2146         *dest++ = ctype_wchar__Dowiden(this, *first);
2147     return last;
2148 }
2149
2150 /* ?_Do_widen_s@?$ctype@_W@std@@MBEPBDPBD0PA_WI@Z */
2151 /* ?_Do_widen_s@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W_K@Z */
2152 /* ?_Do_widen_s@?$ctype@G@std@@MBEPBDPBD0PAGI@Z */
2153 /* ?_Do_widen_s@?$ctype@G@std@@MEBAPEBDPEBD0PEAG_K@Z */
2154 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_widen_s, 20)
2155 #define call_ctype_wchar__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 44, \
2156         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*, MSVCP_size_t), \
2157         (this, first, last, dest, size))
2158 const char* __thiscall ctype_wchar__Do_widen_s(const ctype_wchar *this,
2159         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2160 {
2161     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2162     /* This function converts all multi-byte characters to WEOF,
2163      * thanks to it result size is known before converting */
2164     if(size < last-first)
2165         ctype_base__Xran();
2166     return ctype_wchar_do_widen(this, first, last, dest);
2167 }
2168
2169 /* ?widen@?$ctype@_W@std@@QBE_WD@Z */
2170 /* ?widen@?$ctype@_W@std@@QEBA_WD@Z */
2171 /* ?widen@?$ctype@G@std@@QBEGD@Z */
2172 /* ?widen@?$ctype@G@std@@QEBAGD@Z */
2173 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen_ch, 8)
2174 wchar_t __thiscall ctype_wchar_widen_ch(const ctype_wchar *this, char ch)
2175 {
2176     TRACE("(%p %d)\n", this, ch);
2177     return call_ctype_wchar_do_widen_ch(this, ch);
2178 }
2179
2180 /* ?widen@?$ctype@_W@std@@QBEPBDPBD0PA_W@Z */
2181 /* ?widen@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W@Z */
2182 /* ?widen@?$ctype@G@std@@QBEPBDPBD0PAG@Z */
2183 /* ?widen@?$ctype@G@std@@QEBAPEBDPEBD0PEAG@Z */
2184 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen, 16)
2185 const char* __thiscall ctype_wchar_widen(const ctype_wchar *this,
2186         const char *first, const char *last, wchar_t *dest)
2187 {
2188     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2189     return call_ctype_wchar_do_widen(this, first, last, dest);
2190 }
2191
2192 /* ?_Widen_s@?$ctype@_W@std@@QBEPBDPBD0PA_WI@Z */
2193 /* ?_Widen_s@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W_K@Z */
2194 /* ?_Widen_s@?$ctype@G@std@@QBEPBDPBD0PAGI@Z */
2195 /* ?_Widen_s@?$ctype@G@std@@QEBAPEBDPEBD0PEAG_K@Z */
2196 DEFINE_THISCALL_WRAPPER(ctype_wchar__Widen_s, 20)
2197 const char* __thiscall ctype_wchar__Widen_s(const ctype_wchar *this,
2198         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2199 {
2200     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2201     return call_ctype_wchar__Do_widen_s(this, first, last, dest, size);
2202 }
2203
2204 /* ?_Getcat@?$ctype@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2205 /* ?_Getcat@?$ctype@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2206 MSVCP_size_t __cdecl ctype_wchar__Getcat(const locale_facet **facet, const locale *loc)
2207 {
2208     TRACE("(%p %p)\n", facet, loc);
2209
2210     if(facet && !*facet) {
2211         _Locinfo locinfo;
2212
2213         *facet = MSVCRT_operator_new(sizeof(ctype_wchar));
2214         if(!*facet) {
2215             ERR("Out of memory\n");
2216             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2217             return 0;
2218         }
2219
2220         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
2221         ctype_wchar_ctor_locinfo((ctype_wchar*)*facet, &locinfo, 0);
2222         _Locinfo_dtor(&locinfo);
2223     }
2224
2225     return LC_CTYPE;
2226 }
2227
2228 /* ?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2229 /* ?_Getcat@?$ctype@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2230 MSVCP_size_t __cdecl ctype_short__Getcat(const locale_facet **facet, const locale *loc)
2231 {
2232     if(facet && !*facet) {
2233         ctype_wchar__Getcat(facet, loc);
2234         (*(locale_facet**)facet)->vtable = &MSVCP_ctype_short_vtable;
2235     }
2236
2237     return LC_CTYPE;
2238 }
2239
2240 /* _Towlower */
2241 wchar_t __cdecl _Towlower(wchar_t ch, const _Ctypevec *ctype)
2242 {
2243     TRACE("(%d %p)\n", ch, ctype);
2244     return tolowerW(ch);
2245 }
2246
2247 ctype_wchar* ctype_wchar_use_facet(const locale *loc)
2248 {
2249     static ctype_wchar *obj = NULL;
2250
2251     _Lockit lock;
2252     const locale_facet *fac;
2253
2254     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2255     fac = locale__Getfacet(loc, ctype_wchar_id.id);
2256     if(fac) {
2257         _Lockit_dtor(&lock);
2258         return (ctype_wchar*)fac;
2259     }
2260
2261     if(obj)
2262         return obj;
2263
2264     ctype_wchar__Getcat(&fac, loc);
2265     obj = (ctype_wchar*)fac;
2266     locale_facet__Incref(&obj->base.facet);
2267     locale_facet_register(&obj->base.facet);
2268     _Lockit_dtor(&lock);
2269
2270     return obj;
2271 }
2272
2273 /* ?do_tolower@?$ctype@_W@std@@MBE_W_W@Z */
2274 /* ?do_tolower@?$ctype@_W@std@@MEBA_W_W@Z */
2275 /* ?do_tolower@?$ctype@G@std@@MBEGG@Z */
2276 /* ?do_tolower@?$ctype@G@std@@MEBAGG@Z */
2277 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower_ch, 8)
2278 #define call_ctype_wchar_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
2279         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2280 wchar_t __thiscall ctype_wchar_do_tolower_ch(const ctype_wchar *this, wchar_t ch)
2281 {
2282     return _Towlower(ch, &this->ctype);
2283 }
2284
2285 /* ?do_tolower@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2286 /* ?do_tolower@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2287 /* ?do_tolower@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2288 /* ?do_tolower@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2289 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower, 12)
2290 #define call_ctype_wchar_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 20, \
2291         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2292         (this, first, last))
2293 const wchar_t* __thiscall ctype_wchar_do_tolower(const ctype_wchar *this,
2294         wchar_t *first, const wchar_t *last)
2295 {
2296     TRACE("(%p %p %p)\n", this, first, last);
2297     for(; first<last; first++)
2298         *first = _Towlower(*first, &this->ctype);
2299     return last;
2300 }
2301
2302 /* ?tolower@?$ctype@_W@std@@QBE_W_W@Z */
2303 /* ?tolower@?$ctype@_W@std@@QEBA_W_W@Z */
2304 /* ?tolower@?$ctype@G@std@@QBEGG@Z */
2305 /* ?tolower@?$ctype@G@std@@QEBAGG@Z */
2306 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower_ch, 8)
2307 wchar_t __thiscall ctype_wchar_tolower_ch(const ctype_wchar *this, wchar_t ch)
2308 {
2309     TRACE("(%p %d)\n", this, ch);
2310     return call_ctype_wchar_do_tolower_ch(this, ch);
2311 }
2312
2313 /* ?tolower@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2314 /* ?tolower@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2315 /* ?tolower@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2316 /* ?tolower@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2317 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower, 12)
2318 const wchar_t* __thiscall ctype_wchar_tolower(const ctype_wchar *this,
2319         wchar_t *first, const wchar_t *last)
2320 {
2321     TRACE("(%p %p %p)\n", this, first, last);
2322     return call_ctype_wchar_do_tolower(this, first, last);
2323 }
2324
2325 /* _Towupper */
2326 wchar_t __cdecl _Towupper(wchar_t ch, const _Ctypevec *ctype)
2327 {
2328     TRACE("(%d %p)\n", ch, ctype);
2329     return toupperW(ch);
2330 }
2331
2332 /* ?do_toupper@?$ctype@_W@std@@MBE_W_W@Z */
2333 /* ?do_toupper@?$ctype@_W@std@@MEBA_W_W@Z */
2334 /* ?do_toupper@?$ctype@G@std@@MBEGG@Z */
2335 /* ?do_toupper@?$ctype@G@std@@MEBAGG@Z */
2336 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper_ch, 8)
2337 #define call_ctype_wchar_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 32, \
2338         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2339 wchar_t __thiscall ctype_wchar_do_toupper_ch(const ctype_wchar *this, wchar_t ch)
2340 {
2341     return _Towupper(ch, &this->ctype);
2342 }
2343
2344 /* ?do_toupper@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2345 /* ?do_toupper@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2346 /* ?do_toupper@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2347 /* ?do_toupper@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2348 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper, 12)
2349 #define call_ctype_wchar_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 28, \
2350         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2351         (this, first, last))
2352 const wchar_t* __thiscall ctype_wchar_do_toupper(const ctype_wchar *this,
2353         wchar_t *first, const wchar_t *last)
2354 {
2355     TRACE("(%p %p %p)\n", this, first, last);
2356     for(; first<last; first++)
2357         *first = _Towupper(*first, &this->ctype);
2358     return last;
2359 }
2360
2361 /* ?toupper@?$ctype@_W@std@@QBE_W_W@Z */
2362 /* ?toupper@?$ctype@_W@std@@QEBA_W_W@Z */
2363 /* ?toupper@?$ctype@G@std@@QBEGG@Z */
2364 /* ?toupper@?$ctype@G@std@@QEBAGG@Z */
2365 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper_ch, 8)
2366 wchar_t __thiscall ctype_wchar_toupper_ch(const ctype_wchar *this, wchar_t ch)
2367 {
2368     TRACE("(%p %d)\n", this, ch);
2369     return call_ctype_wchar_do_toupper_ch(this, ch);
2370 }
2371
2372 /* ?toupper@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2373 /* ?toupper@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2374 /* ?toupper@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2375 /* ?toupper@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2376 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper, 12)
2377 const wchar_t* __thiscall ctype_wchar_toupper(const ctype_wchar *this,
2378         wchar_t *first, const wchar_t *last)
2379 {
2380     TRACE("(%p %p %p)\n", this, first, last);
2381     return call_ctype_wchar_do_toupper(this, first, last);
2382 }
2383
2384 /* _Getwctypes */
2385 const wchar_t* __cdecl _Getwctypes(const wchar_t *first, const wchar_t *last,
2386         short *mask, const _Ctypevec *ctype)
2387 {
2388     TRACE("(%p %p %p %p)\n", first, last, mask, ctype);
2389     GetStringTypeW(CT_CTYPE1, first, last-first, (WORD*)mask);
2390     return last;
2391 }
2392
2393 /* _Getwctype */
2394 short __cdecl _Getwctype(wchar_t ch, const _Ctypevec *ctype)
2395 {
2396     short mask = 0;
2397     _Getwctypes(&ch, &ch+1, &mask, ctype);
2398     return mask;
2399 }
2400
2401 /* ?do_is@?$ctype@_W@std@@MBE_NF_W@Z */
2402 /* ?do_is@?$ctype@_W@std@@MEBA_NF_W@Z */
2403 /* ?do_is@?$ctype@G@std@@MBE_NFG@Z */
2404 /* ?do_is@?$ctype@G@std@@MEBA_NFG@Z */
2405 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is_ch, 12)
2406 #define call_ctype_wchar_do_is_ch(this, mask, ch) CALL_VTBL_FUNC(this, 8, \
2407         MSVCP_bool, (const ctype_wchar*, short, wchar_t), (this, mask, ch))
2408 MSVCP_bool __thiscall ctype_wchar_do_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2409 {
2410     TRACE("(%p %x %d)\n", this, mask, ch);
2411     return (_Getwctype(ch, &this->ctype) & mask) != 0;
2412 }
2413
2414 /* ?do_is@?$ctype@_W@std@@MBEPB_WPB_W0PAF@Z */
2415 /* ?do_is@?$ctype@_W@std@@MEBAPEB_WPEB_W0PEAF@Z */
2416 /* ?do_is@?$ctype@G@std@@MBEPBGPBG0PAF@Z */
2417 /* ?do_is@?$ctype@G@std@@MEBAPEBGPEBG0PEAF@Z */
2418 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is, 16)
2419 #define call_ctype_wchar_do_is(this, first, last, dest) CALL_VTBL_FUNC(this, 4, \
2420         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, short*), \
2421         (this, first, last, dest))
2422 const wchar_t* __thiscall ctype_wchar_do_is(const ctype_wchar *this,
2423         const wchar_t *first, const wchar_t *last, short *dest)
2424 {
2425     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2426     return _Getwctypes(first, last, dest, &this->ctype);
2427 }
2428
2429 /* ?is@?$ctype@_W@std@@QBE_NF_W@Z */
2430 /* ?is@?$ctype@_W@std@@QEBA_NF_W@Z */
2431 /* ?is@?$ctype@G@std@@QBE_NFG@Z */
2432 /* ?is@?$ctype@G@std@@QEBA_NFG@Z */
2433 DEFINE_THISCALL_WRAPPER(ctype_wchar_is_ch, 12)
2434 MSVCP_bool __thiscall ctype_wchar_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2435 {
2436     TRACE("(%p %x %d)\n", this, mask, ch);
2437     return call_ctype_wchar_do_is_ch(this, mask, ch);
2438 }
2439
2440 /* ?is@?$ctype@_W@std@@QBEPB_WPB_W0PAF@Z */
2441 /* ?is@?$ctype@_W@std@@QEBAPEB_WPEB_W0PEAF@Z */
2442 /* ?is@?$ctype@G@std@@QBEPBGPBG0PAF@Z */
2443 /* ?is@?$ctype@G@std@@QEBAPEBGPEBG0PEAF@Z */
2444 DEFINE_THISCALL_WRAPPER(ctype_wchar_is, 16)
2445 const wchar_t* __thiscall ctype_wchar_is(const ctype_wchar *this,
2446         const wchar_t *first, const wchar_t *last, short *dest)
2447 {
2448     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2449     return call_ctype_wchar_do_is(this, first, last, dest);
2450 }
2451
2452 /* ?do_scan_is@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2453 /* ?do_scan_is@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2454 /* ?do_scan_is@?$ctype@G@std@@MBEPBGFPBG0@Z */
2455 /* ?do_scan_is@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2456 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_is, 16)
2457 #define call_ctype_wchar_do_scan_is(this, mask, first, last) CALL_VTBL_FUNC(this, 12, \
2458         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2459         (this, mask, first, last))
2460 const wchar_t* __thiscall ctype_wchar_do_scan_is(const ctype_wchar *this,
2461         short mask, const wchar_t *first, const wchar_t *last)
2462 {
2463     TRACE("(%p %d %p %p)\n", this, mask, first, last);
2464     for(; first<last; first++)
2465         if(!ctype_wchar_is_ch(this, mask, *first))
2466             break;
2467     return first;
2468 }
2469
2470 /* ?scan_is@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2471 /* ?scan_is@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2472 /* ?scan_is@?$ctype@G@std@@QBEPBGFPBG0@Z */
2473 /* ?scan_is@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2474 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_is, 16)
2475 const wchar_t* __thiscall ctype_wchar_scan_is(const ctype_wchar *this,
2476         short mask, const wchar_t *first, const wchar_t *last)
2477 {
2478     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2479     return call_ctype_wchar_do_scan_is(this, mask, first, last);
2480 }
2481
2482 /* ?do_scan_not@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2483 /* ?do_scan_not@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2484 /* ?do_scan_not@?$ctype@G@std@@MBEPBGFPBG0@Z */
2485 /* ?do_scan_not@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2486 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_not, 16)
2487 #define call_ctype_wchar_do_scan_not(this, mask, first, last) CALL_VTBL_FUNC(this, 16, \
2488         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2489         (this, mask, first, last))
2490 const wchar_t* __thiscall ctype_wchar_do_scan_not(const ctype_wchar *this,
2491         short mask, const wchar_t *first, const wchar_t *last)
2492 {
2493     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2494     for(; first<last; first++)
2495         if(ctype_wchar_is_ch(this, mask, *first))
2496             break;
2497     return first;
2498 }
2499
2500 /* ?scan_not@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2501 /* ?scan_not@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2502 /* ?scan_not@?$ctype@G@std@@QBEPBGFPBG0@Z */
2503 /* ?scan_not@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2504 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_not, 16)
2505 const wchar_t* __thiscall ctype_wchar_scan_not(const ctype_wchar *this,
2506         short mask, const wchar_t *first, const wchar_t *last)
2507 {
2508     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2509     return call_ctype_wchar_do_scan_not(this, mask, first, last);
2510 }
2511
2512 /* ??_7codecvt_base@std@@6B@ */
2513 extern const vtable_ptr MSVCP_codecvt_base_vtable;
2514
2515 /* ??0codecvt_base@std@@QAE@I@Z */
2516 /* ??0codecvt_base@std@@QEAA@_K@Z */
2517 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor_refs, 8)
2518 codecvt_base* __thiscall codecvt_base_ctor_refs(codecvt_base *this, MSVCP_size_t refs)
2519 {
2520     TRACE("(%p %lu)\n", this, refs);
2521     locale_facet_ctor_refs(&this->facet, refs);
2522     this->facet.vtable = &MSVCP_codecvt_base_vtable;
2523     return this;
2524 }
2525
2526 /* ??_Fcodecvt_base@std@@QAEXXZ */
2527 /* ??_Fcodecvt_base@std@@QEAAXXZ */
2528 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor, 4)
2529 codecvt_base* __thiscall codecvt_base_ctor(codecvt_base *this)
2530 {
2531     return codecvt_base_ctor_refs(this, 0);
2532 }
2533
2534 /* ??1codecvt_base@std@@UAE@XZ */
2535 /* ??1codecvt_base@std@@UEAA@XZ */
2536 DEFINE_THISCALL_WRAPPER(codecvt_base_dtor, 4)
2537 void __thiscall codecvt_base_dtor(codecvt_base *this)
2538 {
2539     TRACE("(%p)\n", this);
2540     locale_facet_dtor(&this->facet);
2541 }
2542
2543 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_base_vector_dtor, 8)
2544 codecvt_base* __thiscall MSVCP_codecvt_base_vector_dtor(codecvt_base *this, unsigned int flags)
2545 {
2546     TRACE("(%p %x)\n", this, flags);
2547     if(flags & 2) {
2548         /* we have an array, with the number of elements stored before the first object */
2549         int i, *ptr = (int *)this-1;
2550
2551         for(i=*ptr-1; i>=0; i--)
2552             codecvt_base_dtor(this+i);
2553         MSVCRT_operator_delete(ptr);
2554     } else {
2555         codecvt_base_dtor(this);
2556         if(flags & 1)
2557             MSVCRT_operator_delete(this);
2558     }
2559
2560     return this;
2561 }
2562
2563 /* ?do_always_noconv@codecvt_base@std@@MBE_NXZ */
2564 /* ?do_always_noconv@codecvt_base@std@@MEBA_NXZ */
2565 #define call_codecvt_base_do_always_noconv(this) CALL_VTBL_FUNC(this, 4, \
2566         MSVCP_bool, (const codecvt_base*), (this))
2567 DEFINE_THISCALL_WRAPPER(codecvt_base_do_always_noconv, 4)
2568 MSVCP_bool __thiscall codecvt_base_do_always_noconv(const codecvt_base *this)
2569 {
2570     TRACE("(%p)\n", this);
2571     return TRUE;
2572 }
2573
2574 /* ?always_noconv@codecvt_base@std@@QBE_NXZ */
2575 /* ?always_noconv@codecvt_base@std@@QEBA_NXZ */
2576 DEFINE_THISCALL_WRAPPER(codecvt_base_always_noconv, 4)
2577 MSVCP_bool __thiscall codecvt_base_always_noconv(const codecvt_base *this)
2578 {
2579     TRACE("(%p)\n", this);
2580     return call_codecvt_base_do_always_noconv(this);
2581 }
2582
2583 /* ?do_max_length@codecvt_base@std@@MBEHXZ */
2584 /* ?do_max_length@codecvt_base@std@@MEBAHXZ */
2585 #define call_codecvt_base_do_max_length(this) CALL_VTBL_FUNC(this, 8, \
2586         int, (const codecvt_base*), (this))
2587 DEFINE_THISCALL_WRAPPER(codecvt_base_do_max_length, 4)
2588 int __thiscall codecvt_base_do_max_length(const codecvt_base *this)
2589 {
2590     TRACE("(%p)\n", this);
2591     return 1;
2592 }
2593
2594 /* ?max_length@codecvt_base@std@@QBEHXZ */
2595 /* ?max_length@codecvt_base@std@@QEBAHXZ */
2596 DEFINE_THISCALL_WRAPPER(codecvt_base_max_length, 4)
2597 int __thiscall codecvt_base_max_length(const codecvt_base *this)
2598 {
2599     TRACE("(%p)\n", this);
2600     return call_codecvt_base_do_max_length(this);
2601 }
2602
2603 /* ?do_encoding@codecvt_base@std@@MBEHXZ */
2604 /* ?do_encoding@codecvt_base@std@@MEBAHXZ */
2605 #define call_codecvt_base_do_encoding(this) CALL_VTBL_FUNC(this, 12, \
2606         int, (const codecvt_base*), (this))
2607 DEFINE_THISCALL_WRAPPER(codecvt_base_do_encoding, 4)
2608 int __thiscall codecvt_base_do_encoding(const codecvt_base *this)
2609 {
2610     TRACE("(%p)\n", this);
2611     return 1;
2612 }
2613
2614 /* ?encoding@codecvt_base@std@@QBEHXZ */
2615 /* ?encoding@codecvt_base@std@@QEBAHXZ */
2616 DEFINE_THISCALL_WRAPPER(codecvt_base_encoding, 4)
2617 int __thiscall codecvt_base_encoding(const codecvt_base *this)
2618 {
2619     TRACE("(%p)\n", this);
2620     return call_codecvt_base_do_encoding(this);
2621 }
2622
2623 /* ?id@?$codecvt@DDH@std@@2V0locale@2@A */
2624 locale_id codecvt_char_id = {0};
2625
2626 /* ??_7?$codecvt@DDH@std@@6B@ */
2627 extern const vtable_ptr MSVCP_codecvt_char_vtable;
2628
2629 /* ?_Init@?$codecvt@DDH@std@@IAEXABV_Locinfo@2@@Z */
2630 /* ?_Init@?$codecvt@DDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2631 DEFINE_THISCALL_WRAPPER(codecvt_char__Init, 8)
2632 void __thiscall codecvt_char__Init(codecvt_char *this, const _Locinfo *locinfo)
2633 {
2634     TRACE("(%p %p)\n", this, locinfo);
2635 }
2636
2637 /* ??0?$codecvt@DDH@std@@QAE@ABV_Locinfo@1@I@Z */
2638 /* ??0?$codecvt@DDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2639 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_locinfo, 12)
2640 codecvt_char* __thiscall codecvt_char_ctor_locinfo(codecvt_char *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2641 {
2642     TRACE("(%p %p %lu)\n", this, locinfo, refs);
2643     codecvt_base_ctor_refs(&this->base, refs);
2644     this->base.facet.vtable = &MSVCP_codecvt_char_vtable;
2645     return this;
2646 }
2647
2648 /* ??0?$codecvt@DDH@std@@QAE@I@Z */
2649 /* ??0?$codecvt@DDH@std@@QEAA@_K@Z */
2650 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_refs, 8)
2651 codecvt_char* __thiscall codecvt_char_ctor_refs(codecvt_char *this, MSVCP_size_t refs)
2652 {
2653     return codecvt_char_ctor_locinfo(this, NULL, refs);
2654 }
2655
2656 /* ??_F?$codecvt@DDH@std@@QAEXXZ */
2657 /* ??_F?$codecvt@DDH@std@@QEAAXXZ */
2658 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor, 4)
2659 codecvt_char* __thiscall codecvt_char_ctor(codecvt_char *this)
2660 {
2661     return codecvt_char_ctor_locinfo(this, NULL, 0);
2662 }
2663
2664 /* ??1?$codecvt@DDH@std@@MAE@XZ */
2665 /* ??1?$codecvt@DDH@std@@MEAA@XZ */
2666 DEFINE_THISCALL_WRAPPER(codecvt_char_dtor, 4)
2667 void __thiscall codecvt_char_dtor(codecvt_char *this)
2668 {
2669     TRACE("(%p)\n", this);
2670     codecvt_base_dtor(&this->base);
2671 }
2672
2673 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_char_vector_dtor, 8)
2674 codecvt_char* __thiscall MSVCP_codecvt_char_vector_dtor(codecvt_char *this, unsigned int flags)
2675 {
2676     TRACE("(%p %x)\n", this, flags);
2677     if(flags & 2) {
2678         /* we have an array, with the number of elements stored before the first object */
2679         int i, *ptr = (int *)this-1;
2680
2681         for(i=*ptr-1; i>=0; i--)
2682             codecvt_char_dtor(this+i);
2683         MSVCRT_operator_delete(ptr);
2684     } else {
2685         codecvt_char_dtor(this);
2686         if(flags & 1)
2687             MSVCRT_operator_delete(this);
2688     }
2689
2690     return this;
2691 }
2692
2693 /* ?_Getcat@?$codecvt@DDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2694 /* ?_Getcat@?$codecvt@DDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2695 MSVCP_size_t __cdecl codecvt_char__Getcat(const locale_facet **facet, const locale *loc)
2696 {
2697     TRACE("(%p %p)\n", facet, loc);
2698
2699     if(facet && !*facet) {
2700         *facet = MSVCRT_operator_new(sizeof(codecvt_char));
2701         if(!*facet) {
2702             ERR("Out of memory\n");
2703             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2704             return 0;
2705         }
2706         codecvt_char_ctor((codecvt_char*)*facet);
2707     }
2708
2709     return LC_CTYPE;
2710 }
2711
2712 codecvt_char* codecvt_char_use_facet(const locale *loc)
2713 {
2714     static codecvt_char *obj = NULL;
2715
2716     _Lockit lock;
2717     const locale_facet *fac;
2718
2719     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2720     fac = locale__Getfacet(loc, codecvt_char_id.id);
2721     if(fac) {
2722         _Lockit_dtor(&lock);
2723         return (codecvt_char*)fac;
2724     }
2725
2726     if(obj)
2727         return obj;
2728
2729     codecvt_char__Getcat(&fac, loc);
2730     obj = (codecvt_char*)fac;
2731     locale_facet__Incref(&obj->base.facet);
2732     locale_facet_register(&obj->base.facet);
2733     _Lockit_dtor(&lock);
2734
2735     return obj;
2736 }
2737
2738 /* ?do_in@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2739 /* ?do_in@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2740 #define call_codecvt_char_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
2741     CALL_VTBL_FUNC(this, 16, int, \
2742             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2743             (this, state, from, from_end, from_next, to, to_end, to_next))
2744 DEFINE_THISCALL_WRAPPER(codecvt_char_do_in, 32)
2745 int __thiscall codecvt_char_do_in(const codecvt_char *this, int *state,
2746         const char *from, const char *from_end, const char **from_next,
2747         char *to, char *to_end, char **to_next)
2748 {
2749     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2750             from_next, to, to_end, to_next);
2751     *from_next = from;
2752     *to_next = to;
2753     return CODECVT_noconv;
2754 }
2755
2756 /* ?in@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2757 /* ?in@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2758 DEFINE_THISCALL_WRAPPER(codecvt_char_in, 32)
2759 int __thiscall codecvt_char_in(const codecvt_char *this, int *state,
2760         const char *from, const char *from_end, const char **from_next,
2761         char *to, char *to_end, char **to_next)
2762 {
2763     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2764             from_next, to, to_end, to_next);
2765     return call_codecvt_char_do_in(this, state, from, from_end, from_next,
2766             to, to_end, to_next);
2767 }
2768
2769 /* ?do_out@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2770 /* ?do_out@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2771 #define call_codecvt_char_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
2772     CALL_VTBL_FUNC(this, 20, int, \
2773             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2774             (this, state, from, from_end, from_next, to, to_end, to_next))
2775 DEFINE_THISCALL_WRAPPER(codecvt_char_do_out, 32)
2776 int __thiscall codecvt_char_do_out(const codecvt_char *this, int *state,
2777         const char *from, const char *from_end, const char **from_next,
2778         char *to, char *to_end, char **to_next)
2779 {
2780     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2781             from_end, from_next, to, to_end, to_next);
2782     *from_next = from;
2783     *to_next = to;
2784     return CODECVT_noconv;
2785 }
2786
2787 /* ?out@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2788 /* ?out@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2789 DEFINE_THISCALL_WRAPPER(codecvt_char_out, 32)
2790 int __thiscall codecvt_char_out(const codecvt_char *this, int *state,
2791         const char *from, const char *from_end, const char **from_next,
2792         char *to, char *to_end, char **to_next)
2793 {
2794     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2795             from_next, to, to_end, to_next);
2796     return call_codecvt_char_do_out(this, state, from, from_end, from_next,
2797             to, to_end, to_next);
2798 }
2799
2800 /* ?do_unshift@?$codecvt@DDH@std@@MBEHAAHPAD1AAPAD@Z */
2801 /* ?do_unshift@?$codecvt@DDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
2802 #define call_codecvt_char_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
2803         int, (const codecvt_char*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
2804 DEFINE_THISCALL_WRAPPER(codecvt_char_do_unshift, 20)
2805 int __thiscall codecvt_char_do_unshift(const codecvt_char *this,
2806         int *state, char *to, char *to_end, char **to_next)
2807 {
2808     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2809     *to_next = to;
2810     return CODECVT_noconv;
2811 }
2812
2813 /* ?unshift@?$codecvt@DDH@std@@QBEHAAHPAD1AAPAD@Z */
2814 /* ?unshift@?$codecvt@DDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
2815 DEFINE_THISCALL_WRAPPER(codecvt_char_unshift, 20)
2816 int __thiscall codecvt_char_unshift(const codecvt_char *this,
2817         int *state, char *to, char *to_end, char **to_next)
2818 {
2819     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2820     return call_codecvt_char_do_unshift(this, state, to, to_end, to_next);
2821 }
2822
2823 /* ?do_length@?$codecvt@DDH@std@@MBEHABHPBD1I@Z */
2824 /* ?do_length@?$codecvt@DDH@std@@MEBAHAEBHPEBD1_K@Z */
2825 #define call_codecvt_char_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
2826         int, (const codecvt_char*, const int*, const char*, const char*, MSVCP_size_t), \
2827         (this, state, from, from_end, max))
2828 DEFINE_THISCALL_WRAPPER(codecvt_char_do_length, 20)
2829 int __thiscall codecvt_char_do_length(const codecvt_char *this, const int *state,
2830         const char *from, const char *from_end, MSVCP_size_t max)
2831 {
2832     TRACE("(%p %p %p %p %lu)\n", this, state, from, from_end, max);
2833     return (from_end-from > max ? max : from_end-from);
2834 }
2835
2836 /* ?length@?$codecvt@DDH@std@@QBEHABHPBD1I@Z */
2837 /* ?length@?$codecvt@DDH@std@@QEBAHAEBHPEBD1_K@Z */
2838 DEFINE_THISCALL_WRAPPER(codecvt_char_length, 20)
2839 int __thiscall codecvt_char_length(const codecvt_char *this, const int *state,
2840         const char *from, const char *from_end, MSVCP_size_t max)
2841 {
2842     TRACE("(%p %p %p %p %lu)\n", this, state, from, from_end, max);
2843     return call_codecvt_char_do_length(this, state, from, from_end, max);
2844 }
2845
2846 /* ?id@?$codecvt@_WDH@std@@2V0locale@2@A */
2847 locale_id codecvt_wchar_id = {0};
2848 /* ?id@?$codecvt@GDH@std@@2V0locale@2@A */
2849 locale_id codecvt_short_id = {0};
2850
2851 /* ??_7?$codecvt@_WDH@std@@6B@ */
2852 extern const vtable_ptr MSVCP_codecvt_wchar_vtable;
2853 /* ??_7?$codecvt@GDH@std@@6B@ */
2854 extern const vtable_ptr MSVCP_codecvt_short_vtable;
2855
2856 /* ?_Init@?$codecvt@GDH@std@@IAEXABV_Locinfo@2@@Z */
2857 /* ?_Init@?$codecvt@GDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2858 /* ?_Init@?$codecvt@_WDH@std@@IAEXABV_Locinfo@2@@Z */
2859 /* ?_Init@?$codecvt@_WDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2860 DEFINE_THISCALL_WRAPPER(codecvt_wchar__Init, 8)
2861 void __thiscall codecvt_wchar__Init(codecvt_wchar *this, const _Locinfo *locinfo)
2862 {
2863     TRACE("(%p %p)\n", this, locinfo);
2864     _Locinfo__Getcvt(locinfo, &this->cvt);
2865 }
2866
2867 /* ??0?$codecvt@_WDH@std@@QAE@ABV_Locinfo@1@I@Z */
2868 /* ??0?$codecvt@_WDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2869 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor_locinfo, 12)
2870 codecvt_wchar* __thiscall codecvt_wchar_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2871 {
2872     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2873
2874     codecvt_base_ctor_refs(&this->base, refs);
2875     this->base.facet.vtable = &MSVCP_codecvt_wchar_vtable;
2876
2877     codecvt_wchar__Init(this, locinfo);
2878     return this;
2879 }
2880
2881 /* ??0?$codecvt@GDH@std@@QAE@ABV_Locinfo@1@I@Z */
2882 /* ??0?$codecvt@GDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2883 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_locinfo, 12)
2884 codecvt_wchar* __thiscall codecvt_short_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2885 {
2886     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2887
2888     codecvt_wchar_ctor_locinfo(this, locinfo, refs);
2889     this->base.facet.vtable = &MSVCP_codecvt_short_vtable;
2890     return this;
2891 }
2892
2893 /* ??0?$codecvt@_WDH@std@@QAE@I@Z */
2894 /* ??0?$codecvt@_WDH@std@@QEAA@_K@Z */
2895 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor_refs, 8)
2896 codecvt_wchar* __thiscall codecvt_wchar_ctor_refs(codecvt_wchar *this, MSVCP_size_t refs)
2897 {
2898     _Locinfo locinfo;
2899
2900     TRACE("(%p %ld)\n", this, refs);
2901
2902     _Locinfo_ctor(&locinfo);
2903     codecvt_wchar_ctor_locinfo(this, &locinfo, refs);
2904     _Locinfo_dtor(&locinfo);
2905     return this;
2906 }
2907
2908 /* ??0?$codecvt@GDH@std@@QAE@I@Z */
2909 /* ??0?$codecvt@GDH@std@@QEAA@_K@Z */
2910 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_refs, 8)
2911 codecvt_wchar* __thiscall codecvt_short_ctor_refs(codecvt_wchar *this, MSVCP_size_t refs)
2912 {
2913     _Locinfo locinfo;
2914
2915     TRACE("(%p %ld)\n", this, refs);
2916
2917     _Locinfo_ctor(&locinfo);
2918     codecvt_short_ctor_locinfo(this, &locinfo, refs);
2919     _Locinfo_dtor(&locinfo);
2920     return this;
2921 }
2922
2923 /* ??0?$codecvt@GDH@std@@IAE@PBDI@Z */
2924 /* ??0?$codecvt@GDH@std@@IEAA@PEBD_K@Z */
2925 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_name, 12)
2926 codecvt_wchar* __thiscall codecvt_short_ctor_name(codecvt_wchar *this, const char *name, MSVCP_size_t refs)
2927 {
2928     _Locinfo locinfo;
2929
2930     TRACE("(%p %s %ld)\n", this, name, refs);
2931
2932     _Locinfo_ctor_cstr(&locinfo, name);
2933     codecvt_short_ctor_locinfo(this, &locinfo, refs);
2934     _Locinfo_dtor(&locinfo);
2935     return this;
2936 }
2937
2938 /* ??_F?$codecvt@_WDH@std@@QAEXXZ */
2939 /* ??_F?$codecvt@_WDH@std@@QEAAXXZ */
2940 DEFINE_THISCALL_WRAPPER(codecvt_wchar_ctor, 4)
2941 codecvt_wchar* __thiscall codecvt_wchar_ctor(codecvt_wchar *this)
2942 {
2943     return codecvt_wchar_ctor_refs(this, 0);
2944 }
2945
2946 /* ??_F?$codecvt@GDH@std@@QAEXXZ */
2947 /* ??_F?$codecvt@GDH@std@@QEAAXXZ */
2948 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor, 4)
2949 codecvt_wchar* __thiscall codecvt_short_ctor(codecvt_wchar *this)
2950 {
2951     return codecvt_short_ctor_refs(this, 0);
2952 }
2953
2954 /* ??1?$codecvt@GDH@std@@MAE@XZ */
2955 /* ??1?$codecvt@GDH@std@@MEAA@XZ */
2956 /* ??1?$codecvt@_WDH@std@@MAE@XZ */
2957 /* ??1?$codecvt@_WDH@std@@MEAA@XZ */
2958 DEFINE_THISCALL_WRAPPER(codecvt_wchar_dtor, 4)
2959 void __thiscall codecvt_wchar_dtor(codecvt_wchar *this)
2960 {
2961     TRACE("(%p)\n", this);
2962     codecvt_base_dtor(&this->base);
2963 }
2964
2965 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_wchar_vector_dtor, 8)
2966 codecvt_wchar* __thiscall MSVCP_codecvt_wchar_vector_dtor(codecvt_wchar *this, unsigned int flags)
2967 {
2968     TRACE("(%p %x)\n", this, flags);
2969     if(flags & 2) {
2970         /* we have an array, with the number of elements stored before the first object */
2971         int i, *ptr = (int *)this-1;
2972
2973         for(i=*ptr-1; i>=0; i--)
2974             codecvt_wchar_dtor(this+i);
2975         MSVCRT_operator_delete(ptr);
2976     } else {
2977         codecvt_wchar_dtor(this);
2978         if(flags & 1)
2979             MSVCRT_operator_delete(this);
2980     }
2981
2982     return this;
2983 }
2984
2985 DEFINE_THISCALL_WRAPPER(MSVCP_codecvt_short_vector_dtor, 8)
2986 codecvt_wchar* __thiscall MSVCP_codecvt_short_vector_dtor(codecvt_wchar *this, unsigned int flags)
2987 {
2988     return MSVCP_codecvt_wchar_vector_dtor(this, flags);
2989 }
2990
2991 /* ?_Getcat@?$codecvt@_WDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2992 /* ?_Getcat@?$codecvt@_WDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2993 unsigned int __cdecl codecvt_wchar__Getcat(const locale_facet **facet, const locale *loc)
2994 {
2995     TRACE("(%p %p)\n", facet, loc);
2996
2997     if(facet && !*facet) {
2998         _Locinfo locinfo;
2999
3000         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
3001         if(!*facet) {
3002             ERR("Out of memory\n");
3003             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3004             return 0;
3005         }
3006
3007         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
3008         codecvt_wchar_ctor_locinfo((codecvt_wchar*)*facet, &locinfo, 0);
3009         _Locinfo_dtor(&locinfo);
3010     }
3011
3012     return LC_CTYPE;
3013 }
3014
3015 /* ?_Getcat@?$codecvt@GDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3016 /* ?_Getcat@?$codecvt@GDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3017 unsigned int __cdecl codecvt_short__Getcat(const locale_facet **facet, const locale *loc)
3018 {
3019     TRACE("(%p %p)\n", facet, loc);
3020
3021     if(facet && !*facet) {
3022         _Locinfo locinfo;
3023
3024         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
3025         if(!*facet) {
3026             ERR("Out of memory\n");
3027             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3028             return 0;
3029         }
3030
3031         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
3032         codecvt_short_ctor((codecvt_wchar*)*facet);
3033         _Locinfo_dtor(&locinfo);
3034     }
3035
3036     return LC_CTYPE;
3037 }
3038
3039 /* ?_Id_func@?$codecvt@_WDH@std@@SAAAVid@locale@2@XZ */
3040 /* ?_Id_func@?$codecvt@_WDH@std@@SAAEAVid@locale@2@XZ */
3041 locale_id* __cdecl codecvt_wchar__Id_func(void)
3042 {
3043     TRACE("()\n");
3044     return &codecvt_wchar_id;
3045 }
3046
3047 /* ?_Id_func@?$codecvt@GDH@std@@SAAAVid@locale@2@XZ */
3048 /* ?_Id_func@?$codecvt@GDH@std@@SAAEAVid@locale@2@XZ */
3049 locale_id* __cdecl codecvt_short__Id_func(void)
3050 {
3051     TRACE("()\n");
3052     return &codecvt_short_id;
3053 }
3054
3055 /* ?do_always_noconv@?$codecvt@GDH@std@@MBE_NXZ */
3056 /* ?do_always_noconv@?$codecvt@GDH@std@@MEBA_NXZ */
3057 /* ?do_always_noconv@?$codecvt@_WDH@std@@MBE_NXZ */
3058 /* ?do_always_noconv@?$codecvt@_WDH@std@@MEBA_NXZ */
3059 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_always_noconv, 4)
3060 MSVCP_bool __thiscall codecvt_wchar_do_always_noconv(const codecvt_wchar *this)
3061 {
3062     TRACE("(%p)\n", this);
3063     return FALSE;
3064 }
3065
3066 /* ?do_max_length@?$codecvt@GDH@std@@MBEHXZ */
3067 /* ?do_max_length@?$codecvt@GDH@std@@MEBAHXZ */
3068 /* ?do_max_length@?$codecvt@_WDH@std@@MBEHXZ */
3069 /* ?do_max_length@?$codecvt@_WDH@std@@MEBAHXZ */
3070 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_max_length, 4)
3071 int __thiscall codecvt_wchar_do_max_length(const codecvt_wchar *this)
3072 {
3073     TRACE("(%p)\n", this);
3074     return MB_LEN_MAX;
3075 }
3076
3077 /* ?do_in@?$codecvt@GDH@std@@MBEHAAHPBD1AAPBDPAG3AAPAG@Z */
3078 /* ?do_in@?$codecvt@GDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
3079 /* ?do_in@?$codecvt@_WDH@std@@MBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
3080 /* ?do_in@?$codecvt@_WDH@std@@MEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
3081 #define call_codecvt_wchar_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
3082     CALL_VTBL_FUNC(this, 16, int, \
3083             (const codecvt_wchar*, int*, const char*, const char*, const char**, wchar_t*, wchar_t*, wchar_t**), \
3084             (this, state, from, from_end, from_next, to, to_end, to_next))
3085 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_in, 32)
3086 int __thiscall codecvt_wchar_do_in(const codecvt_wchar *this, int *state,
3087         const char *from, const char *from_end, const char **from_next,
3088         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
3089 {
3090     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3091             from_end, from_next, to, to_end, to_next);
3092
3093     *from_next = from;
3094     *to_next = to;
3095
3096     while(*from_next!=from_end && *to_next!=to_end) {
3097         switch(_Mbrtowc(*to_next, *from_next, from_end-*from_next, state, &this->cvt)) {
3098         case -2:
3099             *from_next = from_end;
3100             return CODECVT_partial;
3101         case -1:
3102             return CODECVT_error;
3103         case 2:
3104             (*from_next)++;
3105             /* fall through */
3106         case 0:
3107         case 1:
3108             (*from_next)++;
3109             (*to_next)++;
3110         }
3111     }
3112
3113     return CODECVT_ok;
3114 }
3115
3116 /* ?in@?$codecvt@GDH@std@@QBEHAAHPBD1AAPBDPAG3AAPAG@Z */
3117 /* ?in@?$codecvt@GDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
3118 /* ?in@?$codecvt@_WDH@std@@QBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
3119 /* ?in@?$codecvt@_WDH@std@@QEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
3120 DEFINE_THISCALL_WRAPPER(codecvt_wchar_in, 32)
3121 int __thiscall codecvt_wchar_in(const codecvt_wchar *this, int *state,
3122         const char *from, const char *from_end, const char **from_next,
3123         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
3124 {
3125     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3126             from_end, from_next, to, to_end, to_next);
3127     return call_codecvt_wchar_do_in(this, state, from,
3128             from_end, from_next, to, to_end, to_next);
3129 }
3130
3131 /* ?do_out@?$codecvt@GDH@std@@MBEHAAHPBG1AAPBGPAD3AAPAD@Z */
3132 /* ?do_out@?$codecvt@GDH@std@@MEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
3133 /* ?do_out@?$codecvt@_WDH@std@@MBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
3134 /* ?do_out@?$codecvt@_WDH@std@@MEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
3135 #define call_codecvt_wchar_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
3136     CALL_VTBL_FUNC(this, 20, int, \
3137             (const codecvt_wchar*, int*, const wchar_t*, const wchar_t*, const wchar_t**, char*, char*, char**), \
3138             (this, state, from, from_end, from_next, to, to_end, to_next))
3139 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_out, 32)
3140 int __thiscall codecvt_wchar_do_out(const codecvt_wchar *this, int *state,
3141         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
3142         char *to, char *to_end, char **to_next)
3143 {
3144     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3145             from_end, from_next, to, to_end, to_next);
3146
3147     *from_next = from;
3148     *to_next = to;
3149
3150     while(*from_next!=from_end && *to_next!=to_end) {
3151         int old_state = *state, size;
3152         char buf[MB_LEN_MAX];
3153
3154         switch((size = _Wcrtomb(buf, **from_next, state, &this->cvt))) {
3155         case -1:
3156             return CODECVT_error;
3157         default:
3158             if(size > from_end-*from_next) {
3159                 *state = old_state;
3160                 return CODECVT_partial;
3161             }
3162
3163             (*from_next)++;
3164             (*to_next) += size;
3165         }
3166     }
3167
3168     return CODECVT_ok;
3169 }
3170
3171 /* ?out@?$codecvt@GDH@std@@QBEHAAHPBG1AAPBGPAD3AAPAD@Z */
3172 /* ?out@?$codecvt@GDH@std@@QEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
3173 /* ?out@?$codecvt@_WDH@std@@QBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
3174 /* ?out@?$codecvt@_WDH@std@@QEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
3175 DEFINE_THISCALL_WRAPPER(codecvt_wchar_out, 32)
3176 int __thiscall codecvt_wchar_out(const codecvt_wchar *this, int *state,
3177         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
3178         char *to, char *to_end, char **to_next)
3179 {
3180     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
3181             from_end, from_next, to, to_end, to_next);
3182     return call_codecvt_wchar_do_out(this, state, from,
3183             from_end, from_next, to, to_end, to_next);
3184 }
3185
3186 /* ?do_unshift@?$codecvt@GDH@std@@MBEHAAHPAD1AAPAD@Z */
3187 /* ?do_unshift@?$codecvt@GDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
3188 /* ?do_unshift@?$codecvt@_WDH@std@@MBEHAAHPAD1AAPAD@Z */
3189 /* ?do_unshift@?$codecvt@_WDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
3190 #define call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
3191         int, (const codecvt_wchar*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
3192 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_unshift, 20)
3193 int __thiscall codecvt_wchar_do_unshift(const codecvt_wchar *this,
3194         int *state, char *to, char *to_end, char **to_next)
3195 {
3196     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
3197     if(*state)
3198         WARN("unexpected state: %x\n", *state);
3199
3200     *to_next = to;
3201     return CODECVT_ok;
3202 }
3203
3204 /* ?unshift@?$codecvt@GDH@std@@QBEHAAHPAD1AAPAD@Z */
3205 /* ?unshift@?$codecvt@GDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
3206 /* ?unshift@?$codecvt@_WDH@std@@QBEHAAHPAD1AAPAD@Z */
3207 /* ?unshift@?$codecvt@_WDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
3208 DEFINE_THISCALL_WRAPPER(codecvt_wchar_unshift, 20)
3209 int __thiscall codecvt_wchar_unshift(const codecvt_wchar *this,
3210         int *state, char *to, char *to_end, char **to_next)
3211 {
3212     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
3213     return call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next);
3214 }
3215
3216 /* ?do_length@?$codecvt@GDH@std@@MBEHABHPBD1I@Z */
3217 /* ?do_length@?$codecvt@GDH@std@@MEBAHAEBHPEBD1_K@Z */
3218 /* ?do_length@?$codecvt@_WDH@std@@MBEHABHPBD1I@Z */
3219 /* ?do_length@?$codecvt@_WDH@std@@MEBAHAEBHPEBD1_K@Z */
3220 #define call_codecvt_wchar_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
3221         int, (const codecvt_wchar*, const int*, const char*, const char*, MSVCP_size_t), \
3222         (this, state, from, from_end, max))
3223 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_length, 20)
3224 int __thiscall codecvt_wchar_do_length(const codecvt_wchar *this, const int *state,
3225         const char *from, const char *from_end, MSVCP_size_t max)
3226 {
3227     int tmp_state = *state, ret=0;
3228
3229     TRACE("(%p %p %p %p %ld)\n", this, state, from, from_end, max);
3230
3231     while(ret<max && from!=from_end) {
3232         switch(_Mbrtowc(NULL, from, from_end-from, &tmp_state, &this->cvt)) {
3233         case -2:
3234         case -1:
3235             return ret;
3236         case 2:
3237             from++;
3238             /* fall through */
3239         case 0:
3240         case 1:
3241             from++;
3242             ret++;
3243         }
3244     }
3245
3246     return ret;
3247 }
3248
3249 /* ?length@?$codecvt@GDH@std@@QBEHABHPBD1I@Z */
3250 /* ?length@?$codecvt@GDH@std@@QEBAHAEBHPEBD1_K@Z */
3251 /* ?length@?$codecvt@_WDH@std@@QBEHABHPBD1I@Z */
3252 /* ?length@?$codecvt@_WDH@std@@QEBAHAEBHPEBD1_K@Z */
3253 DEFINE_THISCALL_WRAPPER(codecvt_wchar_length, 20)
3254 int __thiscall codecvt_wchar_length(const codecvt_wchar *this, const int *state,
3255         const char *from, const char *from_end, MSVCP_size_t max)
3256 {
3257     TRACE("(%p %p %p %p %ld)\n", this, state, from, from_end, max);
3258     return call_codecvt_wchar_do_length(this, state, from, from_end, max);
3259 }
3260
3261 /* ?id@?$numpunct@D@std@@2V0locale@2@A */
3262 locale_id numpunct_char_id = {0};
3263
3264 /* ??_7?$numpunct@D@std@@6B@ */
3265 extern const vtable_ptr MSVCP_numpunct_char_vtable;
3266
3267 /* ?_Init@?$numpunct@D@std@@IAEXABV_Locinfo@2@_N@Z */
3268 /* ?_Init@?$numpunct@D@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3269 DEFINE_THISCALL_WRAPPER(numpunct_char__Init, 12)
3270 void __thiscall numpunct_char__Init(numpunct_char *this, _Locinfo *locinfo, MSVCP_bool isdef)
3271 {
3272     int len;
3273
3274     TRACE("(%p %p %d)\n", this, locinfo, isdef);
3275
3276     len = strlen(_Locinfo__Getfalse(locinfo))+1;
3277     this->false_name = MSVCRT_operator_new(len);
3278     if(this->false_name)
3279         memcpy((char*)this->false_name, _Locinfo__Getfalse(locinfo), len);
3280
3281     len = strlen(_Locinfo__Gettrue(locinfo))+1;
3282     this->true_name = MSVCRT_operator_new(len);
3283     if(this->true_name)
3284         memcpy((char*)this->true_name, _Locinfo__Gettrue(locinfo), len);
3285
3286     if(isdef) {
3287         this->grouping = MSVCRT_operator_new(1);
3288         if(this->grouping)
3289             *(char*)this->grouping = 0;
3290
3291         this->dp = '.';
3292         this->sep = ',';
3293     } else {
3294         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3295
3296         len = strlen(lc->grouping)+1;
3297         this->grouping = MSVCRT_operator_new(len);
3298         if(this->grouping)
3299             memcpy((char*)this->grouping, lc->grouping, len);
3300
3301         this->dp = lc->decimal_point[0];
3302         this->sep = lc->thousands_sep[0];
3303     }
3304
3305     if(!this->false_name || !this->true_name || !this->grouping) {
3306         MSVCRT_operator_delete((char*)this->grouping);
3307         MSVCRT_operator_delete((char*)this->false_name);
3308         MSVCRT_operator_delete((char*)this->true_name);
3309
3310         ERR("Out of memory\n");
3311         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3312     }
3313 }
3314
3315 /* ?_Tidy@?$numpunct@D@std@@AAEXXZ */
3316 /* ?_Tidy@?$numpunct@D@std@@AEAAXXZ */
3317 DEFINE_THISCALL_WRAPPER(numpunct_char__Tidy, 4)
3318 void __thiscall numpunct_char__Tidy(numpunct_char *this)
3319 {
3320     TRACE("(%p)\n", this);
3321
3322     MSVCRT_operator_delete((char*)this->grouping);
3323     MSVCRT_operator_delete((char*)this->false_name);
3324     MSVCRT_operator_delete((char*)this->true_name);
3325 }
3326
3327 /* ??0?$numpunct@D@std@@QAE@ABV_Locinfo@1@I_N@Z */
3328 /* ??0?$numpunct@D@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3329 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_locinfo, 16)
3330 numpunct_char* __thiscall numpunct_char_ctor_locinfo(numpunct_char *this,
3331         _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3332 {
3333     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3334     locale_facet_ctor_refs(&this->facet, refs);
3335     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3336     numpunct_char__Init(this, locinfo, usedef);
3337     return this;
3338 }
3339
3340 /* ??0?$numpunct@D@std@@IAE@PBDI_N@Z */
3341 /* ??0?$numpunct@D@std@@IEAA@PEBD_K_N@Z */
3342 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_name, 16)
3343 numpunct_char* __thiscall numpunct_char_ctor_name(numpunct_char *this,
3344         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3345 {
3346     _Locinfo locinfo;
3347
3348     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3349     locale_facet_ctor_refs(&this->facet, refs);
3350     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3351
3352     _Locinfo_ctor_cstr(&locinfo, name);
3353     numpunct_char__Init(this, &locinfo, usedef);
3354     _Locinfo_dtor(&locinfo);
3355     return this;
3356 }
3357
3358 /* ??0?$numpunct@D@std@@QAE@I@Z */
3359 /* ??0?$numpunct@D@std@@QEAA@_K@Z */
3360 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_refs, 8)
3361 numpunct_char* __thiscall numpunct_char_ctor_refs(numpunct_char *this, MSVCP_size_t refs)
3362 {
3363     TRACE("(%p %lu)\n", this, refs);
3364     return numpunct_char_ctor_name(this, "C", refs, FALSE);
3365 }
3366
3367 /* ??_F?$numpunct@D@std@@QAEXXZ */
3368 /* ??_F?$numpunct@D@std@@QEAAXXZ */
3369 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor, 4)
3370 numpunct_char* __thiscall numpunct_char_ctor(numpunct_char *this)
3371 {
3372     return numpunct_char_ctor_refs(this, 0);
3373 }
3374
3375 /* ??1?$numpunct@D@std@@MAE@XZ */
3376 /* ??1?$numpunct@D@std@@MEAA@XZ */
3377 DEFINE_THISCALL_WRAPPER(numpunct_char_dtor, 4)
3378 void __thiscall numpunct_char_dtor(numpunct_char *this)
3379 {
3380     TRACE("(%p)\n", this);
3381     numpunct_char__Tidy(this);
3382 }
3383
3384 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_char_vector_dtor, 8)
3385 numpunct_char* __thiscall MSVCP_numpunct_char_vector_dtor(numpunct_char *this, unsigned int flags)
3386 {
3387     TRACE("(%p %x)\n", this, flags);
3388     if(flags & 2) {
3389         /* we have an array, with the number of elements stored before the first object */
3390         int i, *ptr = (int *)this-1;
3391
3392         for(i=*ptr-1; i>=0; i--)
3393             numpunct_char_dtor(this+i);
3394         MSVCRT_operator_delete(ptr);
3395     } else {
3396         numpunct_char_dtor(this);
3397         if(flags & 1)
3398             MSVCRT_operator_delete(this);
3399     }
3400
3401     return this;
3402 }
3403
3404 /* ?_Getcat@?$numpunct@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3405 /* ?_Getcat@?$numpunct@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3406 MSVCP_size_t __cdecl numpunct_char__Getcat(const locale_facet **facet, const locale *loc)
3407 {
3408     TRACE("(%p %p)\n", facet, loc);
3409
3410     if(facet && !*facet) {
3411         *facet = MSVCRT_operator_new(sizeof(numpunct_char));
3412         if(!*facet) {
3413             ERR("Out of memory\n");
3414             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3415             return 0;
3416         }
3417         numpunct_char_ctor_name((numpunct_char*)*facet,
3418                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3419     }
3420
3421     return LC_NUMERIC;
3422 }
3423
3424 numpunct_char* numpunct_char_use_facet(const locale *loc)
3425 {
3426     static numpunct_char *obj = NULL;
3427
3428     _Lockit lock;
3429     const locale_facet *fac;
3430
3431     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3432     fac = locale__Getfacet(loc, numpunct_char_id.id);
3433     if(fac) {
3434         _Lockit_dtor(&lock);
3435         return (numpunct_char*)fac;
3436     }
3437
3438     if(obj)
3439         return obj;
3440
3441     numpunct_char__Getcat(&fac, loc);
3442     obj = (numpunct_char*)fac;
3443     locale_facet__Incref(&obj->facet);
3444     locale_facet_register(&obj->facet);
3445     _Lockit_dtor(&lock);
3446
3447     return obj;
3448 }
3449
3450 /* ?do_decimal_point@?$numpunct@D@std@@MBEDXZ */
3451 /* ?do_decimal_point@?$numpunct@D@std@@MEBADXZ */
3452 DEFINE_THISCALL_WRAPPER(numpunct_char_do_decimal_point, 4)
3453 #define call_numpunct_char_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3454         char, (const numpunct_char *this), (this))
3455 char __thiscall numpunct_char_do_decimal_point(const numpunct_char *this)
3456 {
3457     TRACE("(%p)\n", this);
3458     return this->dp;
3459 }
3460
3461 /* ?decimal_point@?$numpunct@D@std@@QBEDXZ */
3462 /* ?decimal_point@?$numpunct@D@std@@QEBADXZ */
3463 DEFINE_THISCALL_WRAPPER(numpunct_char_decimal_point, 4)
3464 char __thiscall numpunct_char_decimal_point(const numpunct_char *this)
3465 {
3466     TRACE("(%p)\n", this);
3467     return call_numpunct_char_do_decimal_point(this);
3468 }
3469
3470 /* ?do_thousands_sep@?$numpunct@D@std@@MBEDXZ */
3471 /* ?do_thousands_sep@?$numpunct@D@std@@MEBADXZ */
3472 DEFINE_THISCALL_WRAPPER(numpunct_char_do_thousands_sep, 4)
3473 #define call_numpunct_char_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
3474         char, (const numpunct_char*), (this))
3475 char __thiscall numpunct_char_do_thousands_sep(const numpunct_char *this)
3476 {
3477     TRACE("(%p)\n", this);
3478     return this->sep;
3479 }
3480
3481 /* ?thousands_sep@?$numpunct@D@std@@QBEDXZ */
3482 /* ?thousands_sep@?$numpunct@D@std@@QEBADXZ */
3483 DEFINE_THISCALL_WRAPPER(numpunct_char_thousands_sep, 4)
3484 char __thiscall numpunct_char_thousands_sep(const numpunct_char *this)
3485 {
3486     TRACE("(%p)\n", this);
3487     return call_numpunct_char_do_thousands_sep(this);
3488 }
3489
3490 /* ?do_grouping@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3491 /* ?do_grouping@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3492 DEFINE_THISCALL_WRAPPER(numpunct_char_do_grouping, 8)
3493 #define call_numpunct_char_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
3494         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3495 basic_string_char* __thiscall numpunct_char_do_grouping(
3496         const numpunct_char *this, basic_string_char *ret)
3497 {
3498     TRACE("(%p)\n", this);
3499     return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping);
3500 }
3501
3502 /* ?grouping@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3503 /* ?grouping@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3504 DEFINE_THISCALL_WRAPPER(numpunct_char_grouping, 8)
3505 basic_string_char* __thiscall numpunct_char_grouping(const numpunct_char *this, basic_string_char *ret)
3506 {
3507     TRACE("(%p)\n", this);
3508     return call_numpunct_char_do_grouping(this, ret);
3509 }
3510
3511 /* ?do_falsename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3512 /* ?do_falsename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3513 DEFINE_THISCALL_WRAPPER(numpunct_char_do_falsename, 8)
3514 #define call_numpunct_char_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
3515         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3516 basic_string_char* __thiscall numpunct_char_do_falsename(
3517         const numpunct_char *this, basic_string_char *ret)
3518 {
3519     TRACE("(%p)\n", this);
3520     return MSVCP_basic_string_char_ctor_cstr(ret, this->false_name);
3521 }
3522
3523 /* ?falsename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3524 /* ?falsename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3525 DEFINE_THISCALL_WRAPPER(numpunct_char_falsename, 8)
3526 basic_string_char* __thiscall numpunct_char_falsename(const numpunct_char *this, basic_string_char *ret)
3527 {
3528     TRACE("(%p)\n", this);
3529     return call_numpunct_char_do_falsename(this, ret);
3530 }
3531
3532 /* ?do_truename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3533 /* ?do_truename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3534 DEFINE_THISCALL_WRAPPER(numpunct_char_do_truename, 8)
3535 #define call_numpunct_char_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
3536         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3537 basic_string_char* __thiscall numpunct_char_do_truename(
3538         const numpunct_char *this, basic_string_char *ret)
3539 {
3540     TRACE("(%p)\n", this);
3541     return MSVCP_basic_string_char_ctor_cstr(ret, this->true_name);
3542 }
3543
3544 /* ?truename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3545 /* ?truename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3546 DEFINE_THISCALL_WRAPPER(numpunct_char_truename, 8)
3547 basic_string_char* __thiscall numpunct_char_truename(const numpunct_char *this, basic_string_char *ret)
3548 {
3549     TRACE("(%p)\n", this);
3550     return call_numpunct_char_do_truename(this, ret);
3551 }
3552
3553 /* ?id@?$numpunct@_W@std@@2V0locale@2@A */
3554 locale_id numpunct_wchar_id = {0};
3555 /* ?id@?$numpunct@G@std@@2V0locale@2@A */
3556 locale_id numpunct_short_id = {0};
3557
3558 /* ??_7?$numpunct@_W@std@@6B@ */
3559 extern const vtable_ptr MSVCP_numpunct_wchar_vtable;
3560 /* ??_7?$numpunct@G@std@@6B@ */
3561 extern const vtable_ptr MSVCP_numpunct_short_vtable;
3562
3563 /* ?_Init@?$numpunct@_W@std@@IAEXABV_Locinfo@2@_N@Z */
3564 /* ?_Init@?$numpunct@_W@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3565 /* ?_Init@?$numpunct@G@std@@IAEXABV_Locinfo@2@_N@Z */
3566 /* ?_Init@?$numpunct@G@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3567 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Init, 12)
3568 void __thiscall numpunct_wchar__Init(numpunct_wchar *this, _Locinfo *locinfo, MSVCP_bool isdef)
3569 {
3570     const char *to_convert;
3571     _Cvtvec cvt;
3572     int len;
3573
3574     TRACE("(%p %p %d)\n", this, locinfo, isdef);
3575
3576     _Locinfo__Getcvt(locinfo, &cvt);
3577
3578     to_convert = _Locinfo__Getfalse(locinfo);
3579     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3580     this->false_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3581     if(this->false_name)
3582         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3583                 (wchar_t*)this->false_name, len);
3584
3585     to_convert = _Locinfo__Gettrue(locinfo);
3586     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3587     this->true_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3588     if(this->true_name)
3589         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3590                 (wchar_t*)this->true_name, len);
3591
3592     if(isdef) {
3593         this->grouping = MSVCRT_operator_new(1);
3594         if(this->grouping)
3595             *(char*)this->grouping = 0;
3596
3597         this->dp = '.';
3598         this->sep = ',';
3599     } else {
3600         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3601
3602         len = strlen(lc->grouping)+1;
3603         this->grouping = MSVCRT_operator_new(len);
3604         if(this->grouping)
3605             memcpy((char*)this->grouping, lc->grouping, len);
3606
3607         this->dp = lc->decimal_point[0];
3608         this->sep = lc->thousands_sep[0];
3609     }
3610
3611     if(!this->false_name || !this->true_name || !this->grouping) {
3612         MSVCRT_operator_delete((char*)this->grouping);
3613         MSVCRT_operator_delete((wchar_t*)this->false_name);
3614         MSVCRT_operator_delete((wchar_t*)this->true_name);
3615
3616         ERR("Out of memory\n");
3617         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3618     }
3619 }
3620
3621 /* ?_Tidy@?$numpunct@_W@std@@AAEXXZ */
3622 /* ?_Tidy@?$numpunct@_W@std@@AEAAXXZ */
3623 /* ?_Tidy@?$numpunct@G@std@@AAEXXZ */
3624 /* ?_Tidy@?$numpunct@G@std@@AEAAXXZ */
3625 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Tidy, 4)
3626 void __thiscall numpunct_wchar__Tidy(numpunct_wchar *this)
3627 {
3628     TRACE("(%p)\n", this);
3629
3630     MSVCRT_operator_delete((char*)this->grouping);
3631     MSVCRT_operator_delete((wchar_t*)this->false_name);
3632     MSVCRT_operator_delete((wchar_t*)this->true_name);
3633 }
3634
3635 /* ??0?$numpunct@_W@std@@QAE@ABV_Locinfo@1@I_N@Z */
3636 /* ??0?$numpunct@_W@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3637 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_locinfo, 16)
3638 numpunct_wchar* __thiscall numpunct_wchar_ctor_locinfo(numpunct_wchar *this,
3639         _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3640 {
3641     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3642     locale_facet_ctor_refs(&this->facet, refs);
3643     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3644     numpunct_wchar__Init(this, locinfo, usedef);
3645     return this;
3646 }
3647
3648 /* ??0?$numpunct@G@std@@QAE@ABV_Locinfo@1@I_N@Z */
3649 /* ??0?$numpunct@G@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3650 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_locinfo, 16)
3651 numpunct_wchar* __thiscall numpunct_short_ctor_locinfo(numpunct_wchar *this,
3652         _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3653 {
3654     numpunct_wchar_ctor_locinfo(this, locinfo, refs, usedef);
3655     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3656     return this;
3657 }
3658
3659 /* ??0?$numpunct@_W@std@@IAE@PBDI_N@Z */
3660 /* ??0?$numpunct@_W@std@@IEAA@PEBD_K_N@Z */
3661 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_name, 16)
3662 numpunct_wchar* __thiscall numpunct_wchar_ctor_name(numpunct_wchar *this,
3663         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3664 {
3665     _Locinfo locinfo;
3666
3667     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3668     locale_facet_ctor_refs(&this->facet, refs);
3669     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3670
3671     _Locinfo_ctor_cstr(&locinfo, name);
3672     numpunct_wchar__Init(this, &locinfo, usedef);
3673     _Locinfo_dtor(&locinfo);
3674     return this;
3675 }
3676
3677 /* ??0?$numpunct@G@std@@IAE@PBDI_N@Z */
3678 /* ??0?$numpunct@G@std@@IEAA@PEBD_K_N@Z */
3679     DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_name, 16)
3680 numpunct_wchar* __thiscall numpunct_short_ctor_name(numpunct_wchar *this,
3681         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3682 {
3683     numpunct_wchar_ctor_name(this, name, refs, usedef);
3684     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3685     return this;
3686 }
3687
3688 /* ??0?$numpunct@_W@std@@QAE@I@Z */
3689 /* ??0?$numpunct@_W@std@@QEAA@_K@Z */
3690     DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_refs, 8)
3691 numpunct_wchar* __thiscall numpunct_wchar_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3692 {
3693     TRACE("(%p %lu)\n", this, refs);
3694     return numpunct_wchar_ctor_name(this, "C", refs, FALSE);
3695 }
3696
3697 /* ??0?$numpunct@G@std@@QAE@I@Z */
3698 /* ??0?$numpunct@G@std@@QEAA@_K@Z */
3699 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_refs, 8)
3700 numpunct_wchar* __thiscall numpunct_short_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3701 {
3702     numpunct_wchar_ctor_refs(this, refs);
3703     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3704     return this;
3705 }
3706
3707 /* ??_F?$numpunct@_W@std@@QAEXXZ */
3708 /* ??_F?$numpunct@_W@std@@QEAAXXZ */
3709 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor, 4)
3710 numpunct_wchar* __thiscall numpunct_wchar_ctor(numpunct_wchar *this)
3711 {
3712     return numpunct_wchar_ctor_refs(this, 0);
3713 }
3714
3715 /* ??_F?$numpunct@G@std@@QAEXXZ */
3716 /* ??_F?$numpunct@G@std@@QEAAXXZ */
3717 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor, 4)
3718 numpunct_wchar* __thiscall numpunct_short_ctor(numpunct_wchar *this)
3719 {
3720     return numpunct_short_ctor_refs(this, 0);
3721 }
3722
3723 /* ??1?$numpunct@_W@std@@MAE@XZ */
3724 /* ??1?$numpunct@_W@std@@MEAA@XZ */
3725 /* ??1?$numpunct@G@std@@MAE@XZ */
3726 /* ??1?$numpunct@G@std@@MEAA@XZ */
3727 DEFINE_THISCALL_WRAPPER(numpunct_wchar_dtor, 4)
3728 void __thiscall numpunct_wchar_dtor(numpunct_wchar *this)
3729 {
3730     TRACE("(%p)\n", this);
3731     numpunct_wchar__Tidy(this);
3732 }
3733
3734 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_wchar_vector_dtor, 8)
3735 numpunct_wchar* __thiscall MSVCP_numpunct_wchar_vector_dtor(numpunct_wchar *this, unsigned int flags)
3736 {
3737     TRACE("(%p %x)\n", this, flags);
3738     if(flags & 2) {
3739         /* we have an array, with the number of elements stored before the first object */
3740         int i, *ptr = (int *)this-1;
3741
3742         for(i=*ptr-1; i>=0; i--)
3743             numpunct_wchar_dtor(this+i);
3744         MSVCRT_operator_delete(ptr);
3745     } else {
3746         numpunct_wchar_dtor(this);
3747         if(flags & 1)
3748             MSVCRT_operator_delete(this);
3749     }
3750
3751     return this;
3752 }
3753
3754 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_short_vector_dtor, 8)
3755 numpunct_wchar* __thiscall MSVCP_numpunct_short_vector_dtor(numpunct_wchar *this, unsigned int flags)
3756 {
3757     return MSVCP_numpunct_wchar_vector_dtor(this, flags);
3758 }
3759
3760 /* ?_Getcat@?$numpunct@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3761 /* ?_Getcat@?$numpunct@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3762 MSVCP_size_t __cdecl numpunct_wchar__Getcat(const locale_facet **facet, const locale *loc)
3763 {
3764     TRACE("(%p %p)\n", facet, loc);
3765
3766     if(facet && !*facet) {
3767         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3768         if(!*facet) {
3769             ERR("Out of memory\n");
3770             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3771             return 0;
3772         }
3773         numpunct_wchar_ctor_name((numpunct_wchar*)*facet,
3774                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3775     }
3776
3777     return LC_NUMERIC;
3778 }
3779
3780 /* ?_Getcat@?$numpunct@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3781 /* ?_Getcat@?$numpunct@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3782 MSVCP_size_t __cdecl numpunct_short__Getcat(const locale_facet **facet, const locale *loc)
3783 {
3784     TRACE("(%p %p)\n", facet, loc);
3785
3786     if(facet && !*facet) {
3787         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3788         if(!*facet) {
3789             ERR("Out of memory\n");
3790             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3791             return 0;
3792         }
3793         numpunct_short_ctor_name((numpunct_wchar*)*facet,
3794                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3795     }
3796
3797     return LC_NUMERIC;
3798 }
3799
3800 /* ?do_decimal_point@?$numpunct@_W@std@@MBE_WXZ */
3801 /* ?do_decimal_point@?$numpunct@_W@std@@MEBA_WXZ */
3802 /* ?do_decimal_point@?$numpunct@G@std@@MBEGXZ */
3803 /* ?do_decimal_point@?$numpunct@G@std@@MEBAGXZ */
3804 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_decimal_point, 4)
3805 #define call_numpunct_wchar_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3806         wchar_t, (const numpunct_wchar *this), (this))
3807 wchar_t __thiscall numpunct_wchar_do_decimal_point(const numpunct_wchar *this)
3808 {
3809     TRACE("(%p)\n", this);
3810     return this->dp;
3811 }
3812
3813 /* ?decimal_point@?$numpunct@_W@std@@QBE_WXZ */
3814 /* ?decimal_point@?$numpunct@_W@std@@QEBA_WXZ */
3815 /* ?decimal_point@?$numpunct@G@std@@QBEGXZ */
3816 /* ?decimal_point@?$numpunct@G@std@@QEBAGXZ */
3817 DEFINE_THISCALL_WRAPPER(numpunct_wchar_decimal_point, 4)
3818 wchar_t __thiscall numpunct_wchar_decimal_point(const numpunct_wchar *this)
3819 {
3820     TRACE("(%p)\n", this);
3821     return call_numpunct_wchar_do_decimal_point(this);
3822 }
3823
3824 /* ?do_thousands_sep@?$numpunct@_W@std@@MBE_WXZ */
3825 /* ?do_thousands_sep@?$numpunct@_W@std@@MEBA_WXZ */
3826 /* ?do_thousands_sep@?$numpunct@G@std@@MBEGXZ */
3827 /* ?do_thousands_sep@?$numpunct@G@std@@MEBAGXZ */
3828 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_thousands_sep, 4)
3829 #define call_numpunct_wchar_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
3830         wchar_t, (const numpunct_wchar *this), (this))
3831 wchar_t __thiscall numpunct_wchar_do_thousands_sep(const numpunct_wchar *this)
3832 {
3833     TRACE("(%p)\n", this);
3834     return this->sep;
3835 }
3836
3837 /* ?thousands_sep@?$numpunct@_W@std@@QBE_WXZ */
3838 /* ?thousands_sep@?$numpunct@_W@std@@QEBA_WXZ */
3839 /* ?thousands_sep@?$numpunct@G@std@@QBEGXZ */
3840 /* ?thousands_sep@?$numpunct@G@std@@QEBAGXZ */
3841 DEFINE_THISCALL_WRAPPER(numpunct_wchar_thousands_sep, 4)
3842 wchar_t __thiscall numpunct_wchar_thousands_sep(const numpunct_wchar *this)
3843 {
3844     TRACE("(%p)\n", this);
3845     return call_numpunct_wchar_do_thousands_sep(this);
3846 }
3847
3848 /* ?do_grouping@?$numpunct@_W@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3849 /* ?do_grouping@?$numpunct@_W@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3850 /* ?do_grouping@?$numpunct@G@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3851 /* ?do_grouping@?$numpunct@G@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3852 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_grouping, 8)
3853 #define call_numpunct_wchar_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
3854         basic_string_char*, (const numpunct_wchar*, basic_string_char*), (this, ret))
3855 basic_string_char* __thiscall numpunct_wchar_do_grouping(const numpunct_wchar *this, basic_string_char *ret)
3856 {
3857     TRACE("(%p)\n", this);
3858     return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping);
3859 }
3860
3861 /* ?grouping@?$numpunct@_W@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3862 /* ?grouping@?$numpunct@_W@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3863 /* ?grouping@?$numpunct@G@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3864 /* ?grouping@?$numpunct@G@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3865 DEFINE_THISCALL_WRAPPER(numpunct_wchar_grouping, 8)
3866 basic_string_char* __thiscall numpunct_wchar_grouping(const numpunct_wchar *this, basic_string_char *ret)
3867 {
3868     TRACE("(%p)\n", this);
3869     return call_numpunct_wchar_do_grouping(this, ret);
3870 }
3871
3872 /* ?do_falsename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3873 /* ?do_falsename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3874 /* ?do_falsename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3875 /* ?do_falsename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3876 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_falsename, 8)
3877 #define call_numpunct_wchar_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
3878         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
3879 basic_string_wchar* __thiscall numpunct_wchar_do_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
3880 {
3881     TRACE("(%p)\n", this);
3882     return MSVCP_basic_string_wchar_ctor_cstr(ret, this->false_name);
3883 }
3884
3885 /* ?falsename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3886 /* ?falsename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3887 /* ?falsename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3888 /* ?falsename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3889 DEFINE_THISCALL_WRAPPER(numpunct_wchar_falsename, 8)
3890 basic_string_wchar* __thiscall numpunct_wchar_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
3891 {
3892     TRACE("(%p)\n", this);
3893     return call_numpunct_wchar_do_falsename(this, ret);
3894 }
3895
3896 /* ?do_truename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3897 /* ?do_truename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3898 /* ?do_truename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3899 /* ?do_truename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3900 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_truename, 8)
3901 #define call_numpunct_wchar_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
3902         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
3903 basic_string_wchar* __thiscall numpunct_wchar_do_truename(const numpunct_wchar *this, basic_string_wchar *ret)
3904 {
3905     TRACE("(%p)\n", this);
3906     return MSVCP_basic_string_wchar_ctor_cstr(ret, this->true_name);
3907 }
3908
3909 /* ?truename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3910 /* ?truename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3911 /* ?truename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3912 /* ?truename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3913 DEFINE_THISCALL_WRAPPER(numpunct_wchar_truename, 8)
3914 basic_string_wchar* __thiscall numpunct_wchar_truename(const numpunct_wchar *this, basic_string_wchar *ret)
3915 {
3916     TRACE("(%p)\n", this);
3917     return call_numpunct_wchar_do_truename(this, ret);
3918 }
3919
3920 double __cdecl _Stod(const char *buf, char **buf_end, LONG exp)
3921 {
3922     double ret = strtod(buf, buf_end);
3923
3924     if(exp)
3925         ret *= pow(10, exp);
3926     return ret;
3927 }
3928
3929 double __cdecl _Stodx(const char *buf, char **buf_end, LONG exp, int *err)
3930 {
3931     double ret;
3932
3933     *err = *_errno();
3934     *_errno() = 0;
3935     ret = _Stod(buf, buf_end, exp);
3936     if(*_errno()) {
3937         *err = *_errno();
3938     }else {
3939         *_errno() = *err;
3940         *err = 0;
3941     }
3942     return ret;
3943 }
3944
3945 float __cdecl _Stof(const char *buf, char **buf_end, LONG exp)
3946 {
3947     return _Stod(buf, buf_end, exp);
3948 }
3949
3950 float __cdecl _Stofx(const char *buf, char **buf_end, LONG exp, int *err)
3951 {
3952     return _Stodx(buf, buf_end, exp, err);
3953 }
3954
3955 __int64 __cdecl _Stoll(const char *buf, char **buf_end, int base)
3956 {
3957     return _strtoi64(buf, buf_end, base);
3958 }
3959
3960 __int64 __cdecl _Stollx(const char *buf, char **buf_end, int base, int *err)
3961 {
3962     __int64 ret;
3963
3964     *err = *_errno();
3965     *_errno() = 0;
3966     ret = _strtoi64(buf, buf_end, base);
3967     if(*_errno()) {
3968         *err = *_errno();
3969     }else {
3970         *_errno() = *err;
3971         *err = 0;
3972     }
3973     return ret;
3974 }
3975
3976 LONG __cdecl _Stolx(const char *buf, char **buf_end, int base, int *err)
3977 {
3978     __int64 i = _Stollx(buf, buf_end, base, err);
3979     if(!*err && i!=(__int64)((LONG)i))
3980         *err = ERANGE;
3981     return i;
3982 }
3983
3984 unsigned __int64 __cdecl _Stoull(const char *buf, char **buf_end, int base)
3985 {
3986     return _strtoui64(buf, buf_end, base);
3987 }
3988
3989 unsigned __int64 __cdecl _Stoullx(const char *buf, char **buf_end, int base, int *err)
3990 {
3991     unsigned __int64 ret;
3992
3993     *err = *_errno();
3994     *_errno() = 0;
3995     ret = _strtoui64(buf, buf_end, base);
3996     if(*_errno()) {
3997         *err = *_errno();
3998     }else {
3999         *_errno() = *err;
4000         *err = 0;
4001     }
4002     return ret;
4003 }
4004
4005 ULONG __cdecl _Stoul(const char *buf, char **buf_end, int base)
4006 {
4007     int err;
4008     unsigned __int64 i = _Stoullx(buf[0]=='-' ? buf+1 : buf, buf_end, base, &err);
4009     if(!err && i!=(unsigned __int64)((ULONG)i))
4010         *_errno() = ERANGE;
4011     return buf[0]=='-' ? -i : i;
4012 }
4013
4014 ULONG __cdecl _Stoulx(const char *buf, char **buf_end, int base, int *err)
4015 {
4016     unsigned __int64 i = _Stoullx(buf[0]=='-' ? buf+1 : buf, buf_end, base, err);
4017     if(!*err && i!=(unsigned __int64)((ULONG)i))
4018         *err = ERANGE;
4019     return buf[0]=='-' ? -i : i;
4020 }
4021
4022 /* ?id@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
4023 locale_id num_get_wchar_id = {0};
4024 /* ?id@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@2V0locale@2@A */
4025 locale_id num_get_short_id = {0};
4026
4027 /* ??_7?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
4028 extern const vtable_ptr MSVCP_num_get_wchar_vtable;
4029 /* ??_7?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@6B@ */
4030 extern const vtable_ptr MSVCP_num_get_short_vtable;
4031
4032 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4033 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4034 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4035 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4036 DEFINE_THISCALL_WRAPPER(num_get_wchar__Init, 8)
4037 void __thiscall num_get_wchar__Init(num_get *this, const _Locinfo *locinfo)
4038 {
4039     FIXME("(%p %p) stub\n", this, locinfo);
4040 }
4041
4042 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4043 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4044 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_locinfo, 12)
4045 num_get* __thiscall num_get_wchar_ctor_locinfo(num_get *this,
4046         _Locinfo *locinfo, MSVCP_size_t refs)
4047 {
4048     FIXME("(%p %p %lu) stub\n", this, locinfo, refs);
4049     return NULL;
4050 }
4051
4052 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4053 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4054 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_locinfo, 12)
4055 num_get* __thiscall num_get_short_ctor_locinfo(num_get *this,
4056         _Locinfo *locinfo, MSVCP_size_t refs)
4057 {
4058     FIXME("(%p %p %lu) stub\n", this, locinfo, refs);
4059     return NULL;
4060 }
4061
4062 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
4063 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
4064 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_refs, 8)
4065 num_get* __thiscall num_get_wchar_ctor_refs(num_get *this, MSVCP_size_t refs)
4066 {
4067     FIXME("(%p %lu) stub\n", this, refs);
4068     return NULL;
4069 }
4070
4071 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@I@Z */
4072 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@_K@Z */
4073 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_refs, 8)
4074 num_get* __thiscall num_get_short_ctor_refs(num_get *this, MSVCP_size_t refs)
4075 {
4076     FIXME("(%p %lu) stub\n", this, refs);
4077     return NULL;
4078 }
4079
4080 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
4081 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
4082 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor, 4)
4083 num_get* __thiscall num_get_wchar_ctor(num_get *this)
4084 {
4085     FIXME("(%p) stub\n", this);
4086     return NULL;
4087 }
4088
4089 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
4090 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
4091 DEFINE_THISCALL_WRAPPER(num_get_short_ctor, 4)
4092 num_get* __thiscall num_get_short_ctor(num_get *this)
4093 {
4094     FIXME("(%p) stub\n", this);
4095     return NULL;
4096 }
4097
4098 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
4099 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
4100 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MAE@XZ */
4101 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEAA@XZ */
4102 DEFINE_THISCALL_WRAPPER(num_get_wchar_dtor, 4)
4103 void __thiscall num_get_wchar_dtor(num_get *this)
4104 {
4105     FIXME("(%p) stub\n", this);
4106 }
4107
4108 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_wchar_vector_dtor, 8)
4109 num_get* __thiscall MSVCP_num_get_wchar_vector_dtor(num_get *this, unsigned int flags)
4110 {
4111     TRACE("(%p %x)\n", this, flags);
4112     if(flags & 2) {
4113         /* we have an array, with the number of elements stored before the first object */
4114         int i, *ptr = (int *)this-1;
4115
4116         for(i=*ptr-1; i>=0; i--)
4117             num_get_wchar_dtor(this+i);
4118         MSVCRT_operator_delete(ptr);
4119     } else {
4120         num_get_wchar_dtor(this);
4121         if(flags & 1)
4122             MSVCRT_operator_delete(this);
4123     }
4124
4125     return this;
4126 }
4127
4128 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_short_vector_dtor, 8)
4129 num_get* __thiscall MSVCP_num_get_short_vector_dtor(num_get *this, unsigned int flags)
4130 {
4131     return MSVCP_num_get_wchar_vector_dtor(this, flags);
4132 }
4133
4134 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4135 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4136 MSVCP_size_t __cdecl num_get_wchar__Getcat(const locale_facet **facet, const locale *loc)
4137 {
4138     FIXME("(%p %p) stub\n", facet, loc);
4139     return -1;
4140 }
4141
4142 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4143 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4144 MSVCP_size_t __cdecl num_get_short__Getcat(const locale_facet **facet, const locale *loc)
4145 {
4146     FIXME("(%p %p) stub\n", facet, loc);
4147     return -1;
4148 }
4149
4150 /* ?_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 */
4151 /* ?_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 */
4152 /* ?_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 */
4153 /* ?_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 */
4154 int __cdecl num_get_wchar__Getffld(num_get *this, char *dest, istreambuf_iterator_wchar *first,
4155     istreambuf_iterator_wchar *last, const locale *loc)
4156 {
4157     FIXME("(%p %p %p %p) stub\n", dest, first, last, loc);
4158     return -1;
4159 }
4160
4161 /* ?_Getffldx@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1AAVios_base@2@PAH@Z */
4162 /* ?_Getffldx@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1AEAVios_base@2@PEAH@Z */
4163 /* ?_Getffldx@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1AAVios_base@2@PAH@Z */
4164 /* ?_Getffldx@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1AEAVios_base@2@PEAH@Z */
4165 int __cdecl num_get_wchar__Getffldx(num_get *this, char *dest, istreambuf_iterator_wchar *first,
4166     istreambuf_iterator_wchar *last, ios_base *ios, int *phexexp)
4167 {
4168     FIXME("(%p %p %p %p %p) stub\n", dest, first, last, ios, phexexp);
4169     return -1;
4170 }
4171
4172 /* ?_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 */
4173 /* ?_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 */
4174 /* ?_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 */
4175 /* ?_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 */
4176 int __cdecl num_get_wchar__Getifld(num_get *this, char *dest, istreambuf_iterator_wchar *first,
4177     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
4178 {
4179     FIXME("(%p %p %p %04x %p) stub\n", dest, first, last, fmtflags, loc);
4180     return -1;
4181 }
4182
4183 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABEH_W000@Z */
4184 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAH_W000@Z */
4185 /* ?_Hexdig@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABEHGGGG@Z */
4186 /* ?_Hexdig@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHGGGG@Z */
4187 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_wchar__Hexdig, 20)
4188 int __thiscall MSVCP_num_get_wchar__Hexdig(num_get *this, wchar_t dig, wchar_t e0, wchar_t al, wchar_t au)
4189 {
4190     FIXME("(%p %c %c %c %c) stub\n", this, dig, e0, al, au);
4191     return -1;
4192 }
4193
4194 /* ?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 */
4195 /* ?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 */
4196 /* ?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 */
4197 /* ?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 */
4198 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_void,36)
4199 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4200     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4201 {
4202     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4203     return ret;
4204 }
4205
4206 /* ?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 */
4207 /* ?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 */
4208 /* ?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 */
4209 /* ?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 */
4210 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_void,36)
4211 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4212     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4213 {
4214     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4215     return ret;
4216 }
4217
4218 /* ?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 */
4219 /* ?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 */
4220 /* ?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 */
4221 /* ?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 */
4222 /* ?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 */
4223 /* ?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 */
4224 /* ?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 */
4225 /* ?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 */
4226 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_double,36)
4227 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4228     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4229 {
4230     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4231     return ret;
4232 }
4233
4234 /* ?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 */
4235 /* ?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 */
4236 /* ?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 */
4237 /* ?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 */
4238 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ldouble,36)
4239 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ldouble(const num_get *this, istreambuf_iterator_wchar *ret,
4240         istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4241 {
4242     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4243     return ret;
4244 }
4245
4246 /* ?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 */
4247 /* ?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 */
4248 /* ?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 */
4249 /* ?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 */
4250 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_double,36)
4251 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4252     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4253 {
4254     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4255     return ret;
4256 }
4257
4258 /* ?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 */
4259 /* ?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 */
4260 /* ?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 */
4261 /* ?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 */
4262 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_float,36)
4263 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4264     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4265 {
4266     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4267     return ret;
4268 }
4269
4270 /* ?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 */
4271 /* ?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 */
4272 /* ?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 */
4273 /* ?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 */
4274 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_float,36)
4275 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4276     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4277 {
4278     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4279     return ret;
4280 }
4281
4282 /* ?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 */
4283 /* ?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 */
4284 /* ?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 */
4285 /* ?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 */
4286 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint64,36)
4287 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
4288     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
4289 {
4290     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4291     return ret;
4292 }
4293
4294 /* ?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 */
4295 /* ?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 */
4296 /* ?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 */
4297 /* ?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 */
4298 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint64,36)
4299 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
4300     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
4301 {
4302     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4303     return ret;
4304 }
4305
4306 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
4307 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
4308 /* ?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 */
4309 /* ?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 */
4310 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_int64,36)
4311 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
4312     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
4313 {
4314     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4315     return ret;
4316 }
4317
4318 /* ?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 */
4319 /* ?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 */
4320 /* ?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 */
4321 /* ?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 */
4322 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_int64,36)
4323 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
4324     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
4325 {
4326     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4327     return ret;
4328 }
4329
4330 /* ?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 */
4331 /* ?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 */
4332 /* ?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 */
4333 /* ?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 */
4334 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ulong,36)
4335 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
4336     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
4337 {
4338     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4339     return ret;
4340 }
4341
4342 /* ?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 */
4343 /* ?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 */
4344 /* ?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 */
4345 /* ?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 */
4346 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ulong,36)
4347 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
4348     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
4349 {
4350     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4351     return ret;
4352 }
4353
4354 /* ?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 */
4355 /* ?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 */
4356 /* ?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 */
4357 /* ?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 */
4358 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_long,36)
4359 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
4360     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
4361 {
4362     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4363     return ret;
4364 }
4365
4366 /* ?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 */
4367 /* ?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 */
4368 /* ?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 */
4369 /* ?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 */
4370 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_long,36)
4371 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
4372     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
4373 {
4374     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4375     return ret;
4376 }
4377
4378 /* ?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 */
4379 /* ?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 */
4380 /* ?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 */
4381 /* ?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 */
4382 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint,36)
4383 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
4384     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
4385 {
4386     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4387     return ret;
4388 }
4389
4390 /* ?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 */
4391 /* ?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 */
4392 /* ?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 */
4393 /* ?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 */
4394 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint,36)
4395 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
4396     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
4397 {
4398     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4399     return ret;
4400 }
4401
4402 /* ?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 */
4403 /* ?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 */
4404 /* ?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 */
4405 /* ?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 */
4406 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ushort,36)
4407 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
4408     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
4409 {
4410     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4411     return ret;
4412 }
4413
4414 /* ?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 */
4415 /* ?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 */
4416 /* ?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@ */
4417 /* ?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 */
4418 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ushort,36)
4419 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
4420     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
4421 {
4422     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4423     return ret;
4424 }
4425
4426 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
4427 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
4428 /* ?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 */
4429 /* ?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 */
4430 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_bool,36)
4431 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
4432     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
4433 {
4434     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4435     return ret;
4436 }
4437
4438 /* ?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 */
4439 /* ?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 */
4440 /* ?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 */
4441 /* ?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 */
4442 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_bool,36)
4443 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
4444     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
4445 {
4446     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4447     return ret;
4448 }
4449
4450 /* ?id@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
4451 locale_id num_get_char_id = {0};
4452
4453 /* ??_7?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
4454 extern const vtable_ptr MSVCP_num_get_char_vtable;
4455
4456 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4457 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4458 DEFINE_THISCALL_WRAPPER(num_get_char__Init, 8)
4459 void __thiscall num_get_char__Init(num_get *this, const _Locinfo *locinfo)
4460 {
4461     TRACE("(%p %p)\n", this, locinfo);
4462     _Locinfo__Getcvt(locinfo, &this->cvt);
4463 }
4464
4465 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4466 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4467 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_locinfo, 12)
4468 num_get* __thiscall num_get_char_ctor_locinfo(num_get *this,
4469         _Locinfo *locinfo, MSVCP_size_t refs)
4470 {
4471     TRACE("(%p %p %lu)\n", this, locinfo, refs);
4472
4473     locale_facet_ctor_refs(&this->facet, refs);
4474     this->facet.vtable = &MSVCP_num_get_char_vtable;
4475
4476     num_get_char__Init(this, locinfo);
4477     return this;
4478 }
4479
4480 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
4481 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
4482 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_refs, 8)
4483 num_get* __thiscall num_get_char_ctor_refs(num_get *this, MSVCP_size_t refs)
4484 {
4485     _Locinfo locinfo;
4486
4487     TRACE("(%p %lu)\n", this, refs);
4488
4489     _Locinfo_ctor(&locinfo);
4490     num_get_char_ctor_locinfo(this, &locinfo, refs);
4491     _Locinfo_dtor(&locinfo);
4492     return this;
4493 }
4494
4495 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
4496 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
4497 DEFINE_THISCALL_WRAPPER(num_get_char_ctor, 4)
4498 num_get* __thiscall num_get_char_ctor(num_get *this)
4499 {
4500     return num_get_char_ctor_refs(this, 0);
4501 }
4502
4503 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
4504 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
4505 DEFINE_THISCALL_WRAPPER(num_get_char_dtor, 4)
4506 void __thiscall num_get_char_dtor(num_get *this)
4507 {
4508     TRACE("(%p)\n", this);
4509     locale_facet_dtor(&this->facet);
4510 }
4511
4512 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_char_vector_dtor, 8)
4513 num_get* __thiscall MSVCP_num_get_char_vector_dtor(num_get *this, unsigned int flags)
4514 {
4515     TRACE("(%p %x)\n", this, flags);
4516     if(flags & 2) {
4517         /* we have an array, with the number of elements stored before the first object */
4518         int i, *ptr = (int *)this-1;
4519
4520         for(i=*ptr-1; i>=0; i--)
4521             num_get_char_dtor(this+i);
4522         MSVCRT_operator_delete(ptr);
4523     } else {
4524         num_get_char_dtor(this);
4525         if(flags & 1)
4526             MSVCRT_operator_delete(this);
4527     }
4528
4529     return this;
4530 }
4531
4532 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4533 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4534 MSVCP_size_t __cdecl num_get_char__Getcat(const locale_facet **facet, const locale *loc)
4535 {
4536     TRACE("(%p %p)\n", facet, loc);
4537
4538     if(facet && !*facet) {
4539         _Locinfo locinfo;
4540
4541         *facet = MSVCRT_operator_new(sizeof(num_get));
4542         if(!*facet) {
4543             ERR("Out of memory\n");
4544             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
4545             return 0;
4546         }
4547
4548         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
4549         num_get_char_ctor_locinfo((num_get*)*facet, &locinfo, 0);
4550         _Locinfo_dtor(&locinfo);
4551     }
4552
4553     return LC_NUMERIC;
4554 }
4555
4556 num_get* num_get_char_use_facet(const locale *loc)
4557 {
4558     static num_get *obj = NULL;
4559
4560     _Lockit lock;
4561     const locale_facet *fac;
4562
4563     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
4564     fac = locale__Getfacet(loc, num_get_char_id.id);
4565     if(fac) {
4566         _Lockit_dtor(&lock);
4567         return (num_get*)fac;
4568     }
4569
4570     if(obj)
4571         return obj;
4572
4573     num_get_char__Getcat(&fac, loc);
4574     obj = (num_get*)fac;
4575     locale_facet__Incref(&obj->facet);
4576     locale_facet_register(&obj->facet);
4577     _Lockit_dtor(&lock);
4578
4579     return obj;
4580 }
4581
4582 /* ?_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 */
4583 /* ?_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 */
4584 /* Copies number to dest buffer, validates grouping and skips separators.
4585  * Updates first so it points past the number, all digits are skipped.
4586  * Returns how exponent needs to changed.
4587  * Size of dest buffer is not specified, assuming it's not smaller then 32:
4588  * strlen(+0.e+) + 22(digits) + 4(expontent) + 1(nullbyte)
4589  */
4590 int __cdecl num_get_char__Getffld(const num_get *this, char *dest, istreambuf_iterator_char *first,
4591         istreambuf_iterator_char *last, const locale *loc)
4592 {
4593     numpunct_char *numpunct = numpunct_char_use_facet(loc);
4594     basic_string_char grouping_bstr;
4595     int groups_no = 0, cur_group = 0, exp = 0;
4596     char *dest_beg = dest, *num_end = dest+25, *exp_end = dest+31, *groups = NULL, sep;
4597     const char *grouping;
4598     BOOL error = TRUE, dest_empty = TRUE;
4599
4600     TRACE("(%p %p %p %p)\n", dest, first, last, loc);
4601
4602     numpunct_char_grouping(numpunct, &grouping_bstr);
4603     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
4604     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
4605
4606     istreambuf_iterator_char_val(first);
4607     if(first->strbuf && (first->val=='-' || first->val=='+')) {
4608         *dest++ = first->val;
4609         istreambuf_iterator_char_inc(first);
4610     }
4611
4612     if(sep) {
4613         groups_no = strlen(grouping)+2;
4614         groups = calloc(groups_no, sizeof(char));
4615     }
4616
4617     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
4618         if(first->val<'0' || first->val>'9') {
4619             if(sep && first->val==sep) {
4620                 if(cur_group == groups_no+1) {
4621                     if(groups[1] != groups[2]) {
4622                         error = TRUE;
4623                         break;
4624                     }else {
4625                         memmove(groups+1, groups+2, groups_no);
4626                         groups[cur_group] = 0;
4627                     }
4628                 }else {
4629                     cur_group++;
4630                 }
4631             }else {
4632                 break;
4633             }
4634         }else {
4635             error = FALSE;
4636             if(dest_empty && first->val == '0')
4637                 continue;
4638             dest_empty = FALSE;
4639             if(dest < num_end)
4640                 *dest++ = first->val;
4641             else
4642                 exp++;
4643             if(sep && groups[cur_group]<CHAR_MAX)
4644                 groups[cur_group]++;
4645         }
4646     }
4647
4648     if(cur_group && !groups[cur_group])
4649         error = TRUE;
4650     else if(!cur_group)
4651         cur_group--;
4652
4653     for(; cur_group>=0 && !error; cur_group--) {
4654         if(*grouping == CHAR_MAX) {
4655             if(cur_group)
4656                 error = TRUE;
4657             break;
4658         }else if((cur_group && *grouping!=groups[cur_group])
4659                 || (!cur_group && *grouping<groups[cur_group])) {
4660             error = TRUE;
4661             break;
4662         }else if(grouping[1]) {
4663             grouping++;
4664         }
4665     }
4666     MSVCP_basic_string_char_dtor(&grouping_bstr);
4667     free(groups);
4668
4669     if(error) {
4670         *dest_beg = '\0';
4671         return 0;
4672     }else if(dest_empty) {
4673         *dest++ = '0';
4674     }
4675
4676     if(first->strbuf && first->val==numpunct_char_decimal_point(numpunct)) {
4677         if(dest < num_end)
4678             *dest++ = *localeconv()->decimal_point;
4679         istreambuf_iterator_char_inc(first);
4680
4681         if(dest_empty) {
4682             for(; first->strbuf && first->val=='0'; istreambuf_iterator_char_inc(first))
4683                 exp--;
4684
4685             if(!first->strbuf || first->val<'1' || first->val>'9')
4686                 dest--;
4687         }
4688     }
4689
4690     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
4691         if(first->val<'0' || first->val>'9')
4692             break;
4693         else if(dest<num_end)
4694             *dest++ = first->val;
4695     }
4696
4697     if(first->strbuf && (first->val=='e' || first->val=='E')) {
4698         *dest++ = first->val;
4699         istreambuf_iterator_char_inc(first);
4700
4701         if(first->strbuf && (first->val=='-' || first->val=='+')) {
4702             *dest++ = first->val;
4703             istreambuf_iterator_char_inc(first);
4704         }
4705
4706         error = dest_empty = TRUE;
4707         for(; first->strbuf && first->val=='0'; istreambuf_iterator_char_inc(first))
4708             error = FALSE;
4709
4710         for(; first->strbuf && first->val>='0' && first->val<='9'; istreambuf_iterator_char_inc(first)) {
4711             error = dest_empty = FALSE;
4712             if(dest<exp_end)
4713                 *dest++ = first->val;
4714         }
4715
4716         if(error) {
4717             *dest_beg = '\0';
4718             return 0;
4719         }else if(dest_empty) {
4720             *dest++ = '0';
4721         }
4722     }
4723
4724     *dest++ = '\0';
4725     return exp;
4726 }
4727
4728 /* ?_Getffldx@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1AAVios_base@2@PAH@Z */
4729 /* ?_Getffldx@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1AEAVios_base@2@PEAH@Z */
4730 int __cdecl num_get_char__Getffldx(const num_get *this, char *dest, istreambuf_iterator_char *first,
4731     istreambuf_iterator_char *last, ios_base *ios, int *phexexp)
4732 {
4733     FIXME("(%p %p %p %p %p) stub\n", dest, first, last, ios, phexexp);
4734     return -1;
4735 }
4736
4737 /* ?_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 */
4738 /* ?_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 */
4739 /* Copies number to dest buffer, validates grouping and skips separators.
4740  * Updates first so it points past the number, all digits are skipped.
4741  * Returns number base (8, 10 or 16).
4742  * Size of dest buffer is not specified, assuming it's not smaller then 25:
4743  * 22(8^22>2^64)+1(detect overflows)+1(sign)+1(nullbyte) = 25
4744  */
4745 int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_iterator_char *first,
4746         istreambuf_iterator_char *last, int fmtflags, const locale *loc)
4747 {
4748     static const char digits[] = "0123456789abcdefABCDEF";
4749
4750     numpunct_char *numpunct = numpunct_char_use_facet(loc);
4751     basic_string_char grouping_bstr;
4752     int basefield, base, groups_no = 0, cur_group = 0;
4753     char *dest_beg = dest, *dest_end = dest+24, *groups = NULL, sep;
4754     const char *grouping;
4755     BOOL error = TRUE, dest_empty = TRUE;
4756
4757     TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
4758
4759     numpunct_char_grouping(numpunct, &grouping_bstr);
4760     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
4761     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
4762
4763     basefield = fmtflags & FMTFLAG_basefield;
4764     if(basefield == FMTFLAG_oct)
4765         base = 8;
4766     else if(basefield == FMTFLAG_hex)
4767         base = 22; /* equal to the size of digits buffer */
4768     else if(!basefield)
4769         base = 0;
4770     else
4771         base = 10;
4772
4773     istreambuf_iterator_char_val(first);
4774     if(first->strbuf && (first->val=='-' || first->val=='+')) {
4775         *dest++ = first->val;
4776         istreambuf_iterator_char_inc(first);
4777     }
4778
4779     if(!base && first->strbuf && first->val=='0') {
4780         istreambuf_iterator_char_inc(first);
4781         if(first->strbuf && (first->val=='x' || first->val=='X')) {
4782             istreambuf_iterator_char_inc(first);
4783             base = 22;
4784         }else {
4785             error = FALSE;
4786             base = 8;
4787         }
4788     }else {
4789         base = 10;
4790     }
4791
4792     if(sep) {
4793         groups_no = strlen(grouping)+2;
4794         groups = calloc(groups_no, sizeof(char));
4795     }
4796
4797     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
4798         if(!memchr(digits, first->val, base)) {
4799             if(sep && first->val==sep) {
4800                 if(cur_group == groups_no+1) {
4801                     if(groups[1] != groups[2]) {
4802                         error = TRUE;
4803                         break;
4804                     }else {
4805                         memmove(groups+1, groups+2, groups_no);
4806                         groups[cur_group] = 0;
4807                     }
4808                 }else {
4809                     cur_group++;
4810                 }
4811             }else {
4812                 break;
4813             }
4814         }else {
4815             error = FALSE;
4816             if(dest_empty && first->val == '0')
4817                 continue;
4818             dest_empty = FALSE;
4819             /* skip digits that can't be copied to dest buffer, other
4820              * functions are responsible for detecting overflows */
4821             if(dest < dest_end)
4822                 *dest++ = first->val;
4823             if(sep && groups[cur_group]<CHAR_MAX)
4824                 groups[cur_group]++;
4825         }
4826     }
4827
4828     if(cur_group && !groups[cur_group])
4829         error = TRUE;
4830     else if(!cur_group)
4831         cur_group--;
4832
4833     for(; cur_group>=0 && !error; cur_group--) {
4834         if(*grouping == CHAR_MAX) {
4835             if(cur_group)
4836                 error = TRUE;
4837             break;
4838         }else if((cur_group && *grouping!=groups[cur_group])
4839                 || (!cur_group && *grouping<groups[cur_group])) {
4840             error = TRUE;
4841             break;
4842         }else if(grouping[1]) {
4843             grouping++;
4844         }
4845     }
4846     MSVCP_basic_string_char_dtor(&grouping_bstr);
4847     free(groups);
4848
4849     if(error)
4850         dest = dest_beg;
4851     else if(dest_empty)
4852         *dest++ = '0';
4853     *dest = '\0';
4854
4855     return (base==22 ? 16 : base);
4856 }
4857
4858 /* ?_Hexdig@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABEHD000@Z */
4859 /* ?_Hexdig@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHD000@Z */
4860 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_char__Hexdig, 20)
4861 int __thiscall MSVCP_num_get_char__Hexdig(num_get *this, char dig, char e0, char al, char au)
4862 {
4863     FIXME("(%p %c %c %c %c) stub\n", this, dig, e0, al, au);
4864     return -1;
4865 }
4866
4867 /* ?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 */
4868 /* ?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 */
4869 #define call_num_get_char_do_get_void(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 4, istreambuf_iterator_char*, \
4870         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, void**), \
4871         (this, ret, first, last, base, state, pval))
4872 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_void,36)
4873 istreambuf_iterator_char *__thiscall num_get_char_do_get_void(const num_get *this, istreambuf_iterator_char *ret,
4874     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
4875 {
4876     unsigned __int64 v;
4877     char tmp[25], *end;
4878     int err;
4879
4880     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4881
4882     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
4883                 &first, &last, FMTFLAG_hex, base->loc), &err);
4884     if(v!=(unsigned __int64)((INT_PTR)v))
4885         *state |= IOSTATE_failbit;
4886     else if(end!=tmp && !err)
4887         *pval = (void*)((INT_PTR)v);
4888     else
4889         *state |= IOSTATE_failbit;
4890
4891     if(!first.strbuf)
4892         *state |= IOSTATE_eofbit;
4893
4894     *ret = first;
4895     return ret;
4896 }
4897
4898 /* ?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 */
4899 /* ?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 */
4900 DEFINE_THISCALL_WRAPPER(num_get_char_get_void,36)
4901 istreambuf_iterator_char *__thiscall num_get_char_get_void(const num_get *this, istreambuf_iterator_char *ret,
4902     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
4903 {
4904     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4905     return call_num_get_char_do_get_void(this, ret, first, last, base, state, pval);
4906 }
4907
4908 /* ?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 */
4909 /* ?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 */
4910 /* ?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 */
4911 /* ?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 */
4912 #define call_num_get_char_do_get_ldouble(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 8, istreambuf_iterator_char*, \
4913         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
4914         (this, ret, first, last, base, state, pval))
4915 #define call_num_get_char_do_get_double(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 12, istreambuf_iterator_char*, \
4916         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
4917         (this, ret, first, last, base, state, pval))
4918 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_double,36)
4919 istreambuf_iterator_char *__thiscall num_get_char_do_get_double(const num_get *this, istreambuf_iterator_char *ret,
4920     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
4921 {
4922     double v;
4923     char tmp[32], *end;
4924     int err;
4925
4926     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4927
4928     v = _Stodx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
4929     if(end!=tmp && !err)
4930         *pval = v;
4931     else
4932         *state |= IOSTATE_failbit;
4933
4934     if(!first.strbuf)
4935         *state |= IOSTATE_eofbit;
4936
4937     *ret = first;
4938     return ret;
4939 }
4940
4941 /* ?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 */
4942 /* ?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 */
4943 DEFINE_THISCALL_WRAPPER(num_get_char_get_ldouble,36)
4944 istreambuf_iterator_char *__thiscall num_get_char_get_ldouble(const num_get *this, istreambuf_iterator_char *ret,
4945         istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
4946 {
4947     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4948     return ret;
4949 }
4950
4951 /* ?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 */
4952 /* ?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 */
4953 DEFINE_THISCALL_WRAPPER(num_get_char_get_double,36)
4954 istreambuf_iterator_char *__thiscall num_get_char_get_double(const num_get *this, istreambuf_iterator_char *ret,
4955     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
4956 {
4957     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4958     return call_num_get_char_do_get_double(this, ret, first, last, base, state, pval);
4959 }
4960
4961 /* ?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 */
4962 /* ?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 */
4963 #define call_num_get_char_do_get_float(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 16, istreambuf_iterator_char*, \
4964         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, float*), \
4965         (this, ret, first, last, base, state, pval))
4966 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_float,36)
4967 istreambuf_iterator_char *__thiscall num_get_char_do_get_float(const num_get *this, istreambuf_iterator_char *ret,
4968     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
4969 {
4970     float v;
4971     char tmp[32], *end;
4972     int err;
4973
4974     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4975
4976     v = _Stofx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
4977     if(end!=tmp && !err)
4978         *pval = v;
4979     else
4980         *state |= IOSTATE_failbit;
4981
4982     if(!first.strbuf)
4983         *state |= IOSTATE_eofbit;
4984
4985     *ret = first;
4986     return ret;
4987 }
4988
4989 /* ?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 */
4990 /* ?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 */
4991 DEFINE_THISCALL_WRAPPER(num_get_char_get_float,36)
4992 istreambuf_iterator_char *__thiscall num_get_char_get_float(const num_get *this, istreambuf_iterator_char *ret,
4993     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
4994 {
4995     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4996     return call_num_get_char_do_get_float(this, ret, first, last, base, state, pval);
4997 }
4998
4999 /* ?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 */
5000 /* ?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 */
5001 #define call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 20, istreambuf_iterator_char*, \
5002         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONGLONG*), \
5003         (this, ret, first, last, base, state, pval))
5004 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint64,36)
5005 istreambuf_iterator_char *__thiscall num_get_char_do_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5006     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5007 {
5008     unsigned __int64 v;
5009     char tmp[25], *end;
5010     int err;
5011
5012     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5013
5014     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
5015                 &first, &last, base->fmtfl, base->loc), &err);
5016     if(end!=tmp && !err)
5017         *pval = v;
5018     else
5019         *state |= IOSTATE_failbit;
5020
5021     if(!first.strbuf)
5022         *state |= IOSTATE_eofbit;
5023
5024     *ret = first;
5025     return ret;
5026 }
5027
5028 /* ?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 */
5029 /* ?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 */
5030 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint64,36)
5031 istreambuf_iterator_char *__thiscall num_get_char_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5032     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5033 {
5034     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5035     return call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval);
5036 }
5037
5038 /* ?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 */
5039 /* ?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 */
5040 #define call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 24, istreambuf_iterator_char*, \
5041         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONGLONG*), \
5042         (this, ret, first, last, base, state, pval))
5043 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_int64,36)
5044 istreambuf_iterator_char *__thiscall num_get_char_do_get_int64(const num_get *this, istreambuf_iterator_char *ret,
5045     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
5046 {
5047     __int64 v;
5048     char tmp[25], *end;
5049     int err;
5050
5051     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5052
5053     v = _Stollx(tmp, &end, num_get_char__Getifld(this, tmp,
5054                 &first, &last, base->fmtfl, base->loc), &err);
5055     if(end!=tmp && !err)
5056         *pval = v;
5057     else
5058         *state |= IOSTATE_failbit;
5059
5060     if(!first.strbuf)
5061         *state |= IOSTATE_eofbit;
5062
5063     *ret = first;
5064     return ret;
5065 }
5066
5067 /* ?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 */
5068 /* ?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 */
5069 DEFINE_THISCALL_WRAPPER(num_get_char_get_int64,36)
5070 istreambuf_iterator_char *__thiscall num_get_char_get_int64(const num_get *this, istreambuf_iterator_char *ret,
5071     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
5072 {
5073     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5074     return call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval);
5075 }
5076
5077 /* ?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 */
5078 /* ?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 */
5079 #define call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 28, istreambuf_iterator_char*, \
5080         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONG*), \
5081         (this, ret, first, last, base, state, pval))
5082 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ulong,36)
5083 istreambuf_iterator_char *__thiscall num_get_char_do_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
5084     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
5085 {
5086     ULONG v;
5087     char tmp[25], *end;
5088     int err;
5089
5090     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5091
5092     v = _Stoulx(tmp, &end, num_get_char__Getifld(this, tmp,
5093                 &first, &last, base->fmtfl, base->loc), &err);
5094     if(end!=tmp && !err)
5095         *pval = v;
5096     else
5097         *state |= IOSTATE_failbit;
5098
5099     if(!first.strbuf)
5100         *state |= IOSTATE_eofbit;
5101
5102     *ret = first;
5103     return ret;
5104 }
5105
5106 /* ?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 */
5107 /* ?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 */
5108 DEFINE_THISCALL_WRAPPER(num_get_char_get_ulong,36)
5109 istreambuf_iterator_char *__thiscall num_get_char_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
5110     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
5111 {
5112     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5113     return call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
5114 }
5115
5116 /* ?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 */
5117 /* ?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 */
5118 #define call_num_get_char_do_get_long(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 32, istreambuf_iterator_char*, \
5119         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONG*), \
5120         (this, ret, first, last, base, state, pval))
5121 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_long,36)
5122 istreambuf_iterator_char *__thiscall num_get_char_do_get_long(const num_get *this, istreambuf_iterator_char *ret,
5123     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
5124 {
5125     LONG v;
5126     char tmp[25], *end;
5127     int err;
5128
5129     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5130
5131     v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
5132                 &first, &last, base->fmtfl, base->loc), &err);
5133     if(end!=tmp && !err)
5134         *pval = v;
5135     else
5136         *state |= IOSTATE_failbit;
5137
5138     if(!first.strbuf)
5139         *state |= IOSTATE_eofbit;
5140
5141     *ret = first;
5142     return ret;
5143 }
5144
5145 /* ?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 */
5146 /* ?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 */
5147 DEFINE_THISCALL_WRAPPER(num_get_char_get_long,36)
5148 istreambuf_iterator_char *__thiscall num_get_char_get_long(const num_get *this, istreambuf_iterator_char *ret,
5149     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
5150 {
5151     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5152     return call_num_get_char_do_get_long(this, ret, first, last, base, state, pval);
5153 }
5154
5155 /* ?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 */
5156 /* ?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 */
5157 #define call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 36, istreambuf_iterator_char*, \
5158         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned int*), \
5159         (this, ret, first, last, base, state, pval))
5160 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint,36)
5161 istreambuf_iterator_char *__thiscall num_get_char_do_get_uint(const num_get *this, istreambuf_iterator_char *ret,
5162     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned int *pval)
5163 {
5164     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5165     return num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
5166 }
5167
5168 /* ?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 */
5169 /* ?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 */
5170 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint,36)
5171 istreambuf_iterator_char *__thiscall num_get_char_get_uint(const num_get *this, istreambuf_iterator_char *ret,
5172     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned int *pval)
5173 {
5174     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5175     return call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval);
5176 }
5177
5178 /* ?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 */
5179 /* ?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 */
5180 #define call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 40, istreambuf_iterator_char*, \
5181         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned short*), \
5182         (this, ret, first, last, base, state, pval))
5183 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ushort,36)
5184 istreambuf_iterator_char *__thiscall num_get_char_do_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
5185     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
5186 {
5187     ULONG v;
5188     char tmp[25], *beg, *end;
5189     int err, b;
5190
5191     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5192
5193     b = num_get_char__Getifld(this, tmp,
5194             &first, &last, base->fmtfl, base->loc);
5195     beg = tmp + (tmp[0]=='-' ? 1 : 0);
5196     v = _Stoulx(beg, &end, b, &err);
5197
5198     if(v != (ULONG)((unsigned short)v))
5199         *state |= IOSTATE_failbit;
5200     else if(end!=beg && !err)
5201         *pval = (tmp[0]=='-' ? -((unsigned short)v) : v);
5202     else
5203         *state |= IOSTATE_failbit;
5204
5205     if(!first.strbuf)
5206         *state |= IOSTATE_eofbit;
5207
5208     *ret = first;
5209     return ret;
5210 }
5211
5212 /* ?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 */
5213 /* ?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 */
5214 DEFINE_THISCALL_WRAPPER(num_get_char_get_ushort,36)
5215 istreambuf_iterator_char *__thiscall num_get_char_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
5216     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
5217 {
5218     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5219     return call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval);
5220 }
5221
5222 /* ?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 */
5223 /* ?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 */
5224 #define call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 44, istreambuf_iterator_char*, \
5225         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, MSVCP_bool*), \
5226         (this, ret, first, last, base, state, pval))
5227 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_bool,36)
5228 istreambuf_iterator_char *__thiscall num_get_char_do_get_bool(const num_get *this, istreambuf_iterator_char *ret,
5229     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
5230 {
5231     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5232
5233     if(base->fmtfl & FMTFLAG_boolalpha) {
5234         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
5235         basic_string_char false_bstr, true_bstr;
5236         const char *pfalse, *ptrue;
5237
5238         numpunct_char_falsename(numpunct, &false_bstr);
5239         numpunct_char_truename(numpunct, &true_bstr);
5240         pfalse = MSVCP_basic_string_char_c_str(&false_bstr);
5241         ptrue = MSVCP_basic_string_char_c_str(&true_bstr);
5242
5243         for(istreambuf_iterator_char_val(&first); first.strbuf;
5244                 istreambuf_iterator_char_inc(&first)) {
5245             if(pfalse && *pfalse && first.val!=*pfalse)
5246                 pfalse = NULL;
5247             if(ptrue && *ptrue && first.val!=*ptrue)
5248                 ptrue = NULL;
5249
5250             if(pfalse && *pfalse && ptrue && !*ptrue)
5251                 ptrue = NULL;
5252             if(ptrue && *ptrue && pfalse && !*pfalse)
5253                 pfalse = NULL;
5254
5255             if(pfalse)
5256                 pfalse++;
5257             if(ptrue)
5258                 ptrue++;
5259
5260             if((!pfalse || !*pfalse) && (!ptrue || !*ptrue))
5261                 break;
5262         }
5263
5264         if(ptrue)
5265             *pval = TRUE;
5266         else if(pfalse)
5267             *pval = FALSE;
5268         else
5269             *state |= IOSTATE_failbit;
5270
5271         MSVCP_basic_string_char_dtor(&false_bstr);
5272         MSVCP_basic_string_char_dtor(&true_bstr);
5273     }else {
5274         char tmp[25], *end;
5275         int err;
5276         LONG v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
5277                     &first, &last, base->fmtfl, base->loc), &err);
5278
5279         if(end!=tmp && err==0 && (v==0 || v==1))
5280             *pval = v;
5281         else
5282             *state |= IOSTATE_failbit;
5283     }
5284
5285     if(!first.strbuf)
5286         *state |= IOSTATE_eofbit;
5287     memcpy(ret, &first, sizeof(first));
5288     return ret;
5289 }
5290
5291 /* ?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 */
5292 /* ?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 */
5293 DEFINE_THISCALL_WRAPPER(num_get_char_get_bool,36)
5294 istreambuf_iterator_char *__thiscall num_get_char_get_bool(const num_get *this, istreambuf_iterator_char *ret,
5295     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
5296 {
5297     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5298     return call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval);
5299 }
5300
5301 /* ?id@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
5302 locale_id num_put_char_id = {0};
5303
5304 /* num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
5305 extern const vtable_ptr MSVCP_num_put_char_vtable;
5306
5307 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
5308 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
5309 DEFINE_THISCALL_WRAPPER(num_put_char__Init, 8)
5310 void __thiscall num_put_char__Init(num_put *this, const _Locinfo *locinfo)
5311 {
5312     TRACE("(%p %p)\n", this, locinfo);
5313     _Locinfo__Getcvt(locinfo, &this->cvt);
5314 }
5315
5316 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
5317 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
5318 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_locinfo, 12)
5319 num_put* __thiscall num_put_char_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
5320 {
5321     TRACE("(%p %p %ld)\n", this, locinfo, refs);
5322
5323     locale_facet_ctor_refs(&this->facet, refs);
5324     this->facet.vtable = &MSVCP_num_put_char_vtable;
5325
5326     num_put_char__Init(this, locinfo);
5327     return this;
5328 }
5329
5330 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
5331 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
5332 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_refs, 8)
5333 num_put* __thiscall num_put_char_ctor_refs(num_put *this, MSVCP_size_t refs)
5334 {
5335      _Locinfo locinfo;
5336
5337      TRACE("(%p %lu)\n", this, refs);
5338
5339      _Locinfo_ctor(&locinfo);
5340      num_put_char_ctor_locinfo(this, &locinfo, refs);
5341      _Locinfo_dtor(&locinfo);
5342      return this;
5343 }
5344
5345 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
5346 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
5347 DEFINE_THISCALL_WRAPPER(num_put_char_ctor, 4)
5348 num_put* __thiscall num_put_char_ctor(num_put *this)
5349 {
5350     return num_put_char_ctor_refs(this, 0);
5351 }
5352
5353 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
5354 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
5355 DEFINE_THISCALL_WRAPPER(num_put_char_dtor, 4)
5356 void __thiscall num_put_char_dtor(num_put *this)
5357 {
5358     TRACE("(%p)\n", this);
5359     locale_facet_dtor(&this->facet);
5360 }
5361
5362 DEFINE_THISCALL_WRAPPER(MSVCP_num_put_char_vector_dtor, 8)
5363 num_put* __thiscall MSVCP_num_put_char_vector_dtor(num_put *this, unsigned int flags)
5364 {
5365     TRACE("(%p %x)\n", this, flags);
5366     if(flags & 2) {
5367         /* we have an array, with the number of elements stored before the first object */
5368         int i, *ptr = (int *)this-1;
5369
5370         for(i=*ptr-1; i>=0; i--)
5371             num_put_char_dtor(this+i);
5372         MSVCRT_operator_delete(ptr);
5373     } else {
5374         num_put_char_dtor(this);
5375         if(flags & 1)
5376             MSVCRT_operator_delete(this);
5377     }
5378
5379     return this;
5380 }
5381
5382 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
5383 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
5384 unsigned int __cdecl num_put_char__Getcat(const locale_facet **facet, const locale *loc)
5385 {
5386     TRACE("(%p %p)\n", facet, loc);
5387
5388     if(facet && !*facet) {
5389         _Locinfo locinfo;
5390
5391         *facet = MSVCRT_operator_new(sizeof(num_put));
5392         if(!*facet) {
5393             ERR("Out of memory\n");
5394             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
5395             return 0;
5396         }
5397
5398         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
5399         num_put_char_ctor_locinfo((num_put*)*facet, &locinfo, 0);
5400         _Locinfo_dtor(&locinfo);
5401     }
5402
5403     return LC_NUMERIC;
5404 }
5405
5406 /* ?_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 */
5407 /* ?_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 */
5408 ostreambuf_iterator_char* __cdecl num_put_char__Put(const num_put *this, ostreambuf_iterator_char *ret,
5409         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count)
5410 {
5411     TRACE("(%p %p %p %ld)\n", this, ret, ptr, count);
5412
5413     for(; count>0; count--)
5414         ostreambuf_iterator_char_put(&dest, *ptr++);
5415
5416     *ret = dest;
5417     return ret;
5418 }
5419
5420 /* ?_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 */
5421 /* ?_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 */
5422 ostreambuf_iterator_char* __cdecl num_put_char__Putc(const num_put *this, ostreambuf_iterator_char *ret,
5423         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count)
5424 {
5425     TRACE("(%p %p %p %ld)\n", this, ret, ptr, count);
5426
5427     for(; count>0; count--)
5428         ostreambuf_iterator_char_put(&dest, *ptr++);
5429
5430     *ret = dest;
5431     return ret;
5432 }
5433
5434 /* ?_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 */
5435 /* ?_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 */
5436 ostreambuf_iterator_char* __cdecl num_put_char__Putgrouped(const num_put *this, ostreambuf_iterator_char *ret,
5437         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count, char delim)
5438 {
5439     FIXME("(%p %p %p %ld %d) stub\n", this, ret, ptr, count, delim);
5440     return NULL;
5441 }
5442
5443 /* ?_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 */
5444 /* ?_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 */
5445 ostreambuf_iterator_char* __cdecl num_put_char__Rep(const num_put *this, ostreambuf_iterator_char *ret,
5446         ostreambuf_iterator_char dest, char c, MSVCP_size_t count)
5447 {
5448     TRACE("(%p %p %d %ld)\n", this, ret, c, count);
5449
5450     for(; count>0; count--)
5451         ostreambuf_iterator_char_put(&dest, c);
5452
5453     *ret = dest;
5454     return ret;
5455 }
5456
5457 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADDH@Z */
5458 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADDH@Z */
5459 char* __cdecl num_put_char__Ffmt(const num_put *this, char *fmt, char spec, int fmtfl)
5460 {
5461     FIXME("(%p %p %d %d) stub\n", this, fmt, spec, fmtfl);
5462     return NULL;
5463 }
5464
5465 /* ?_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 */
5466 /* ?_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 */
5467 ostreambuf_iterator_char* __cdecl num_put_char__Fput(const num_put *this, ostreambuf_iterator_char *ret,
5468         ostreambuf_iterator_char dest, ios_base *base, char fill, const char *buf, MSVCP_size_t bef_point,
5469         MSVCP_size_t aft_point, MSVCP_size_t trailing, MSVCP_size_t count)
5470 {
5471     FIXME("(%p %p %p %d %p %ld %ld %ld %ld) stub\n", this, ret, base,
5472             fill, buf, bef_point, aft_point, trailing, count);
5473     return NULL;
5474 }
5475
5476 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADPBDH@Z */
5477 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
5478 char* __cdecl num_put_char__Ifmt(const num_put *this, char *fmt, const char *spec, int fmtfl)
5479 {
5480     int base = fmtfl & FMTFLAG_basefield;
5481     char *p = fmt;
5482
5483     TRACE("(%p %p %p %d)\n", this, fmt, spec, fmtfl);
5484
5485     *p++ = '%';
5486     if(fmtfl & FMTFLAG_showpos)
5487         *p++ = '+';
5488     if(fmtfl & FMTFLAG_showbase)
5489         *p++ = '#';
5490
5491     *p++ = *spec++;
5492     if(*spec == 'l')
5493         *p++ = *spec++;
5494
5495     if(base == FMTFLAG_oct)
5496         *p++ = 'o';
5497     else if(base == FMTFLAG_hex)
5498         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'X' : 'x';
5499     else
5500         *p++ = *spec;
5501
5502     *p++ = '\0';
5503     return fmt;
5504 }
5505
5506 /* ?_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 */
5507 /* ?_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 */
5508 ostreambuf_iterator_char* __cdecl num_put_char__Iput(const num_put *this, ostreambuf_iterator_char *ret,
5509         ostreambuf_iterator_char dest, ios_base *base, char fill, char *buf, MSVCP_size_t count)
5510 {
5511     numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
5512     basic_string_char grouping_bstr;
5513     const char *grouping;
5514     char *p, sep;
5515     int cur_group = 0, group_size = 0;
5516     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
5517     MSVCP_size_t pad;
5518
5519     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
5520
5521     /* Add separators to number */
5522     numpunct_char_grouping(numpunct, &grouping_bstr);
5523     grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
5524     sep = grouping[0] ? numpunct_char_thousands_sep(numpunct) : '\0';
5525
5526     for(p=buf+count-1; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
5527         group_size++;
5528         if(group_size == grouping[cur_group]) {
5529             group_size = 0;
5530             if(grouping[cur_group+1])
5531                 cur_group++;
5532
5533             memmove(p+1, p, buf+count-p);
5534             *p = sep;
5535             count++;
5536         }
5537     }
5538     MSVCP_basic_string_char_dtor(&grouping_bstr);
5539
5540     /* Display number with padding */
5541     if(count >= base->wide)
5542         pad = 0;
5543     else
5544         pad = base->wide-count;
5545     base->wide = 0;
5546
5547     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
5548         num_put_char__Putc(this, &dest, dest, buf, 1);
5549         buf++;
5550     }else if((adjustfield & FMTFLAG_internal) && (buf[1]=='x' || buf[1]=='X')) {
5551         num_put_char__Putc(this, &dest, dest, buf, 2);
5552         buf += 2;
5553     }
5554     if(adjustfield != FMTFLAG_left) {
5555         num_put_char__Rep(this, ret, dest, fill, pad);
5556         pad = 0;
5557     }
5558     num_put_char__Putc(this, &dest, dest, buf, count);
5559     return num_put_char__Rep(this, ret, dest, fill, pad);
5560 }
5561
5562 /* ?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 */
5563 /* ?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 */
5564 #define call_num_put_char_do_put_long(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 28, ostreambuf_iterator_char*, \
5565         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, LONG), \
5566         (this, ret, dest, base, fill, v))
5567 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_long, 28)
5568 ostreambuf_iterator_char* __thiscall num_put_char_do_put_long(const num_put *this, ostreambuf_iterator_char *ret,
5569         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
5570 {
5571     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
5572     char fmt[7]; /* strlen("%+#lld")+1 */
5573
5574     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
5575
5576     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
5577             sprintf(tmp, num_put_char__Ifmt(this, fmt, "ld", base->fmtfl), v));
5578 }
5579
5580 /* ?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 */
5581 /* ?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 */
5582 DEFINE_THISCALL_WRAPPER(num_put_char_put_long, 28)
5583 ostreambuf_iterator_char* __thiscall num_put_char_put_long(const num_put *this, ostreambuf_iterator_char *ret,
5584         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
5585 {
5586     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
5587     return call_num_put_char_do_put_long(this, ret, dest, base, fill, v);
5588 }
5589
5590 /* ?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 */
5591 /* ?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 */
5592 #define call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 24, ostreambuf_iterator_char*, \
5593         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, ULONG), \
5594         (this, ret, dest, base, fill, v))
5595 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ulong, 28)
5596 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
5597         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
5598 {
5599     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
5600     char fmt[7]; /* strlen("%+#lld")+1 */
5601
5602     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
5603
5604     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
5605             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lu", base->fmtfl), v));
5606 }
5607
5608 /* ?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 */
5609 /* ?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 */
5610 DEFINE_THISCALL_WRAPPER(num_put_char_put_ulong, 28)
5611 ostreambuf_iterator_char* __thiscall num_put_char_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
5612         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
5613 {
5614     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
5615     return call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v);
5616 }
5617
5618 /* ?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 */
5619 /* ?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 */
5620 /* ?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 */
5621 /* ?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 */
5622 #define call_num_put_char_do_put_double(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 12, ostreambuf_iterator_char*, \
5623         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
5624         (this, ret, dest, base, fill, v))
5625 #define call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 8, ostreambuf_iterator_char*, \
5626         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
5627         (this, ret, dest, base, fill, v))
5628 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_double, 32)
5629 ostreambuf_iterator_char* __thiscall num_put_char_do_put_double(const num_put *this, ostreambuf_iterator_char *ret,
5630         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
5631 {
5632     FIXME("(%p %p %p %d %lf) stub\n", this, ret, base, fill, v);
5633     return NULL;
5634 }
5635
5636 /* ?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 */
5637 /* ?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 */
5638 DEFINE_THISCALL_WRAPPER(num_put_char_put_double, 32)
5639 ostreambuf_iterator_char* __thiscall num_put_char_put_double(const num_put *this, ostreambuf_iterator_char *ret,
5640         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
5641 {
5642     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
5643     return call_num_put_char_do_put_double(this, ret, dest, base, fill, v);
5644 }
5645
5646 /* ?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 */
5647 /* ?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 */
5648 DEFINE_THISCALL_WRAPPER(num_put_char_put_ldouble, 32)
5649 ostreambuf_iterator_char* __thiscall num_put_char_put_ldouble(const num_put *this, ostreambuf_iterator_char *ret,
5650         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
5651 {
5652     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
5653     return call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v);
5654 }
5655
5656 /* ?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 */
5657 /* ?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 */
5658 #define call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 4, ostreambuf_iterator_char*, \
5659         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, const void*), \
5660         (this, ret, dest, base, fill, v))
5661 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ptr, 28)
5662 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
5663         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
5664 {
5665     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
5666
5667     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
5668
5669     return num_put_char__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
5670 }
5671
5672 /* ?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 */
5673 /* ?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 */
5674 DEFINE_THISCALL_WRAPPER(num_put_char_put_ptr, 28)
5675 ostreambuf_iterator_char* __thiscall num_put_char_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
5676         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
5677 {
5678     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
5679     return call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v);
5680 }
5681
5682 /* ?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 */
5683 /* ?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 */
5684 #define call_num_put_char_do_put_int64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 20, ostreambuf_iterator_char*, \
5685         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, __int64), \
5686         (this, ret, dest, base, fill, v))
5687 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_int64, 32)
5688 ostreambuf_iterator_char* __thiscall num_put_char_do_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
5689         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
5690 {
5691     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
5692     char fmt[7]; /* strlen("%+#lld")+1 */
5693
5694     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
5695
5696     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
5697             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lld", base->fmtfl), v));
5698 }
5699
5700 /* ?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 */
5701 /* ?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 */
5702 DEFINE_THISCALL_WRAPPER(num_put_char_put_int64, 32)
5703 ostreambuf_iterator_char* __thiscall num_put_char_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
5704         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
5705 {
5706     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
5707     return call_num_put_char_do_put_int64(this, ret, dest, base, fill, v);
5708 }
5709
5710 /* ?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 */
5711 /* ?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 */
5712 #define call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 16, ostreambuf_iterator_char*, \
5713         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, unsigned __int64), \
5714         (this, ret, dest, base, fill, v))
5715 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_uint64, 32)
5716 ostreambuf_iterator_char* __thiscall num_put_char_do_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
5717         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
5718 {
5719     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
5720     char fmt[7]; /* strlen("%+#lld")+1 */
5721
5722     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
5723
5724     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
5725             sprintf(tmp, num_put_char__Ifmt(this, fmt, "llu", base->fmtfl), v));
5726 }
5727
5728 /* ?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 */
5729 /* ?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 */
5730 DEFINE_THISCALL_WRAPPER(num_put_char_put_uint64, 32)
5731 ostreambuf_iterator_char* __thiscall num_put_char_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
5732         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
5733 {
5734     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
5735     return call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v);
5736 }
5737
5738 /* ?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 */
5739 /* ?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 */
5740 #define call_num_put_char_do_put_bool(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 32, ostreambuf_iterator_char*, \
5741         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, MSVCP_bool), \
5742         (this, ret, dest, base, fill, v))
5743 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_bool, 28)
5744 ostreambuf_iterator_char* __thiscall num_put_char_do_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
5745         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
5746 {
5747     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
5748
5749     if(base->fmtfl & FMTFLAG_boolalpha) {
5750         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
5751         basic_string_char str;
5752         MSVCP_size_t pad, len;
5753
5754         if(v)
5755             numpunct_char_truename(numpunct, &str);
5756         else
5757             numpunct_char_falsename(numpunct, &str);
5758
5759         len = MSVCP_basic_string_char_length(&str);
5760         pad = (len>base->wide ? 0 : base->wide-len);
5761         base->wide = 0;
5762
5763         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
5764             num_put_char__Rep(this, &dest, dest, fill, pad);
5765             pad = 0;
5766         }
5767         num_put_char__Putc(this, &dest, dest, MSVCP_basic_string_char_c_str(&str), len);
5768         MSVCP_basic_string_char_dtor(&str);
5769         return num_put_char__Rep(this, ret, dest, fill, pad);
5770     }
5771
5772     return num_put_char_put_long(this, ret, dest, base, fill, v);
5773 }
5774
5775 /* ?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 */
5776 /* ?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 */
5777 DEFINE_THISCALL_WRAPPER(num_put_char_put_bool, 28)
5778 ostreambuf_iterator_char* __thiscall num_put_char_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
5779         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
5780 {
5781     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
5782     return call_num_put_char_do_put_bool(this, ret, dest, base, fill, v);
5783 }
5784
5785 /* ??0_Locimp@locale@std@@AAE@_N@Z */
5786 /* ??0_Locimp@locale@std@@AEAA@_N@Z */
5787 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor_transparent, 8)
5788 locale__Locimp* __thiscall locale__Locimp_ctor_transparent(locale__Locimp *this, MSVCP_bool transparent)
5789 {
5790     TRACE("(%p %d)\n", this, transparent);
5791
5792     memset(this, 0, sizeof(locale__Locimp));
5793     locale_facet_ctor_refs(&this->facet, 1);
5794     this->transparent = transparent;
5795     MSVCP_basic_string_char_ctor_cstr(&this->name, "*");
5796     return this;
5797 }
5798
5799 /* ??_F_Locimp@locale@std@@QAEXXZ */
5800 /* ??_F_Locimp@locale@std@@QEAAXXZ */
5801 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor, 4)
5802 locale__Locimp* __thiscall locale__Locimp_ctor(locale__Locimp *this)
5803 {
5804     return locale__Locimp_ctor_transparent(this, FALSE);
5805 }
5806
5807 /* ??0_Locimp@locale@std@@AAE@ABV012@@Z */
5808 /* ??0_Locimp@locale@std@@AEAA@AEBV012@@Z */
5809 DEFINE_THISCALL_WRAPPER(locale__Locimp_copy_ctor, 8)
5810 locale__Locimp* __thiscall locale__Locimp_copy_ctor(locale__Locimp *this, const locale__Locimp *copy)
5811 {
5812     _Lockit lock;
5813     MSVCP_size_t i;
5814
5815     TRACE("(%p %p)\n", this, copy);
5816
5817     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
5818     memcpy(this, copy, sizeof(locale__Locimp));
5819     locale_facet_ctor_refs(&this->facet, 1);
5820     if(copy->facetvec) {
5821         this->facetvec = MSVCRT_operator_new(copy->facet_cnt*sizeof(locale_facet*));
5822         if(!this->facetvec) {
5823             _Lockit_dtor(&lock);
5824             ERR("Out of memory\n");
5825             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
5826             return NULL;
5827         }
5828         for(i=0; i<this->facet_cnt; i++)
5829             if(this->facetvec[i])
5830                 locale_facet__Incref(this->facetvec[i]);
5831     }
5832     MSVCP_basic_string_char_copy_ctor(&this->name, &copy->name);
5833     _Lockit_dtor(&lock);
5834     return this;
5835 }
5836
5837 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPAV123@ABV123@@Z */
5838 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPEAV123@AEBV123@@Z */
5839 locale__Locimp* __cdecl locale__Locimp__Locimp_ctor(locale__Locimp *this, const locale__Locimp *copy)
5840 {
5841     return locale__Locimp_copy_ctor(this, copy);
5842 }
5843
5844 /* ??1_Locimp@locale@std@@MAE@XZ */
5845 /* ??1_Locimp@locale@std@@MEAA@XZ */
5846 DEFINE_THISCALL_WRAPPER(locale__Locimp_dtor, 4)
5847 void __thiscall locale__Locimp_dtor(locale__Locimp *this)
5848 {
5849     TRACE("(%p)\n", this);
5850
5851     if(locale_facet__Decref(&this->facet)) {
5852         MSVCP_size_t i;
5853         for(i=0; i<this->facet_cnt; i++)
5854             if(this->facetvec[i] && locale_facet__Decref(this->facetvec[i]))
5855                 call_locale_facet_vector_dtor(this->facetvec[i], 0);
5856
5857         MSVCRT_operator_delete(this->facetvec);
5858         MSVCP_basic_string_char_dtor(&this->name);
5859     }
5860 }
5861
5862 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPAV123@@Z */
5863 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPEAV123@@Z */
5864 void __cdecl locale__Locimp__Locimp_dtor(locale__Locimp *this)
5865 {
5866     locale__Locimp_dtor(this);
5867 }
5868
5869 DEFINE_THISCALL_WRAPPER(MSVCP_locale__Locimp_vector_dtor, 8)
5870 locale__Locimp* __thiscall MSVCP_locale__Locimp_vector_dtor(locale__Locimp *this, unsigned int flags)
5871 {
5872     TRACE("(%p %x)\n", this, flags);
5873     if(flags & 2) {
5874         /* we have an array, with the number of elements stored before the first object */
5875         int i, *ptr = (int *)this-1;
5876
5877         for(i=*ptr-1; i>=0; i--)
5878             locale__Locimp_dtor(this+i);
5879         MSVCRT_operator_delete(ptr);
5880     } else {
5881         locale__Locimp_dtor(this);
5882         if(flags & 1)
5883             MSVCRT_operator_delete(this);
5884     }
5885
5886     return this;
5887 }
5888
5889 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPAV123@PAVfacet@23@I@Z */
5890 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPEAV123@PEAVfacet@23@_K@Z */
5891 void __cdecl locale__Locimp__Locimp_Addfac(locale__Locimp *locimp, locale_facet *facet, MSVCP_size_t id)
5892 {
5893     _Lockit lock;
5894
5895     TRACE("(%p %p %lu)\n", locimp, facet, id);
5896
5897     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
5898     if(id >= locimp->facet_cnt) {
5899         MSVCP_size_t new_size = id+1;
5900         locale_facet **new_facetvec;
5901
5902         if(new_size < locale_id__Id_cnt+1)
5903             new_size = locale_id__Id_cnt+1;
5904
5905         new_facetvec = MSVCRT_operator_new(sizeof(locale_facet*)*new_size);
5906         if(!new_facetvec) {
5907             _Lockit_dtor(&lock);
5908             ERR("Out of memory\n");
5909             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
5910             return;
5911         }
5912
5913         memset(new_facetvec, 0, sizeof(locale_facet*)*new_size);
5914         memcpy(new_facetvec, locimp->facetvec, sizeof(locale_facet*)*locimp->facet_cnt);
5915         MSVCRT_operator_delete(locimp->facetvec);
5916         locimp->facetvec = new_facetvec;
5917         locimp->facet_cnt = new_size;
5918     }
5919
5920     if(locimp->facetvec[id] && locale_facet__Decref(locimp->facetvec[id]))
5921         call_locale_facet_vector_dtor(locimp->facetvec[id], 0);
5922
5923     locimp->facetvec[id] = facet;
5924     if(facet)
5925         locale_facet__Incref(facet);
5926     _Lockit_dtor(&lock);
5927 }
5928
5929 /* ?_Addfac@_Locimp@locale@std@@AAEXPAVfacet@23@I@Z */
5930 /* ?_Addfac@_Locimp@locale@std@@AEAAXPEAVfacet@23@_K@Z */
5931 DEFINE_THISCALL_WRAPPER(locale__Locimp__Addfac, 12)
5932 void __thiscall locale__Locimp__Addfac(locale__Locimp *this, locale_facet *facet, MSVCP_size_t id)
5933 {
5934     locale__Locimp__Locimp_Addfac(this, facet, id);
5935 }
5936
5937 /* ?_Clocptr_func@_Locimp@locale@std@@CAAAPAV123@XZ */
5938 /* ?_Clocptr_func@_Locimp@locale@std@@CAAEAPEAV123@XZ */
5939 locale__Locimp** __cdecl locale__Locimp__Clocptr_func(void)
5940 {
5941     FIXME("stub\n");
5942     return NULL;
5943 }
5944
5945 /* ?_Makeloc@_Locimp@locale@std@@CAPAV123@ABV_Locinfo@3@HPAV123@PBV23@@Z */
5946 /* ?_Makeloc@_Locimp@locale@std@@CAPEAV123@AEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
5947 locale__Locimp* __cdecl locale__Locimp__Makeloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
5948 {
5949     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
5950     return NULL;
5951 }
5952
5953 /* ?_Makeushloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
5954 /* ?_Makeushloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
5955 void __cdecl locale__Locimp__Makeushloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
5956 {
5957     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
5958 }
5959
5960 /* ?_Makewloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
5961 /* ?_Makewloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
5962 void __cdecl locale__Locimp__Makewloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
5963 {
5964     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
5965 }
5966
5967 /* ?_Makexloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
5968 /* ?_Makexloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
5969 void __cdecl locale__Locimp__Makexloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
5970 {
5971     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
5972 }
5973
5974 /* ??_7_Locimp@locale@std@@6B@ */
5975 const vtable_ptr MSVCP_locale__Locimp_vtable[] = {
5976     (vtable_ptr)THISCALL_NAME(MSVCP_locale__Locimp_vector_dtor)
5977 };
5978
5979 /* ??0locale@std@@AAE@PAV_Locimp@01@@Z */
5980 /* ??0locale@std@@AEAA@PEAV_Locimp@01@@Z */
5981 DEFINE_THISCALL_WRAPPER(locale_ctor_locimp, 8)
5982 locale* __thiscall locale_ctor_locimp(locale *this, locale__Locimp *locimp)
5983 {
5984     TRACE("(%p %p)\n", this, locimp);
5985     /* Don't change locimp reference counter */
5986     this->ptr = locimp;
5987     return this;
5988 }
5989
5990 /* ?_Init@locale@std@@CAPAV_Locimp@12@XZ */
5991 /* ?_Init@locale@std@@CAPEAV_Locimp@12@XZ */
5992 locale__Locimp* __cdecl locale__Init(void)
5993 {
5994     _Lockit lock;
5995
5996     TRACE("\n");
5997
5998     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
5999     if(global_locale) {
6000         _Lockit_dtor(&lock);
6001         return global_locale;
6002     }
6003
6004     global_locale = MSVCRT_operator_new(sizeof(locale__Locimp));
6005     if(!global_locale) {
6006         _Lockit_dtor(&lock);
6007         ERR("Out of memory\n");
6008         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6009         return NULL;
6010     }
6011
6012     locale__Locimp_ctor(global_locale);
6013     global_locale->catmask = (1<<(LC_MAX+1))-1;
6014     MSVCP_basic_string_char_dtor(&global_locale->name);
6015     MSVCP_basic_string_char_ctor_cstr(&global_locale->name, "C");
6016
6017     locale__Locimp__Clocptr = global_locale;
6018     global_locale->facet.refs++;
6019     locale_ctor_locimp(&classic_locale, locale__Locimp__Clocptr);
6020     _Lockit_dtor(&lock);
6021
6022     return global_locale;
6023 }
6024
6025 /* ??0locale@std@@QAE@ABV01@0H@Z */
6026 /* ??0locale@std@@QEAA@AEBV01@0H@Z */
6027 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_locale, 16)
6028 locale* __thiscall locale_ctor_locale_locale(locale *this, const locale *loc, const locale *other, category cat)
6029 {
6030     FIXME("(%p %p %p %d) stub\n", this, loc, other, cat);
6031     return NULL;
6032 }
6033
6034 /* ??0locale@std@@QAE@ABV01@@Z */
6035 /* ??0locale@std@@QEAA@AEBV01@@Z */
6036 DEFINE_THISCALL_WRAPPER(locale_copy_ctor, 8)
6037 locale* __thiscall locale_copy_ctor(locale *this, const locale *copy)
6038 {
6039     TRACE("(%p %p)\n", this, copy);
6040     this->ptr = copy->ptr;
6041     locale_facet__Incref(&this->ptr->facet);
6042     return this;
6043 }
6044
6045 /* ??0locale@std@@QAE@ABV01@PBDH@Z */
6046 /* ??0locale@std@@QEAA@AEBV01@PEBDH@Z */
6047 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_cstr, 16)
6048 locale* __thiscall locale_ctor_locale_cstr(locale *this, const locale *loc, const char *locname, category cat)
6049 {
6050     FIXME("(%p %p %s %d) stub\n", this, loc, locname, cat);
6051     return NULL;
6052 }
6053
6054 /* ??0locale@std@@QAE@PBDH@Z */
6055 /* ??0locale@std@@QEAA@PEBDH@Z */
6056 DEFINE_THISCALL_WRAPPER(locale_ctor_cstr, 12)
6057 locale* __thiscall locale_ctor_cstr(locale *this, const char *locname, category cat)
6058 {
6059     FIXME("(%p %s %d) stub\n", this, locname, cat);
6060     return NULL;
6061 }
6062
6063 /* ??0locale@std@@QAE@W4_Uninitialized@1@@Z */
6064 /* ??0locale@std@@QEAA@W4_Uninitialized@1@@Z */
6065 DEFINE_THISCALL_WRAPPER(locale_ctor_uninitialized, 8)
6066 locale* __thiscall locale_ctor_uninitialized(locale *this, int uninitialized)
6067 {
6068     TRACE("(%p)\n", this);
6069     this->ptr = NULL;
6070     return this;
6071 }
6072
6073 /* ??0locale@std@@QAE@XZ */
6074 /* ??0locale@std@@QEAA@XZ */
6075 DEFINE_THISCALL_WRAPPER(locale_ctor, 4)
6076 locale* __thiscall locale_ctor(locale *this)
6077 {
6078     TRACE("(%p)\n", this);
6079     this->ptr = locale__Init();
6080     locale_facet__Incref(&this->ptr->facet);
6081     return this;
6082 }
6083
6084 /* ??1locale@std@@QAE@XZ */
6085 /* ??1locale@std@@QEAA@XZ */
6086 DEFINE_THISCALL_WRAPPER(locale_dtor, 4)
6087 void __thiscall locale_dtor(locale *this)
6088 {
6089     TRACE("(%p)\n", this);
6090     if(this->ptr)
6091         locale__Locimp_dtor(this->ptr);
6092 }
6093
6094 DEFINE_THISCALL_WRAPPER(MSVCP_locale_vector_dtor, 8)
6095 locale* __thiscall MSVCP_locale_vector_dtor(locale *this, unsigned int flags)
6096 {
6097     TRACE("(%p %x)\n", this, flags);
6098     if(flags & 2) {
6099         /* we have an array, with the number of elements stored before the first object */
6100         int i, *ptr = (int *)this-1;
6101
6102         for(i=*ptr-1; i>=0; i--)
6103             locale_dtor(this+i);
6104         MSVCRT_operator_delete(ptr);
6105     } else {
6106         locale_dtor(this);
6107         if(flags & 1)
6108             MSVCRT_operator_delete(this);
6109     }
6110
6111     return this;
6112 }
6113
6114 /* ??4locale@std@@QAEAAV01@ABV01@@Z */
6115 /* ??4locale@std@@QEAAAEAV01@AEBV01@@Z */
6116 DEFINE_THISCALL_WRAPPER(locale_operator_assign, 8)
6117 locale* __thiscall locale_operator_assign(locale *this, const locale *loc)
6118 {
6119     FIXME("(%p %p) stub\n", this, loc);
6120     return NULL;
6121 }
6122
6123 /* ??8locale@std@@QBE_NABV01@@Z */
6124 /* ??8locale@std@@QEBA_NAEBV01@@Z */
6125 DEFINE_THISCALL_WRAPPER(locale_operator_equal, 8)
6126 MSVCP_bool __thiscall locale_operator_equal(const locale *this, const locale *loc)
6127 {
6128     FIXME("(%p %p) stub\n", this, loc);
6129     return 0;
6130 }
6131
6132 /* ??9locale@std@@QBE_NABV01@@Z */
6133 /* ??9locale@std@@QEBA_NAEBV01@@Z */
6134 DEFINE_THISCALL_WRAPPER(locale_operator_not_equal, 8)
6135 MSVCP_bool __thiscall locale_operator_not_equal(const locale *this, locale const *loc)
6136 {
6137     FIXME("(%p %p) stub\n", this, loc);
6138     return 0;
6139 }
6140
6141 /* ?_Addfac@locale@std@@QAEAAV12@PAVfacet@12@II@Z */
6142 /* ?_Addfac@locale@std@@QEAAAEAV12@PEAVfacet@12@_K1@Z */
6143 DEFINE_THISCALL_WRAPPER(locale__Addfac, 16)
6144 locale* __thiscall locale__Addfac(locale *this, locale_facet *facet, MSVCP_size_t id, MSVCP_size_t catmask)
6145 {
6146     TRACE("(%p %p %lu %lu)\n", this, facet, id, catmask);
6147
6148     if(this->ptr->facet.refs > 1) {
6149         locale__Locimp *new_ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
6150         if(!new_ptr) {
6151             ERR("Out of memory\n");
6152             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6153             return NULL;
6154         }
6155         locale__Locimp_copy_ctor(new_ptr, this->ptr);
6156         locale_facet__Decref(&this->ptr->facet);
6157         this->ptr = new_ptr;
6158     }
6159
6160     locale__Locimp__Addfac(this->ptr, facet, id);
6161
6162     if(catmask) {
6163         MSVCP_basic_string_char_dtor(&this->ptr->name);
6164         MSVCP_basic_string_char_ctor_cstr(&this->ptr->name, "*");
6165     }
6166     return this;
6167 }
6168
6169 /* ?_Getfacet@locale@std@@QBEPBVfacet@12@I@Z */
6170 /* ?_Getfacet@locale@std@@QEBAPEBVfacet@12@_K@Z */
6171 DEFINE_THISCALL_WRAPPER(locale__Getfacet, 8)
6172 const locale_facet* __thiscall locale__Getfacet(const locale *this, MSVCP_size_t id)
6173 {
6174     locale_facet *fac;
6175
6176     TRACE("(%p %lu)\n", this, id);
6177
6178     fac = id < this->ptr->facet_cnt ? this->ptr->facetvec[id] : NULL;
6179     if(fac || !this->ptr->transparent)
6180         return fac;
6181
6182     return id < global_locale->facet_cnt ? global_locale->facetvec[id] : NULL;
6183 }
6184
6185 /* ?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ */
6186 /* ?_Getgloballocale@locale@std@@CAPEAV_Locimp@12@XZ */
6187 locale__Locimp* __cdecl locale__Getgloballocale(void)
6188 {
6189     TRACE("\n");
6190     return global_locale;
6191 }
6192
6193 /* ?_Setgloballocale@locale@std@@CAXPAX@Z */
6194 /* ?_Setgloballocale@locale@std@@CAXPEAX@Z */
6195 void __cdecl locale__Setgloballocale(void *locimp)
6196 {
6197     TRACE("(%p)\n", locimp);
6198     global_locale = locimp;
6199 }
6200
6201 /* ?classic@locale@std@@SAABV12@XZ */
6202 /* ?classic@locale@std@@SAAEBV12@XZ */
6203 const locale* __cdecl locale_classic(void)
6204 {
6205     TRACE("\n");
6206     locale__Init();
6207     return &classic_locale;
6208 }
6209
6210 /* ?name@locale@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
6211 /* ?name@locale@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
6212 DEFINE_THISCALL_WRAPPER(locale_name, 8)
6213 basic_string_char* __thiscall locale_name(const locale *this, basic_string_char *ret)
6214 {
6215     TRACE( "(%p)\n", this);
6216     MSVCP_basic_string_char_copy_ctor(ret, &this->ptr->name);
6217     return ret;
6218 }
6219
6220 /* ?global@locale@std@@SA?AV12@ABV12@@Z */
6221 /* ?global@locale@std@@SA?AV12@AEBV12@@Z */
6222 locale* __cdecl locale_global(locale *ret, const locale *loc)
6223 {
6224     _Lockit lock;
6225     int i;
6226
6227     TRACE("(%p %p)\n", loc, ret);
6228
6229     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
6230     locale_ctor(ret);
6231
6232     if(loc->ptr != global_locale) {
6233         locale_facet__Decref(&global_locale->facet);
6234         global_locale = loc->ptr;
6235         locale_facet__Incref(&global_locale->facet);
6236
6237         for(i=LC_ALL+1; i<=LC_MAX; i++) {
6238             if((global_locale->catmask & (1<<(i-1))) == 0)
6239                 continue;
6240             setlocale(i, MSVCP_basic_string_char_c_str(&global_locale->name));
6241         }
6242     }
6243     _Lockit_dtor(&lock);
6244     return ret;
6245 }
6246
6247 DEFINE_RTTI_DATA0(locale_facet, 0, ".?AVfacet@locale@std@@");
6248 DEFINE_RTTI_DATA1(collate_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@D@std@@");
6249 DEFINE_RTTI_DATA1(collate_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@_W@std@@");
6250 DEFINE_RTTI_DATA1(collate_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@G@std@@");
6251 DEFINE_RTTI_DATA1(ctype_base, 0, &locale_facet_rtti_base_descriptor, ".?AUctype_base@std@@");
6252 DEFINE_RTTI_DATA2(ctype_char, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@D@std@@");
6253 DEFINE_RTTI_DATA2(ctype_wchar, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@_W@std@@");
6254 DEFINE_RTTI_DATA2(ctype_short, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@G@std@@");
6255 DEFINE_RTTI_DATA1(codecvt_base, 0, &locale_facet_rtti_base_descriptor, ".?AVcodecvt_base@std@@");
6256 DEFINE_RTTI_DATA2(codecvt_char, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@DDH@std@@");
6257 DEFINE_RTTI_DATA2(codecvt_wchar, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@_WDH@std@@");
6258 DEFINE_RTTI_DATA2(codecvt_short, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@GDH@std@@");
6259 DEFINE_RTTI_DATA1(numpunct_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@D@std@@");
6260 DEFINE_RTTI_DATA1(numpunct_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@_W@std@@");
6261 DEFINE_RTTI_DATA1(numpunct_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@G@std@@");
6262 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@@");
6263 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@@");
6264 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@@");
6265 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@@");
6266
6267 #ifndef __GNUC__
6268 void __asm_dummy_vtables(void) {
6269 #endif
6270     __ASM_VTABLE(locale_facet, "");
6271     __ASM_VTABLE(collate_char,
6272             VTABLE_ADD_FUNC(collate_char_do_compare)
6273             VTABLE_ADD_FUNC(collate_char_do_transform)
6274             VTABLE_ADD_FUNC(collate_char_do_hash));
6275     __ASM_VTABLE(collate_wchar,
6276             VTABLE_ADD_FUNC(collate_wchar_do_compare)
6277             VTABLE_ADD_FUNC(collate_wchar_do_transform)
6278             VTABLE_ADD_FUNC(collate_wchar_do_hash));
6279     __ASM_VTABLE(collate_short,
6280             VTABLE_ADD_FUNC(collate_wchar_do_compare)
6281             VTABLE_ADD_FUNC(collate_wchar_do_transform)
6282             VTABLE_ADD_FUNC(collate_wchar_do_hash));
6283     __ASM_VTABLE(ctype_base, "");
6284     __ASM_VTABLE(ctype_char,
6285             VTABLE_ADD_FUNC(ctype_char_do_tolower)
6286             VTABLE_ADD_FUNC(ctype_char_do_tolower_ch)
6287             VTABLE_ADD_FUNC(ctype_char_do_toupper)
6288             VTABLE_ADD_FUNC(ctype_char_do_toupper_ch)
6289             VTABLE_ADD_FUNC(ctype_char_do_widen)
6290             VTABLE_ADD_FUNC(ctype_char_do_widen_ch)
6291             VTABLE_ADD_FUNC(ctype_char__Do_widen_s)
6292             VTABLE_ADD_FUNC(ctype_char_do_narrow)
6293             VTABLE_ADD_FUNC(ctype_char_do_narrow_ch)
6294             VTABLE_ADD_FUNC(ctype_char__Do_narrow_s));
6295     __ASM_VTABLE(ctype_wchar,
6296             VTABLE_ADD_FUNC(ctype_wchar_do_is)
6297             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
6298             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
6299             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
6300             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
6301             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
6302             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
6303             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
6304             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
6305             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
6306             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
6307             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
6308             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
6309             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
6310     __ASM_VTABLE(ctype_short,
6311             VTABLE_ADD_FUNC(ctype_wchar_do_is)
6312             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
6313             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
6314             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
6315             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
6316             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
6317             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
6318             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
6319             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
6320             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
6321             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
6322             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
6323             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
6324             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
6325     __ASM_VTABLE(codecvt_base,
6326             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
6327             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
6328             VTABLE_ADD_FUNC(codecvt_base_do_encoding));
6329     __ASM_VTABLE(codecvt_char,
6330             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
6331             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
6332             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
6333             VTABLE_ADD_FUNC(codecvt_char_do_in)
6334             VTABLE_ADD_FUNC(codecvt_char_do_out)
6335             VTABLE_ADD_FUNC(codecvt_char_do_unshift)
6336             VTABLE_ADD_FUNC(codecvt_char_do_length));
6337     __ASM_VTABLE(codecvt_wchar,
6338             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
6339             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
6340             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
6341             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
6342             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
6343             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
6344             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
6345     __ASM_VTABLE(codecvt_short,
6346             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
6347             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
6348             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
6349             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
6350             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
6351             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
6352             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
6353     __ASM_VTABLE(numpunct_char,
6354             VTABLE_ADD_FUNC(numpunct_char_do_decimal_point)
6355             VTABLE_ADD_FUNC(numpunct_char_do_thousands_sep)
6356             VTABLE_ADD_FUNC(numpunct_char_do_grouping)
6357             VTABLE_ADD_FUNC(numpunct_char_do_falsename)
6358             VTABLE_ADD_FUNC(numpunct_char_do_truename));
6359     __ASM_VTABLE(numpunct_wchar,
6360             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
6361             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
6362             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
6363             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
6364             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
6365     __ASM_VTABLE(numpunct_short,
6366             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
6367             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
6368             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
6369             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
6370             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
6371     __ASM_VTABLE(num_get_char,
6372             VTABLE_ADD_FUNC(num_get_char_do_get_void)
6373             VTABLE_ADD_FUNC(num_get_char_do_get_double)
6374             VTABLE_ADD_FUNC(num_get_char_do_get_double)
6375             VTABLE_ADD_FUNC(num_get_char_do_get_float)
6376             VTABLE_ADD_FUNC(num_get_char_do_get_uint64)
6377             VTABLE_ADD_FUNC(num_get_char_do_get_int64)
6378             VTABLE_ADD_FUNC(num_get_char_do_get_ulong)
6379             VTABLE_ADD_FUNC(num_get_char_do_get_long)
6380             VTABLE_ADD_FUNC(num_get_char_do_get_uint)
6381             VTABLE_ADD_FUNC(num_get_char_do_get_ushort)
6382             VTABLE_ADD_FUNC(num_get_char_do_get_bool));
6383     __ASM_VTABLE(num_get_short,
6384             VTABLE_ADD_FUNC(num_get_wchar_do_get_void)
6385             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
6386             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
6387             VTABLE_ADD_FUNC(num_get_wchar_do_get_float)
6388             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint64)
6389             VTABLE_ADD_FUNC(num_get_wchar_do_get_int64)
6390             VTABLE_ADD_FUNC(num_get_wchar_do_get_ulong)
6391             VTABLE_ADD_FUNC(num_get_wchar_do_get_long)
6392             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint)
6393             VTABLE_ADD_FUNC(num_get_wchar_do_get_ushort)
6394             VTABLE_ADD_FUNC(num_get_wchar_do_get_bool));
6395     __ASM_VTABLE(num_get_wchar,
6396             VTABLE_ADD_FUNC(num_get_wchar_do_get_void)
6397             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
6398             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
6399             VTABLE_ADD_FUNC(num_get_wchar_do_get_float)
6400             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint64)
6401             VTABLE_ADD_FUNC(num_get_wchar_do_get_int64)
6402             VTABLE_ADD_FUNC(num_get_wchar_do_get_ulong)
6403             VTABLE_ADD_FUNC(num_get_wchar_do_get_long)
6404             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint)
6405             VTABLE_ADD_FUNC(num_get_wchar_do_get_ushort)
6406             VTABLE_ADD_FUNC(num_get_wchar_do_get_bool));
6407     __ASM_VTABLE(num_put_char,
6408             VTABLE_ADD_FUNC(num_put_char_do_put_ptr)
6409             VTABLE_ADD_FUNC(num_put_char_do_put_double)
6410             VTABLE_ADD_FUNC(num_put_char_do_put_double)
6411             VTABLE_ADD_FUNC(num_put_char_do_put_uint64)
6412             VTABLE_ADD_FUNC(num_put_char_do_put_int64)
6413             VTABLE_ADD_FUNC(num_put_char_do_put_ulong)
6414             VTABLE_ADD_FUNC(num_put_char_do_put_long)
6415             VTABLE_ADD_FUNC(num_put_char_do_put_bool));
6416 #ifndef __GNUC__
6417 }
6418 #endif
6419
6420 void free_locale(void)
6421 {
6422     facets_elem *iter, *safe;
6423
6424     if(global_locale) {
6425         locale__Locimp_dtor(global_locale);
6426         locale_dtor(&classic_locale);
6427     }
6428
6429     LIST_FOR_EACH_ENTRY_SAFE(iter, safe, &lazy_facets, facets_elem, entry) {
6430         list_remove(&iter->entry);
6431         if(locale_facet__Decref(iter->fac))
6432             call_locale_facet_vector_dtor(iter->fac, 1);
6433         MSVCRT_operator_delete(iter);
6434     }
6435 }