msvcp90: Fix return value for ctype<wchar_t> do_is(ch).
[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
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winnls.h"
31 #include "wine/unicode.h"
32 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
34
35 char* __cdecl _Getdays(void);
36 char* __cdecl _Getmonths(void);
37 void* __cdecl _Gettnames(void);
38 unsigned int __cdecl ___lc_codepage_func(void);
39 LCID* __cdecl ___lc_handle_func(void);
40
41 typedef int category;
42
43 typedef struct {
44     MSVCP_size_t id;
45 } locale_id;
46
47 typedef struct {
48     const vtable_ptr *vtable;
49     MSVCP_size_t refs;
50 } locale_facet;
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     LCID handle;
80     unsigned page;
81     const short *table;
82     int delfl;
83 } _Ctypevec;
84
85 typedef struct {
86     LCID handle;
87     unsigned page;
88 } _Cvtvec;
89
90 typedef struct {
91     locale_facet facet;
92     _Collvec coll;
93 } collate;
94
95 typedef struct {
96     locale_facet facet;
97 } ctype_base;
98
99 typedef struct {
100     ctype_base base;
101     _Ctypevec ctype;
102 } ctype_char;
103
104 typedef struct {
105     ctype_base base;
106     _Ctypevec ctype;
107     _Cvtvec cvt;
108 } ctype_wchar;
109
110 typedef struct {
111     locale_facet facet;
112     const char *grouping;
113     char dp;
114     char sep;
115     const char *false_name;
116     const char *true_name;
117 } numpunct_char;
118
119 typedef struct {
120     locale_facet facet;
121     const char *grouping;
122     wchar_t dp;
123     wchar_t sep;
124     const wchar_t *false_name;
125     const wchar_t *true_name;
126 } numpunct_wchar;
127
128 typedef struct _num_get_wchar {
129     locale_facet    facet;
130     _Cvtvec         cvt;
131 } num_get_wchar;
132
133 struct _ios_base;
134 typedef struct _istreambuf_iterator_wchar
135 {
136     struct _basic_streambuf_wchar *strbuf;
137     MSVCP_bool      got;
138     wchar_t         val;
139 } istreambuf_iterator_wchar;
140
141 /* ?_Id_cnt@id@locale@std@@0HA */
142 int locale_id__Id_cnt = 0;
143
144 /* ?_Clocptr@_Locimp@locale@std@@0PAV123@A */
145 /* ?_Clocptr@_Locimp@locale@std@@0PEAV123@EA */
146 locale__Locimp *locale__Locimp__Clocptr = NULL;
147
148 /* ??1facet@locale@std@@UAE@XZ */
149 /* ??1facet@locale@std@@UEAA@XZ */
150 DEFINE_THISCALL_WRAPPER(locale_facet_dtor, 4)
151 void __thiscall locale_facet_dtor(locale_facet *this)
152 {
153     TRACE("(%p)\n", this);
154 }
155
156 DEFINE_THISCALL_WRAPPER(MSVCP_locale_facet_vector_dtor, 8)
157 #define call_locale_facet_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0, \
158         locale_facet*, (locale_facet*, unsigned int), (this, flags))
159 locale_facet* __thiscall MSVCP_locale_facet_vector_dtor(locale_facet *this, unsigned int flags)
160 {
161     TRACE("(%p %x)\n", this, flags);
162     if(flags & 2) {
163         /* we have an array, with the number of elements stored before the first object */
164         int i, *ptr = (int *)this-1;
165
166         for(i=*ptr-1; i>=0; i--)
167             locale_facet_dtor(this+i);
168         MSVCRT_operator_delete(ptr);
169     } else {
170         locale_facet_dtor(this);
171         if(flags & 1)
172             MSVCRT_operator_delete(this);
173     }
174
175     return this;
176 }
177
178 const vtable_ptr MSVCP_locale_facet_vtable[] = {
179     (vtable_ptr)THISCALL_NAME(MSVCP_locale_facet_vector_dtor)
180 };
181
182 /* ??0id@locale@std@@QAE@I@Z */
183 /* ??0id@locale@std@@QEAA@_K@Z */
184 DEFINE_THISCALL_WRAPPER(locale_id_ctor_id, 8)
185 locale_id* __thiscall locale_id_ctor_id(locale_id *this, MSVCP_size_t id)
186 {
187     TRACE("(%p %lu)\n", this, id);
188
189     this->id = id;
190     return this;
191 }
192
193 /* ??_Fid@locale@std@@QAEXXZ */
194 /* ??_Fid@locale@std@@QEAAXXZ */
195 DEFINE_THISCALL_WRAPPER(locale_id_ctor, 4)
196 locale_id* __thiscall locale_id_ctor(locale_id *this)
197 {
198     TRACE("(%p)\n", this);
199
200     this->id = 0;
201     return this;
202 }
203
204 /* ??Bid@locale@std@@QAEIXZ */
205 /* ??Bid@locale@std@@QEAA_KXZ */
206 DEFINE_THISCALL_WRAPPER(locale_id_operator_size_t, 4)
207 MSVCP_size_t __thiscall locale_id_operator_size_t(locale_id *this)
208 {
209     _Lockit lock;
210
211     TRACE("(%p)\n", this);
212
213     if(!this->id) {
214         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
215         this->id = ++locale_id__Id_cnt;
216         _Lockit_dtor(&lock);
217     }
218
219     return this->id;
220 }
221
222 /* ?_Id_cnt_func@id@locale@std@@CAAAHXZ */
223 /* ?_Id_cnt_func@id@locale@std@@CAAEAHXZ */
224 int* __cdecl locale_id__Id_cnt_func(void)
225 {
226     TRACE("\n");
227     return &locale_id__Id_cnt;
228 }
229
230 /* ??_Ffacet@locale@std@@QAEXXZ */
231 /* ??_Ffacet@locale@std@@QEAAXXZ */
232 DEFINE_THISCALL_WRAPPER(locale_facet_ctor, 4)
233 locale_facet* __thiscall locale_facet_ctor(locale_facet *this)
234 {
235     TRACE("(%p)\n", this);
236     this->vtable = MSVCP_locale_facet_vtable;
237     this->refs = 0;
238     return this;
239 }
240
241 /* ??0facet@locale@std@@IAE@I@Z */
242 /* ??0facet@locale@std@@IEAA@_K@Z */
243 DEFINE_THISCALL_WRAPPER(locale_facet_ctor_refs, 8)
244 locale_facet* __thiscall locale_facet_ctor_refs(locale_facet *this, MSVCP_size_t refs)
245 {
246     TRACE("(%p %lu)\n", this, refs);
247     this->vtable = MSVCP_locale_facet_vtable;
248     this->refs = refs;
249     return this;
250 }
251
252 /* ?_Incref@facet@locale@std@@QAEXXZ */
253 /* ?_Incref@facet@locale@std@@QEAAXXZ */
254 DEFINE_THISCALL_WRAPPER(locale_facet__Incref, 4)
255 void __thiscall locale_facet__Incref(locale_facet *this)
256 {
257     _Lockit lock;
258
259     TRACE("(%p)\n", this);
260
261     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
262     this->refs++;
263     _Lockit_dtor(&lock);
264 }
265
266 /* ?_Decref@facet@locale@std@@QAEPAV123@XZ */
267 /* ?_Decref@facet@locale@std@@QEAAPEAV123@XZ */
268 DEFINE_THISCALL_WRAPPER(locale_facet__Decref, 4)
269 locale_facet* __thiscall locale_facet__Decref(locale_facet *this)
270 {
271     _Lockit lock;
272     locale_facet *ret;
273
274     TRACE("(%p)\n", this);
275
276     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
277     if(this->refs)
278         this->refs--;
279
280     ret = this->refs ? NULL : this;
281     _Lockit_dtor(&lock);
282
283     return ret;
284 }
285
286 /* ?_Getcat@facet@locale@std@@SAIPAPBV123@PBV23@@Z */
287 /* ?_Getcat@facet@locale@std@@SA_KPEAPEBV123@PEBV23@@Z */
288 MSVCP_size_t __cdecl locale_facet__Getcat(const locale_facet **facet, const locale *loc)
289 {
290     TRACE("(%p %p)\n", facet, loc);
291     return -1;
292 }
293
294 /* ??0_Timevec@std@@QAE@ABV01@@Z */
295 /* ??0_Timevec@std@@QEAA@AEBV01@@Z */
296 /* This copy constructor modifies copied object */
297 DEFINE_THISCALL_WRAPPER(_Timevec_copy_ctor, 8)
298 _Timevec* __thiscall _Timevec_copy_ctor(_Timevec *this, _Timevec *copy)
299 {
300     TRACE("(%p %p)\n", this, copy);
301     this->timeptr = copy->timeptr;
302     copy->timeptr = NULL;
303     return this;
304 }
305
306 /* ??0_Timevec@std@@QAE@PAX@Z */
307 /* ??0_Timevec@std@@QEAA@PEAX@Z */
308 DEFINE_THISCALL_WRAPPER(_Timevec_ctor_timeptr, 8)
309 _Timevec* __thiscall _Timevec_ctor_timeptr(_Timevec *this, void *timeptr)
310 {
311     TRACE("(%p %p)\n", this, timeptr);
312     this->timeptr = timeptr;
313     return this;
314 }
315
316 /* ??_F_Timevec@std@@QAEXXZ */
317 /* ??_F_Timevec@std@@QEAAXXZ */
318 DEFINE_THISCALL_WRAPPER(_Timevec_ctor, 4)
319 _Timevec* __thiscall _Timevec_ctor(_Timevec *this)
320 {
321     TRACE("(%p)\n", this);
322     this->timeptr = NULL;
323     return this;
324 }
325
326 /* ??1_Timevec@std@@QAE@XZ */
327 /* ??1_Timevec@std@@QEAA@XZ */
328 DEFINE_THISCALL_WRAPPER(_Timevec_dtor, 4)
329 void __thiscall _Timevec_dtor(_Timevec *this)
330 {
331     TRACE("(%p)\n", this);
332     free(this->timeptr);
333 }
334
335 /* ??4_Timevec@std@@QAEAAV01@ABV01@@Z */
336 /* ??4_Timevec@std@@QEAAAEAV01@AEBV01@@Z */
337 DEFINE_THISCALL_WRAPPER(_Timevec_op_assign, 8)
338 _Timevec* __thiscall _Timevec_op_assign(_Timevec *this, _Timevec *right)
339 {
340     TRACE("(%p %p)\n", this, right);
341     this->timeptr = right->timeptr;
342     right->timeptr = NULL;
343     return this;
344 }
345
346 /* ?_Getptr@_Timevec@std@@QBEPAXXZ */
347 /* ?_Getptr@_Timevec@std@@QEBAPEAXXZ */
348 DEFINE_THISCALL_WRAPPER(_Timevec__Getptr, 4)
349 void* __thiscall _Timevec__Getptr(_Timevec *this)
350 {
351     TRACE("(%p)\n", this);
352     return this->timeptr;
353 }
354
355 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@HPBD@Z */
356 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@HPEBD@Z */
357 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cat_cstr(_Locinfo *locinfo, int category, const char *locstr)
358 {
359     const char *locale = NULL;
360
361     /* This function is probably modifying more global objects */
362     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
363
364     if(!locstr)
365         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
366
367     _Lockit_ctor_locktype(&locinfo->lock, _LOCK_LOCALE);
368     MSVCP_basic_string_char_ctor_cstr(&locinfo->days, "");
369     MSVCP_basic_string_char_ctor_cstr(&locinfo->months, "");
370     MSVCP_basic_string_char_ctor_cstr(&locinfo->oldlocname, setlocale(LC_ALL, NULL));
371
372     if(category)
373         locale = setlocale(LC_ALL, locstr);
374     else
375         locale = setlocale(LC_ALL, NULL);
376
377     if(locale)
378         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
379     else
380         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
381
382     return locinfo;
383 }
384
385 /* ??0_Locinfo@std@@QAE@HPBD@Z */
386 /* ??0_Locinfo@std@@QEAA@HPEBD@Z */
387 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cat_cstr, 12)
388 _Locinfo* __thiscall _Locinfo_ctor_cat_cstr(_Locinfo *this, int category, const char *locstr)
389 {
390     return _Locinfo__Locinfo_ctor_cat_cstr(this, category, locstr);
391 }
392
393 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
394 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z */
395 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_bstr(_Locinfo *locinfo, const basic_string_char *locstr)
396 {
397     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
398 }
399
400 /* ??0_Locinfo@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
401 /* ??0_Locinfo@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
402 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_bstr, 8)
403 _Locinfo* __thiscall _Locinfo_ctor_bstr(_Locinfo *this, const basic_string_char *locstr)
404 {
405     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, MSVCP_basic_string_char_c_str(locstr));
406 }
407
408 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@PBD@Z */
409 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@PEBD@Z */
410 _Locinfo* __cdecl _Locinfo__Locinfo_ctor_cstr(_Locinfo *locinfo, const char *locstr)
411 {
412     return _Locinfo__Locinfo_ctor_cat_cstr(locinfo, 1/*FIXME*/, locstr);
413 }
414
415 /* ??0_Locinfo@std@@QAE@PBD@Z */
416 /* ??0_Locinfo@std@@QEAA@PEBD@Z */
417 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cstr, 8)
418 _Locinfo* __thiscall _Locinfo_ctor_cstr(_Locinfo *this, const char *locstr)
419 {
420     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, locstr);
421 }
422
423 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z */
424 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPEAV12@@Z */
425 void __cdecl _Locinfo__Locinfo_dtor(_Locinfo *locinfo)
426 {
427     TRACE("(%p)\n", locinfo);
428
429     setlocale(LC_ALL, MSVCP_basic_string_char_c_str(&locinfo->oldlocname));
430     MSVCP_basic_string_char_dtor(&locinfo->days);
431     MSVCP_basic_string_char_dtor(&locinfo->months);
432     MSVCP_basic_string_char_dtor(&locinfo->oldlocname);
433     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
434     _Lockit_dtor(&locinfo->lock);
435 }
436
437 /* ??_F_Locinfo@std@@QAEXXZ */
438 /* ??_F_Locinfo@std@@QEAAXXZ */
439 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor, 4)
440 _Locinfo* __thiscall _Locinfo_ctor(_Locinfo *this)
441 {
442     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, "C");
443 }
444
445 /* ??1_Locinfo@std@@QAE@XZ */
446 /* ??1_Locinfo@std@@QEAA@XZ */
447 DEFINE_THISCALL_WRAPPER(_Locinfo_dtor, 4)
448 void __thiscall _Locinfo_dtor(_Locinfo *this)
449 {
450     _Locinfo__Locinfo_dtor(this);
451 }
452
453 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAAV12@PAV12@HPBD@Z */
454 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAEAV12@PEAV12@HPEBD@Z */
455 _Locinfo* __cdecl _Locinfo__Locinfo_Addcats(_Locinfo *locinfo, int category, const char *locstr)
456 {
457     const char *locale = NULL;
458
459     /* This function is probably modifying more global objects */
460     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
461     if(!locstr)
462         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
463
464     MSVCP_basic_string_char_dtor(&locinfo->newlocname);
465
466     if(category)
467         locale = setlocale(LC_ALL, locstr);
468     else
469         locale = setlocale(LC_ALL, NULL);
470
471     if(locale)
472         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
473     else
474         MSVCP_basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
475
476     return locinfo;
477 }
478
479 /* ?_Addcats@_Locinfo@std@@QAEAAV12@HPBD@Z */
480 /* ?_Addcats@_Locinfo@std@@QEAAAEAV12@HPEBD@Z */
481 DEFINE_THISCALL_WRAPPER(_Locinfo__Addcats, 12)
482 _Locinfo* __thiscall _Locinfo__Addcats(_Locinfo *this, int category, const char *locstr)
483 {
484     return _Locinfo__Locinfo_Addcats(this, category, locstr);
485 }
486
487 /* _Getcoll */
488 _Collvec __cdecl _Getcoll(void)
489 {
490     _Collvec ret;
491     _locale_t locale = _get_current_locale();
492
493     TRACE("\n");
494
495     ret.page = locale->locinfo->lc_collate_cp;
496     ret.handle = locale->locinfo->lc_handle[LC_COLLATE];
497     _free_locale(locale);
498     return ret;
499 }
500
501 /* ?_Getcoll@_Locinfo@std@@QBE?AU_Collvec@@XZ */
502 /* ?_Getcoll@_Locinfo@std@@QEBA?AU_Collvec@@XZ */
503 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcoll, 8)
504 _Collvec* __thiscall _Locinfo__Getcoll(const _Locinfo *this, _Collvec *ret)
505 {
506     *ret = _Getcoll();
507     return ret;
508 }
509
510 /* _Getctype */
511 _Ctypevec __cdecl _Getctype(void)
512 {
513     _Ctypevec ret;
514     _locale_t locale = _get_current_locale();
515     short *table;
516
517     TRACE("\n");
518
519     ret.page = locale->locinfo->lc_codepage;
520     ret.handle = locale->locinfo->lc_handle[LC_COLLATE];
521     ret.delfl = TRUE;
522     table = malloc(sizeof(short[256]));
523     if(!table) {
524         _free_locale(locale);
525         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
526     }
527     memcpy(table, locale->locinfo->pctype, sizeof(short[256]));
528     ret.table = table;
529     _free_locale(locale);
530     return ret;
531 }
532
533 /* ?_Getctype@_Locinfo@std@@QBE?AU_Ctypevec@@XZ */
534 /* ?_Getctype@_Locinfo@std@@QEBA?AU_Ctypevec@@XZ */
535 DEFINE_THISCALL_WRAPPER(_Locinfo__Getctype, 8)
536 _Ctypevec* __thiscall _Locinfo__Getctype(const _Locinfo *this, _Ctypevec *ret)
537 {
538     *ret = _Getctype();
539     return ret;
540 }
541
542 /* _Getcvt */
543 _Cvtvec __cdecl _Getcvt(void)
544 {
545     _Cvtvec ret;
546     _locale_t locale = _get_current_locale();
547
548     TRACE("\n");
549
550     ret.page = locale->locinfo->lc_codepage;
551     ret.handle = locale->locinfo->lc_handle[LC_CTYPE];
552     _free_locale(locale);
553     return ret;
554 }
555
556 /* ?_Getcvt@_Locinfo@std@@QBE?AU_Cvtvec@@XZ */
557 /* ?_Getcvt@_Locinfo@std@@QEBA?AU_Cvtvec@@XZ */
558 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcvt, 8)
559 _Cvtvec* __thiscall _Locinfo__Getcvt(const _Locinfo *this, _Cvtvec *ret)
560 {
561     *ret = _Getcvt();
562     return ret;
563 }
564
565 /* ?_Getdateorder@_Locinfo@std@@QBEHXZ */
566 /* ?_Getdateorder@_Locinfo@std@@QEBAHXZ */
567 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdateorder, 4)
568 int __thiscall _Locinfo__Getdateorder(const _Locinfo *this)
569 {
570     FIXME("(%p) stub\n", this);
571     return 0;
572 }
573
574 /* ?_Getdays@_Locinfo@std@@QBEPBDXZ */
575 /* ?_Getdays@_Locinfo@std@@QEBAPEBDXZ */
576 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdays, 4)
577 const char* __thiscall _Locinfo__Getdays(_Locinfo *this)
578 {
579     char *days = _Getdays();
580
581     TRACE("(%p)\n", this);
582
583     if(days) {
584         MSVCP_basic_string_char_dtor(&this->days);
585         MSVCP_basic_string_char_ctor_cstr(&this->days, days);
586         free(days);
587     }
588
589     return this->days.size ? MSVCP_basic_string_char_c_str(&this->days) :
590         ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
591 }
592
593 /* ?_Getmonths@_Locinfo@std@@QBEPBDXZ */
594 /* ?_Getmonths@_Locinfo@std@@QEBAPEBDXZ */
595 DEFINE_THISCALL_WRAPPER(_Locinfo__Getmonths, 4)
596 const char* __thiscall _Locinfo__Getmonths(_Locinfo *this)
597 {
598     char *months = _Getmonths();
599
600     TRACE("(%p)\n", this);
601
602     if(months) {
603         MSVCP_basic_string_char_dtor(&this->months);
604         MSVCP_basic_string_char_ctor_cstr(&this->months, months);
605         free(months);
606     }
607
608     return this->months.size ? MSVCP_basic_string_char_c_str(&this->months) :
609         ":Jan:January:Feb:February:Mar:March:Apr:April:May:May:Jun:June:Jul:July"
610         ":Aug:August:Sep:September:Oct:October:Nov:November:Dec:December";
611 }
612
613 /* ?_Getfalse@_Locinfo@std@@QBEPBDXZ */
614 /* ?_Getfalse@_Locinfo@std@@QEBAPEBDXZ */
615 DEFINE_THISCALL_WRAPPER(_Locinfo__Getfalse, 4)
616 const char* __thiscall _Locinfo__Getfalse(const _Locinfo *this)
617 {
618     TRACE("(%p)\n", this);
619     return "false";
620 }
621
622 /* ?_Gettrue@_Locinfo@std@@QBEPBDXZ */
623 /* ?_Gettrue@_Locinfo@std@@QEBAPEBDXZ */
624 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettrue, 4)
625 const char* __thiscall _Locinfo__Gettrue(const _Locinfo *this)
626 {
627     TRACE("(%p)\n", this);
628     return "true";
629 }
630
631 /* ?_Getlconv@_Locinfo@std@@QBEPBUlconv@@XZ */
632 /* ?_Getlconv@_Locinfo@std@@QEBAPEBUlconv@@XZ */
633 DEFINE_THISCALL_WRAPPER(_Locinfo__Getlconv, 4)
634 const struct lconv* __thiscall _Locinfo__Getlconv(const _Locinfo *this)
635 {
636     TRACE("(%p)\n", this);
637     return localeconv();
638 }
639
640 /* ?_Getname@_Locinfo@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
641 /* ?_Getname@_Locinfo@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
642 DEFINE_THISCALL_WRAPPER(_Locinfo__Getname, 8)
643 basic_string_char* __thiscall _Locinfo__Getname(const _Locinfo *this, basic_string_char *ret)
644 {
645     TRACE("(%p)\n", this);
646
647     MSVCP_basic_string_char_copy_ctor(ret, &this->newlocname);
648     return ret;
649 }
650
651 /* ?_Gettnames@_Locinfo@std@@QBE?AV_Timevec@2@XZ */
652 /* ?_Gettnames@_Locinfo@std@@QEBA?AV_Timevec@2@XZ */
653 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettnames, 8)
654 _Timevec*__thiscall _Locinfo__Gettnames(const _Locinfo *this, _Timevec *ret)
655 {
656     TRACE("(%p)\n", this);
657
658     _Timevec_ctor_timeptr(ret, _Gettnames());
659     return ret;
660 }
661
662 static const type_info locale_facet_type_info = {
663     MSVCP_locale_facet_vtable,
664     NULL,
665     ".?AVfacet@locale@std@@"
666 };
667
668 /* ?id@?$collate@D@std@@2V0locale@2@A */
669 locale_id collate_char_id = {0};
670
671 /* ??_7?$collate@D@std@@6B@ */
672 extern const vtable_ptr MSVCP_collate_char_vtable;
673
674 /* ?_Init@?$collate@D@std@@IAEXABV_Locinfo@2@@Z */
675 /* ?_Init@?$collate@D@std@@IEAAXAEBV_Locinfo@2@@Z */
676 DEFINE_THISCALL_WRAPPER(collate_char__Init, 8)
677 void __thiscall collate_char__Init(collate *this, const _Locinfo *locinfo)
678 {
679     TRACE("(%p %p)\n", this, locinfo);
680     _Locinfo__Getcoll(locinfo, &this->coll);
681 }
682
683 /* ??0?$collate@D@std@@IAE@PBDI@Z */
684 /* ??0?$collate@D@std@@IEAA@PEBD_K@Z */
685 DEFINE_THISCALL_WRAPPER(collate_char_ctor_name, 12)
686 collate* __thiscall collate_char_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
687 {
688     _Locinfo locinfo;
689
690     TRACE("(%p %s %lu)\n", this, name, refs);
691
692     locale_facet_ctor_refs(&this->facet, refs);
693     this->facet.vtable = &MSVCP_collate_char_vtable;
694
695     _Locinfo_ctor_cstr(&locinfo, name);
696     collate_char__Init(this, &locinfo);
697     _Locinfo_dtor(&locinfo);
698     return this;
699 }
700
701 /* ??0?$collate@D@std@@QAE@ABV_Locinfo@1@I@Z */
702 /* ??0?$collate@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
703 DEFINE_THISCALL_WRAPPER(collate_char_ctor_locinfo, 12)
704 collate* __thiscall collate_char_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
705 {
706     TRACE("(%p %p %lu)\n", this, locinfo, refs);
707
708     locale_facet_ctor_refs(&this->facet, refs);
709     this->facet.vtable = &MSVCP_collate_char_vtable;
710     collate_char__Init(this, locinfo);
711     return this;
712 }
713
714 /* ??0?$collate@D@std@@QAE@I@Z */
715 /* ??0?$collate@D@std@@QEAA@_K@Z */
716 DEFINE_THISCALL_WRAPPER(collate_char_ctor_refs, 8)
717 collate* __thiscall collate_char_ctor_refs(collate *this, MSVCP_size_t refs)
718 {
719     return collate_char_ctor_name(this, "C", refs);
720 }
721
722 /* ??1?$collate@D@std@@MAE@XZ */
723 /* ??1?$collate@D@std@@MEAA@XZ */
724 DEFINE_THISCALL_WRAPPER(collate_char_dtor, 4)
725 void __thiscall collate_char_dtor(collate *this)
726 {
727     TRACE("(%p)\n", this);
728 }
729
730 DEFINE_THISCALL_WRAPPER(MSVCP_collate_char_vector_dtor, 8)
731 collate* __thiscall MSVCP_collate_char_vector_dtor(collate *this, unsigned int flags)
732 {
733     TRACE("(%p %x)\n", this, flags);
734     if(flags & 2) {
735         /* we have an array, with the number of elements stored before the first object */
736         int i, *ptr = (int *)this-1;
737
738         for(i=*ptr-1; i>=0; i--)
739             collate_char_dtor(this+i);
740         MSVCRT_operator_delete(ptr);
741     } else {
742         collate_char_dtor(this);
743         if(flags & 1)
744             MSVCRT_operator_delete(this);
745     }
746
747     return this;
748 }
749
750 /* ??_F?$collate@D@std@@QAEXXZ */
751 /* ??_F?$collate@D@std@@QEAAXXZ */
752 DEFINE_THISCALL_WRAPPER(collate_char_ctor, 4)
753 collate* __thiscall collate_char_ctor(collate *this)
754 {
755     return collate_char_ctor_name(this, "C", 0);
756 }
757
758 /* ?_Getcat@?$collate@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
759 /* ?_Getcat@?$collate@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
760 MSVCP_size_t __cdecl collate_char__Getcat(const locale_facet **facet, const locale *loc)
761 {
762     TRACE("(%p %p)\n", facet, loc);
763
764     if(facet && !*facet) {
765         *facet = MSVCRT_operator_new(sizeof(collate));
766         if(!*facet) {
767             ERR("Out of memory\n");
768             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
769             return 0;
770         }
771         collate_char_ctor_name((collate*)*facet,
772                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
773     }
774
775     return LC_COLLATE;
776 }
777
778 /* _Strcoll */
779 int __cdecl _Strcoll(const char *first1, const char *last1, const char *first2,
780         const char *last2, const _Collvec *coll)
781 {
782     LCID lcid;
783
784     TRACE("(%s %s)\n", debugstr_an(first1, last1-first1), debugstr_an(first2, last2-first2));
785
786     if(coll)
787         lcid = coll->handle;
788     else
789         lcid = ___lc_handle_func()[LC_COLLATE];
790     return CompareStringA(lcid, 0, first1, last1-first1, first2, last2-first2)-2;
791 }
792
793 /* ?do_compare@?$collate@D@std@@MBEHPBD000@Z */
794 /* ?do_compare@?$collate@D@std@@MEBAHPEBD000@Z */
795 DEFINE_THISCALL_WRAPPER(collate_char_do_compare, 20)
796 #define call_collate_char_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
797         (const collate*, const char*, const char*, const char*, const char*), \
798         (this, first1, last1, first2, last2))
799 int __thiscall collate_char_do_compare(const collate *this, const char *first1,
800         const char *last1, const char *first2, const char *last2)
801 {
802     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
803     return _Strcoll(first1, last1, first2, last2, &this->coll);
804 }
805
806 /* ?compare@?$collate@D@std@@QBEHPBD000@Z */
807 /* ?compare@?$collate@D@std@@QEBAHPEBD000@Z */
808 DEFINE_THISCALL_WRAPPER(collate_char_compare, 20)
809 int __thiscall collate_char_compare(const collate *this, const char *first1,
810         const char *last1, const char *first2, const char *last2)
811 {
812     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
813     return call_collate_char_do_compare(this, first1, last1, first2, last2);
814 }
815
816 /* ?do_hash@?$collate@D@std@@MBEJPBD0@Z */
817 /* ?do_hash@?$collate@D@std@@MEBAJPEBD0@Z */
818 DEFINE_THISCALL_WRAPPER(collate_char_do_hash, 12)
819 #define call_collate_char_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
820         (const collate*, const char*, const char*), (this, first, last))
821 LONG __thiscall collate_char_do_hash(const collate *this,
822         const char *first, const char *last)
823 {
824     ULONG ret = 0;
825
826     TRACE("(%p %p %p)\n", this, first, last);
827
828     for(; first<last; first++)
829         ret = (ret<<8 | ret>>24) + *first;
830     return ret;
831 }
832
833 /* ?hash@?$collate@D@std@@QBEJPBD0@Z */
834 /* ?hash@?$collate@D@std@@QEBAJPEBD0@Z */
835 DEFINE_THISCALL_WRAPPER(collate_char_hash, 12)
836 LONG __thiscall collate_char_hash(const collate *this,
837         const char *first, const char *last)
838 {
839     TRACE("(%p %p %p)\n", this, first, last);
840     return call_collate_char_do_hash(this, first, last);
841 }
842
843 /* ?do_transform@?$collate@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
844 /* ?do_transform@?$collate@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
845 DEFINE_THISCALL_WRAPPER(collate_char_do_transform, 16)
846 basic_string_char* __thiscall collate_char_do_transform(const collate *this,
847         basic_string_char *ret, const char *first, const char *last)
848 {
849     FIXME("(%p %p %p) stub\n", this, first, last);
850     return ret;
851 }
852
853 /* ?transform@?$collate@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
854 /* ?transform@?$collate@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
855 DEFINE_THISCALL_WRAPPER(collate_char_transform, 16)
856 basic_string_char* __thiscall collate_char_transform(const collate *this,
857         basic_string_char *ret, const char *first, const char *last)
858 {
859     FIXME("(%p %p %p) stub\n", this, first, last);
860     return ret;
861 }
862
863 /* ?id@?$collate@_W@std@@2V0locale@2@A */
864 locale_id collate_wchar_id = {0};
865 /* ?id@?$collate@G@std@@2V0locale@2@A */
866 locale_id collate_short_id = {0};
867
868 /* ??_7?$collate@_W@std@@6B@ */
869 extern const vtable_ptr MSVCP_collate_wchar_vtable;
870 /* ??_7?$collate@G@std@@6B@ */
871 extern const vtable_ptr MSVCP_collate_short_vtable;
872
873 /* ?_Init@?$collate@_W@std@@IAEXABV_Locinfo@2@@Z */
874 /* ?_Init@?$collate@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
875 /* ?_Init@?$collate@G@std@@IAEXABV_Locinfo@2@@Z */
876 /* ?_Init@?$collate@G@std@@IEAAXAEBV_Locinfo@2@@Z */
877 DEFINE_THISCALL_WRAPPER(collate_wchar__Init, 8)
878 void __thiscall collate_wchar__Init(collate *this, const _Locinfo *locinfo)
879 {
880     TRACE("(%p %p)\n", this, locinfo);
881     _Locinfo__Getcoll(locinfo, &this->coll);
882 }
883
884 /* ??0?$collate@_W@std@@IAE@PBDI@Z */
885 /* ??0?$collate@_W@std@@IEAA@PEBD_K@Z */
886 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_name, 12)
887 collate* __thiscall collate_wchar_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
888 {
889     _Locinfo locinfo;
890
891     TRACE("(%p %s %lu)\n", this, name, refs);
892
893     locale_facet_ctor_refs(&this->facet, refs);
894     this->facet.vtable = &MSVCP_collate_wchar_vtable;
895
896     _Locinfo_ctor_cstr(&locinfo, name);
897     collate_wchar__Init(this, &locinfo);
898     _Locinfo_dtor(&locinfo);
899     return this;
900 }
901
902 /* ??0?$collate@G@std@@IAE@PBDI@Z */
903 /* ??0?$collate@G@std@@IEAA@PEBD_K@Z */
904 DEFINE_THISCALL_WRAPPER(collate_short_ctor_name, 12)
905 collate* __thiscall collate_short_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
906 {
907     collate *ret = collate_wchar_ctor_name(this, name, refs);
908     ret->facet.vtable = &MSVCP_collate_short_vtable;
909     return ret;
910 }
911
912 /* ??0?$collate@_W@std@@QAE@ABV_Locinfo@1@I@Z */
913 /* ??0?$collate@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
914 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_locinfo, 12)
915 collate* __thiscall collate_wchar_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
916 {
917     TRACE("(%p %p %lu)\n", this, locinfo, refs);
918
919     locale_facet_ctor_refs(&this->facet, refs);
920     this->facet.vtable = &MSVCP_collate_wchar_vtable;
921     collate_wchar__Init(this, locinfo);
922     return this;
923 }
924
925 /* ??0?$collate@G@std@@QAE@ABV_Locinfo@1@I@Z */
926 /* ??0?$collate@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
927 DEFINE_THISCALL_WRAPPER(collate_short_ctor_locinfo, 12)
928 collate* __thiscall collate_short_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
929 {
930     collate *ret = collate_wchar_ctor_locinfo(this, locinfo, refs);
931     ret->facet.vtable = &MSVCP_collate_short_vtable;
932     return ret;
933 }
934
935 /* ??0?$collate@_W@std@@QAE@I@Z */
936 /* ??0?$collate@_W@std@@QEAA@_K@Z */
937 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor_refs, 8)
938 collate* __thiscall collate_wchar_ctor_refs(collate *this, MSVCP_size_t refs)
939 {
940     return collate_wchar_ctor_name(this, "C", refs);
941 }
942
943 /* ??0?$collate@G@std@@QAE@I@Z */
944 /* ??0?$collate@G@std@@QEAA@_K@Z */
945 DEFINE_THISCALL_WRAPPER(collate_short_ctor_refs, 8)
946 collate* __thiscall collate_short_ctor_refs(collate *this, MSVCP_size_t refs)
947 {
948     collate *ret = collate_wchar_ctor_refs(this, refs);
949     ret->facet.vtable = &MSVCP_collate_short_vtable;
950     return ret;
951 }
952
953 /* ??1?$collate@_W@std@@MAE@XZ */
954 /* ??1?$collate@_W@std@@MEAA@XZ */
955 /* ??1?$collate@G@std@@MAE@XZ */
956 /* ??1?$collate@G@std@@MEAA@XZ */
957 DEFINE_THISCALL_WRAPPER(collate_wchar_dtor, 4)
958 void __thiscall collate_wchar_dtor(collate *this)
959 {
960     TRACE("(%p)\n", this);
961 }
962
963 DEFINE_THISCALL_WRAPPER(MSVCP_collate_wchar_vector_dtor, 8)
964 collate* __thiscall MSVCP_collate_wchar_vector_dtor(collate *this, unsigned int flags)
965 {
966     TRACE("(%p %x)\n", this, flags);
967     if(flags & 2) {
968         /* we have an array, with the number of elements stored before the first object */
969         int i, *ptr = (int *)this-1;
970
971         for(i=*ptr-1; i>=0; i--)
972             collate_wchar_dtor(this+i);
973         MSVCRT_operator_delete(ptr);
974     } else {
975         collate_wchar_dtor(this);
976         if(flags & 1)
977             MSVCRT_operator_delete(this);
978     }
979
980     return this;
981 }
982
983 DEFINE_THISCALL_WRAPPER(MSVCP_collate_short_vector_dtor, 8)
984 collate* __thiscall MSVCP_collate_short_vector_dtor(collate *this, unsigned int flags)
985 {
986     return MSVCP_collate_wchar_vector_dtor(this, flags);
987 }
988
989 /* ??_F?$collate@_W@std@@QAEXXZ */
990 /* ??_F?$collate@_W@std@@QEAAXXZ */
991 DEFINE_THISCALL_WRAPPER(collate_wchar_ctor, 4)
992 collate* __thiscall collate_wchar_ctor(collate *this)
993 {
994     return collate_wchar_ctor_name(this, "C", 0);
995 }
996
997 /* ??_F?$collate@G@std@@QAEXXZ */
998 /* ??_F?$collate@G@std@@QEAAXXZ */
999 DEFINE_THISCALL_WRAPPER(collate_short_ctor, 4)
1000 collate* __thiscall collate_short_ctor(collate *this)
1001 {
1002     collate *ret = collate_wchar_ctor(this);
1003     ret->facet.vtable = &MSVCP_collate_short_vtable;
1004     return ret;
1005 }
1006
1007 /* ?_Getcat@?$collate@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1008 /* ?_Getcat@?$collate@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1009 MSVCP_size_t __cdecl collate_wchar__Getcat(const locale_facet **facet, const locale *loc)
1010 {
1011     TRACE("(%p %p)\n", facet, loc);
1012
1013     if(facet && !*facet) {
1014         *facet = MSVCRT_operator_new(sizeof(collate));
1015         if(!*facet) {
1016             ERR("Out of memory\n");
1017             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1018             return 0;
1019         }
1020         collate_wchar_ctor_name((collate*)*facet,
1021                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0);
1022     }
1023
1024     return LC_COLLATE;
1025 }
1026
1027 /* ?_Getcat@?$collate@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1028 /* ?_Getcat@?$collate@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1029 MSVCP_size_t __cdecl collate_short__Getcat(const locale_facet **facet, const locale *loc)
1030 {
1031     if(facet && !*facet) {
1032         collate_wchar__Getcat(facet, loc);
1033         (*(locale_facet**)facet)->vtable = &MSVCP_collate_short_vtable;
1034     }
1035
1036     return LC_COLLATE;
1037 }
1038
1039 /* _Wcscoll */
1040 int __cdecl _Wcscoll(const wchar_t *first1, const wchar_t *last1, const wchar_t *first2,
1041         const wchar_t *last2, const _Collvec *coll)
1042 {
1043     LCID lcid;
1044
1045     TRACE("(%s %s)\n", debugstr_wn(first1, last1-first1), debugstr_wn(first2, last2-first2));
1046
1047     if(coll)
1048         lcid = coll->handle;
1049     else
1050         lcid = ___lc_handle_func()[LC_COLLATE];
1051     return CompareStringW(lcid, 0, first1, last1-first1, first2, last2-first2)-2;
1052 }
1053
1054 /* ?do_compare@?$collate@_W@std@@MBEHPB_W000@Z */
1055 /* ?do_compare@?$collate@_W@std@@MEBAHPEB_W000@Z */
1056 /* ?do_compare@?$collate@G@std@@MBEHPBG000@Z */
1057 /* ?do_compare@?$collate@G@std@@MEBAHPEBG000@Z */
1058 DEFINE_THISCALL_WRAPPER(collate_wchar_do_compare, 20)
1059 #define call_collate_wchar_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
1060         (const collate*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*), \
1061         (this, first1, last1, first2, last2))
1062 int __thiscall collate_wchar_do_compare(const collate *this, const wchar_t *first1,
1063         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1064 {
1065     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1066     return _Wcscoll(first1, last1, first2, last2, &this->coll);
1067 }
1068
1069 /* ?compare@?$collate@_W@std@@QBEHPB_W000@Z */
1070 /* ?compare@?$collate@_W@std@@QEBAHPEB_W000@Z */
1071 /* ?compare@?$collate@G@std@@QBEHPBG000@Z */
1072 /* ?compare@?$collate@G@std@@QEBAHPEBG000@Z */
1073 DEFINE_THISCALL_WRAPPER(collate_wchar_compare, 20)
1074 int __thiscall collate_wchar_compare(const collate *this, const wchar_t *first1,
1075         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
1076 {
1077     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
1078     return call_collate_wchar_do_compare(this, first1, last1, first2, last2);
1079 }
1080
1081 /* ?do_hash@?$collate@_W@std@@MBEJPB_W0@Z */
1082 /* ?do_hash@?$collate@_W@std@@MEBAJPEB_W0@Z */
1083 /* ?do_hash@?$collate@G@std@@MBEJPBG0@Z */
1084 /* ?do_hash@?$collate@G@std@@MEBAJPEBG0@Z */
1085 DEFINE_THISCALL_WRAPPER(collate_wchar_do_hash, 12)
1086 #define call_collate_wchar_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
1087         (const collate*, const wchar_t*, const wchar_t*), (this, first, last))
1088 LONG __thiscall collate_wchar_do_hash(const collate *this,
1089         const wchar_t *first, const wchar_t *last)
1090 {
1091     ULONG ret = 0;
1092
1093     TRACE("(%p %p %p)\n", this, first, last);
1094
1095     for(; first<last; first++)
1096         ret = (ret<<8 | ret>>24) + *first;
1097     return ret;
1098 }
1099
1100 /* ?hash@?$collate@_W@std@@QBEJPB_W0@Z */
1101 /* ?hash@?$collate@_W@std@@QEBAJPEB_W0@Z */
1102 /* ?hash@?$collate@G@std@@QBEJPBG0@Z */
1103 /* ?hash@?$collate@G@std@@QEBAJPEBG0@Z */
1104 DEFINE_THISCALL_WRAPPER(collate_wchar_hash, 12)
1105 LONG __thiscall collate_wchar_hash(const collate *this,
1106         const wchar_t *first, const wchar_t *last)
1107 {
1108     TRACE("(%p %p %p)\n", this, first, last);
1109     return call_collate_wchar_do_hash(this, first, last);
1110 }
1111
1112 /* ?do_transform@?$collate@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1113 /* ?do_transform@?$collate@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1114 /* ?do_transform@?$collate@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1115 /* ?do_transform@?$collate@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1116 DEFINE_THISCALL_WRAPPER(collate_wchar_do_transform, 16)
1117 basic_string_wchar* __thiscall collate_wchar_do_transform(const collate *this,
1118         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1119 {
1120     FIXME("(%p %p %p) stub\n", this, first, last);
1121     return ret;
1122 }
1123
1124 /* ?transform@?$collate@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1125 /* ?transform@?$collate@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1126 /* ?transform@?$collate@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1127 /* ?transform@?$collate@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1128 DEFINE_THISCALL_WRAPPER(collate_wchar_transform, 16)
1129 basic_string_wchar* __thiscall collate_wchar_transform(const collate *this,
1130         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1131 {
1132     FIXME("(%p %p %p) stub\n", this, first, last);
1133     return ret;
1134 }
1135
1136 /* ??_7ctype_base@std@@6B@ */
1137 extern const vtable_ptr MSVCP_ctype_base_vtable;
1138
1139 /* ??0ctype_base@std@@QAE@I@Z */
1140 /* ??0ctype_base@std@@QEAA@_K@Z */
1141 DEFINE_THISCALL_WRAPPER(ctype_base_ctor_refs, 8)
1142 ctype_base* __thiscall ctype_base_ctor_refs(ctype_base *this, MSVCP_size_t refs)
1143 {
1144     TRACE("(%p %lu)\n", this, refs);
1145     locale_facet_ctor_refs(&this->facet, refs);
1146     this->facet.vtable = &MSVCP_ctype_base_vtable;
1147     return this;
1148 }
1149
1150 /* ??_Fctype_base@std@@QAEXXZ */
1151 /* ??_Fctype_base@std@@QEAAXXZ */
1152 DEFINE_THISCALL_WRAPPER(ctype_base_ctor, 4)
1153 ctype_base* __thiscall ctype_base_ctor(ctype_base *this)
1154 {
1155     TRACE("(%p)\n", this);
1156     locale_facet_ctor_refs(&this->facet, 0);
1157     this->facet.vtable = &MSVCP_ctype_base_vtable;
1158     return this;
1159 }
1160
1161 /* ??1ctype_base@std@@UAE@XZ */
1162 /* ??1ctype_base@std@@UEAA@XZ */
1163 DEFINE_THISCALL_WRAPPER(ctype_base_dtor, 4)
1164 void __thiscall ctype_base_dtor(ctype_base *this)
1165 {
1166     TRACE("(%p)\n", this);
1167 }
1168
1169 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_base_vector_dtor, 8)
1170 ctype_base* __thiscall MSVCP_ctype_base_vector_dtor(ctype_base *this, unsigned int flags)
1171 {
1172     TRACE("(%p %x)\n", this, flags);
1173     if(flags & 2) {
1174         /* we have an array, with the number of elements stored before the first object */
1175         int i, *ptr = (int *)this-1;
1176
1177         for(i=*ptr-1; i>=0; i--)
1178             ctype_base_dtor(this+i);
1179         MSVCRT_operator_delete(ptr);
1180     } else {
1181         ctype_base_dtor(this);
1182         if(flags & 1)
1183             MSVCRT_operator_delete(this);
1184     }
1185
1186     return this;
1187 }
1188
1189 /* ?_Xran@ctype_base@std@@KAXXZ */
1190 void __cdecl ctype_base__Xran(void)
1191 {
1192     throw_exception(EXCEPTION_OUT_OF_RANGE, "out of range in ctype<T>");
1193 }
1194
1195 /* ?id@?$ctype@D@std@@2V0locale@2@A */
1196 locale_id ctype_char_id = {0};
1197 /* ?table_size@?$ctype@D@std@@2IB */
1198 /* ?table_size@?$ctype@D@std@@2_KB */
1199 MSVCP_size_t ctype_char_table_size = 256;
1200
1201 /* ??_7?$ctype@D@std@@6B@ */
1202 extern const vtable_ptr MSVCP_ctype_char_vtable;
1203
1204 /* ?_Id_func@?$ctype@D@std@@SAAAVid@locale@2@XZ */
1205 /* ?_Id_func@?$ctype@D@std@@SAAEAVid@locale@2@XZ */
1206 locale_id* __cdecl ctype_char__Id_func(void)
1207 {
1208     TRACE("()\n");
1209     return &ctype_char_id;
1210 }
1211
1212 /* ?_Init@?$ctype@D@std@@IAEXABV_Locinfo@2@@Z */
1213 /* ?_Init@?$ctype@D@std@@IEAAXAEBV_Locinfo@2@@Z */
1214 DEFINE_THISCALL_WRAPPER(ctype_char__Init, 8)
1215 void __thiscall ctype_char__Init(ctype_char *this, _Locinfo *locinfo)
1216 {
1217     TRACE("(%p %p)\n", this, locinfo);
1218     _Locinfo__Getctype(locinfo, &this->ctype);
1219 }
1220
1221 /* ?_Tidy@?$ctype@D@std@@IAEXXZ */
1222 /* ?_Tidy@?$ctype@D@std@@IEAAXXZ */
1223 DEFINE_THISCALL_WRAPPER(ctype_char__Tidy, 4)
1224 void __thiscall ctype_char__Tidy(ctype_char *this)
1225 {
1226     TRACE("(%p)\n", this);
1227
1228     if(this->ctype.delfl)
1229         free((short*)this->ctype.table);
1230 }
1231
1232 /* ?classic_table@?$ctype@D@std@@KAPBFXZ */
1233 /* ?classic_table@?$ctype@D@std@@KAPEBFXZ */
1234 const short* __cdecl ctype_char_classic_table(void)
1235 {
1236     TRACE("()\n");
1237     return &((short*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_ctype"))[1];
1238 }
1239
1240 /* ??0?$ctype@D@std@@QAE@ABV_Locinfo@1@I@Z */
1241 /* ??0?$ctype@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1242 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_locinfo, 12)
1243 ctype_char* __thiscall ctype_char_ctor_locinfo(ctype_char *this,
1244         _Locinfo *locinfo, MSVCP_size_t refs)
1245 {
1246     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1247     ctype_base_ctor_refs(&this->base, refs);
1248     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1249     ctype_char__Init(this, locinfo);
1250     return this;
1251 }
1252
1253 /* ??0?$ctype@D@std@@QAE@PBF_NI@Z */
1254 /* ??0?$ctype@D@std@@QEAA@PEBF_N_K@Z */
1255 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_table, 16)
1256 ctype_char* __thiscall ctype_char_ctor_table(ctype_char *this,
1257         const short *table, MSVCP_bool delete, MSVCP_size_t refs)
1258 {
1259     _Locinfo locinfo;
1260
1261     TRACE("(%p %p %d %lu)\n", this, table, delete, refs);
1262
1263     ctype_base_ctor_refs(&this->base, refs);
1264     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1265
1266     _Locinfo_ctor(&locinfo);
1267     ctype_char__Init(this, &locinfo);
1268     _Locinfo_dtor(&locinfo);
1269
1270     if(table) {
1271         ctype_char__Tidy(this);
1272         this->ctype.table = table;
1273         this->ctype.delfl = delete;
1274     }
1275     return this;
1276 }
1277
1278 /* ??_F?$ctype@D@std@@QAEXXZ */
1279 /* ??_F?$ctype@D@std@@QEAAXXZ */
1280 DEFINE_THISCALL_WRAPPER(ctype_char_ctor, 4)
1281 ctype_char* __thiscall ctype_char_ctor(ctype_char *this)
1282 {
1283     return ctype_char_ctor_table(this, NULL, FALSE, 0);
1284 }
1285
1286 /* ??1?$ctype@D@std@@MAE@XZ */
1287 /* ??1?$ctype@D@std@@MEAA@XZ */
1288 DEFINE_THISCALL_WRAPPER(ctype_char_dtor, 4)
1289 void __thiscall ctype_char_dtor(ctype_char *this)
1290 {
1291     TRACE("(%p)\n", this);
1292     ctype_char__Tidy(this);
1293 }
1294
1295 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_char_vector_dtor, 8)
1296 ctype_char* __thiscall MSVCP_ctype_char_vector_dtor(ctype_char *this, unsigned int flags)
1297 {
1298     TRACE("(%p %x)\n", this, flags);
1299     if(flags & 2) {
1300         /* we have an array, with the number of elements stored before the first object */
1301         int i, *ptr = (int *)this-1;
1302
1303         for(i=*ptr-1; i>=0; i--)
1304             ctype_char_dtor(this+i);
1305         MSVCRT_operator_delete(ptr);
1306     } else {
1307         ctype_char_dtor(this);
1308         if(flags & 1)
1309             MSVCRT_operator_delete(this);
1310     }
1311
1312     return this;
1313 }
1314
1315 /* ?do_narrow@?$ctype@D@std@@MBEDDD@Z */
1316 /* ?do_narrow@?$ctype@D@std@@MEBADDD@Z */
1317 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow_ch, 12)
1318 #define call_ctype_char_do_narrow_ch(this, ch, unused) CALL_VTBL_FUNC(this, 36, \
1319         char, (const ctype_char*, char, char), (this, ch, unused))
1320 char __thiscall ctype_char_do_narrow_ch(const ctype_char *this, char ch, char unused)
1321 {
1322     TRACE("(%p %c %c)\n", this, ch, unused);
1323     return ch;
1324 }
1325
1326 /* ?do_narrow@?$ctype@D@std@@MBEPBDPBD0DPAD@Z */
1327 /* ?do_narrow@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD@Z */
1328 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow, 20)
1329 #define call_ctype_char_do_narrow(this, first, last, unused, dest) CALL_VTBL_FUNC(this, 32, \
1330         const char*, (const ctype_char*, const char*, const char*, char, char*), \
1331         (this, first, last, unused, dest))
1332 const char* __thiscall ctype_char_do_narrow(const ctype_char *this,
1333         const char *first, const char *last, char unused, char *dest)
1334 {
1335     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1336     memcpy(dest, first, last-first);
1337     return last;
1338 }
1339
1340 /* ?_Do_narrow_s@?$ctype@D@std@@MBEPBDPBD0DPADI@Z */
1341 /* ?_Do_narrow_s@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD_K@Z */
1342 DEFINE_THISCALL_WRAPPER(ctype_char__Do_narrow_s, 24)
1343 #define call_ctype_char__Do_narrow_s(this, first, last, unused, dest, size) CALL_VTBL_FUNC(this, 40, \
1344         const char*, (const ctype_char*, const char*, const char*, char, char*, MSVCP_size_t), \
1345         (this, first, last, unused, dest, size))
1346 const char* __thiscall ctype_char__Do_narrow_s(const ctype_char *this, const char *first,
1347         const char *last, char unused, char *dest, MSVCP_size_t size)
1348 {
1349     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1350     memcpy_s(dest, size, first, last-first);
1351     return last;
1352 }
1353
1354 /* ?narrow@?$ctype@D@std@@QBEDDD@Z */
1355 /* ?narrow@?$ctype@D@std@@QEBADDD@Z */
1356 DEFINE_THISCALL_WRAPPER(ctype_char_narrow_ch, 12)
1357 char __thiscall ctype_char_narrow_ch(const ctype_char *this, char ch, char dflt)
1358 {
1359     TRACE("(%p %c %c)\n", this, ch, dflt);
1360     return call_ctype_char_do_narrow_ch(this, ch, dflt);
1361 }
1362
1363 /* ?narrow@?$ctype@D@std@@QBEPBDPBD0DPAD@Z */
1364 /* ?narrow@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD@Z */
1365 DEFINE_THISCALL_WRAPPER(ctype_char_narrow, 20)
1366 const char* __thiscall ctype_char_narrow(const ctype_char *this,
1367         const char *first, const char *last, char dflt, char *dest)
1368 {
1369     TRACE("(%p %p %p %c %p)\n", this, first, last, dflt, dest);
1370     return call_ctype_char_do_narrow(this, first, last, dflt, dest);
1371 }
1372
1373 /* ?_Narrow_s@?$ctype@D@std@@QBEPBDPBD0DPADI@Z */
1374 /* ?_Narrow_s@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD_K@Z */
1375 DEFINE_THISCALL_WRAPPER(ctype_char__Narrow_s, 24)
1376 const char* __thiscall ctype_char__Narrow_s(const ctype_char *this, const char *first,
1377         const char *last, char dflt, char *dest, MSVCP_size_t size)
1378 {
1379     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1380     return call_ctype_char__Do_narrow_s(this, first, last, dflt, dest, size);
1381 }
1382
1383 /* ?do_widen@?$ctype@D@std@@MBEDD@Z */
1384 /* ?do_widen@?$ctype@D@std@@MEBADD@Z */
1385 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen_ch, 8)
1386 #define call_ctype_char_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
1387         char, (const ctype_char*, char), (this, ch))
1388 char __thiscall ctype_char_do_widen_ch(const ctype_char *this, char ch)
1389 {
1390     TRACE("(%p %c)\n", this, ch);
1391     return ch;
1392 }
1393
1394 /* ?do_widen@?$ctype@D@std@@MBEPBDPBD0PAD@Z */
1395 /* ?do_widen@?$ctype@D@std@@MEBAPEBDPEBD0PEAD@Z */
1396 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen, 16)
1397 #define call_ctype_char_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 20, \
1398         const char*, (const ctype_char*, const char*, const char*, char*), \
1399         (this, first, last, dest))
1400 const char* __thiscall ctype_char_do_widen(const ctype_char *this,
1401         const char *first, const char *last, char *dest)
1402 {
1403     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1404     memcpy(dest, first, last-first);
1405     return last;
1406 }
1407
1408 /* ?_Do_widen_s@?$ctype@D@std@@MBEPBDPBD0PADI@Z */
1409 /* ?_Do_widen_s@?$ctype@D@std@@MEBAPEBDPEBD0PEAD_K@Z */
1410 DEFINE_THISCALL_WRAPPER(ctype_char__Do_widen_s, 20)
1411 #define call_ctype_char__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 28, \
1412         const char*, (const ctype_char*, const char*, const char*, char*, MSVCP_size_t), \
1413         (this, first, last, dest, size))
1414 const char* __thiscall ctype_char__Do_widen_s(const ctype_char *this,
1415         const char *first, const char *last, char *dest, MSVCP_size_t size)
1416 {
1417     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1418     memcpy_s(dest, size, first, last-first);
1419     return last;
1420 }
1421
1422 /* ?widen@?$ctype@D@std@@QBEDD@Z */
1423 /* ?widen@?$ctype@D@std@@QEBADD@Z */
1424 DEFINE_THISCALL_WRAPPER(ctype_char_widen_ch, 8)
1425 char __thiscall ctype_char_widen_ch(const ctype_char *this, char ch)
1426 {
1427     TRACE("(%p %c)\n", this, ch);
1428     return call_ctype_char_do_widen_ch(this, ch);
1429 }
1430
1431 /* ?widen@?$ctype@D@std@@QBEPBDPBD0PAD@Z */
1432 /* ?widen@?$ctype@D@std@@QEBAPEBDPEBD0PEAD@Z */
1433 DEFINE_THISCALL_WRAPPER(ctype_char_widen, 16)
1434 const char* __thiscall ctype_char_widen(const ctype_char *this,
1435         const char *first, const char *last, char *dest)
1436 {
1437     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1438     return call_ctype_char_do_widen(this, first, last, dest);
1439 }
1440
1441 /* ?_Widen_s@?$ctype@D@std@@QBEPBDPBD0PADI@Z */
1442 /* ?_Widen_s@?$ctype@D@std@@QEBAPEBDPEBD0PEAD_K@Z */
1443 DEFINE_THISCALL_WRAPPER(ctype_char__Widen_s, 20)
1444 const char* __thiscall ctype_char__Widen_s(const ctype_char *this,
1445         const char *first, const char *last, char *dest, MSVCP_size_t size)
1446 {
1447     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
1448     return call_ctype_char__Do_widen_s(this, first, last, dest, size);
1449 }
1450
1451 /* ?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1452 /* ?_Getcat@?$ctype@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1453 MSVCP_size_t __cdecl ctype_char__Getcat(const locale_facet **facet, const locale *loc)
1454 {
1455     TRACE("(%p %p)\n", facet, loc);
1456
1457     if(facet && !*facet) {
1458         _Locinfo locinfo;
1459
1460         *facet = MSVCRT_operator_new(sizeof(ctype_char));
1461         if(!*facet) {
1462             ERR("Out of memory\n");
1463             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1464             return 0;
1465         }
1466
1467         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
1468         ctype_char_ctor_locinfo((ctype_char*)*facet, &locinfo, 0);
1469         _Locinfo_dtor(&locinfo);
1470     }
1471
1472     return LC_CTYPE;
1473 }
1474
1475 /* _Tolower */
1476 int __cdecl _Tolower(int ch, const _Ctypevec *ctype)
1477 {
1478     unsigned int cp;
1479
1480     TRACE("%d %p\n", ch, ctype);
1481
1482     if(ctype)
1483         cp = ctype->page;
1484     else
1485         cp = ___lc_codepage_func();
1486
1487     /* Don't convert to unicode in case of C locale */
1488     if(!cp) {
1489         if(ch>='A' && ch<='Z')
1490             ch = ch-'A'+'a';
1491         return ch;
1492     } else {
1493         WCHAR wide, lower;
1494         char str[2];
1495         int size;
1496
1497         if(ch > 255) {
1498             str[0] = (ch>>8) & 255;
1499             str[1] = ch & 255;
1500             size = 2;
1501         } else {
1502             str[0] = ch & 255;
1503             size = 1;
1504         }
1505
1506         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1507             return ch;
1508
1509         lower = tolowerW(wide);
1510         if(lower == wide)
1511             return ch;
1512
1513         WideCharToMultiByte(cp, 0, &lower, 1, str, 2, NULL, NULL);
1514
1515         return str[0] + (str[1]<<8);
1516     }
1517 }
1518
1519 /* ?do_tolower@?$ctype@D@std@@MBEDD@Z */
1520 /* ?do_tolower@?$ctype@D@std@@MEBADD@Z */
1521 #define call_ctype_char_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 8, \
1522         char, (const ctype_char*, char), (this, ch))
1523 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower_ch, 8)
1524 char __thiscall ctype_char_do_tolower_ch(const ctype_char *this, char ch)
1525 {
1526     TRACE("(%p %c)\n", this, ch);
1527     return _Tolower(ch, &this->ctype);
1528 }
1529
1530 /* ?do_tolower@?$ctype@D@std@@MBEPBDPADPBD@Z */
1531 /* ?do_tolower@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1532 #define call_ctype_char_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 4, \
1533         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1534 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower, 12)
1535 const char* __thiscall ctype_char_do_tolower(const ctype_char *this, char *first, const char *last)
1536 {
1537     TRACE("(%p %p %p)\n", this, first, last);
1538     for(; first<last; first++)
1539         *first = _Tolower(*first, &this->ctype);
1540     return last;
1541 }
1542
1543 /* ?tolower@?$ctype@D@std@@QBEDD@Z */
1544 /* ?tolower@?$ctype@D@std@@QEBADD@Z */
1545 DEFINE_THISCALL_WRAPPER(ctype_char_tolower_ch, 8)
1546 char __thiscall ctype_char_tolower_ch(const ctype_char *this, char ch)
1547 {
1548     TRACE("(%p %c)\n", this, ch);
1549     return call_ctype_char_do_tolower_ch(this, ch);
1550 }
1551
1552 /* ?tolower@?$ctype@D@std@@QBEPBDPADPBD@Z */
1553 /* ?tolower@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1554 DEFINE_THISCALL_WRAPPER(ctype_char_tolower, 12)
1555 const char* __thiscall ctype_char_tolower(const ctype_char *this, char *first, const char *last)
1556 {
1557     TRACE("(%p %p %p)\n", this, first, last);
1558     return call_ctype_char_do_tolower(this, first, last);
1559 }
1560
1561 /* _Toupper */
1562 int __cdecl _Toupper(int ch, const _Ctypevec *ctype)
1563 {
1564     unsigned int cp;
1565
1566     TRACE("%d %p\n", ch, ctype);
1567
1568     if(ctype)
1569         cp = ctype->page;
1570     else
1571         cp = ___lc_codepage_func();
1572
1573     /* Don't convert to unicode in case of C locale */
1574     if(!cp) {
1575         if(ch>='a' && ch<='z')
1576             ch = ch-'a'+'A';
1577         return ch;
1578     } else {
1579         WCHAR wide, upper;
1580         char str[2];
1581         int size;
1582
1583         if(ch > 255) {
1584             str[0] = (ch>>8) & 255;
1585             str[1] = ch & 255;
1586             size = 2;
1587         } else {
1588             str[0] = ch & 255;
1589             size = 1;
1590         }
1591
1592         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1593             return ch;
1594
1595         upper = toupperW(wide);
1596         if(upper == wide)
1597             return ch;
1598
1599         WideCharToMultiByte(cp, 0, &upper, 1, str, 2, NULL, NULL);
1600
1601         return str[0] + (str[1]<<8);
1602     }
1603 }
1604
1605 /* ?do_toupper@?$ctype@D@std@@MBEDD@Z */
1606 /* ?do_toupper@?$ctype@D@std@@MEBADD@Z */
1607 #define call_ctype_char_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 16, \
1608         char, (const ctype_char*, char), (this, ch))
1609 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper_ch, 8)
1610 char __thiscall ctype_char_do_toupper_ch(const ctype_char *this, char ch)
1611 {
1612     TRACE("(%p %c)\n", this, ch);
1613     return _Toupper(ch, &this->ctype);
1614 }
1615
1616 /* ?do_toupper@?$ctype@D@std@@MBEPBDPADPBD@Z */
1617 /* ?do_toupper@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1618 #define call_ctype_char_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 12, \
1619         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1620 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper, 12)
1621 const char* __thiscall ctype_char_do_toupper(const ctype_char *this,
1622         char *first, const char *last)
1623 {
1624     TRACE("(%p %p %p)\n", this, first, last);
1625     for(; first<last; first++)
1626         *first = _Toupper(*first, &this->ctype);
1627     return last;
1628 }
1629
1630 /* ?toupper@?$ctype@D@std@@QBEDD@Z */
1631 /* ?toupper@?$ctype@D@std@@QEBADD@Z */
1632 DEFINE_THISCALL_WRAPPER(ctype_char_toupper_ch, 8)
1633 char __thiscall ctype_char_toupper_ch(const ctype_char *this, char ch)
1634 {
1635     TRACE("(%p %c)\n", this, ch);
1636     return call_ctype_char_do_toupper_ch(this, ch);
1637 }
1638
1639 /* ?toupper@?$ctype@D@std@@QBEPBDPADPBD@Z */
1640 /* ?toupper@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1641 DEFINE_THISCALL_WRAPPER(ctype_char_toupper, 12)
1642 const char* __thiscall ctype_char_toupper(const ctype_char *this, char *first, const char *last)
1643 {
1644     TRACE("(%p %p %p)\n", this, first, last);
1645     return call_ctype_char_do_toupper(this, first, last);
1646 }
1647
1648 /* ?is@?$ctype@D@std@@QBE_NFD@Z */
1649 /* ?is@?$ctype@D@std@@QEBA_NFD@Z */
1650 DEFINE_THISCALL_WRAPPER(ctype_char_is_ch, 12)
1651 MSVCP_bool __thiscall ctype_char_is_ch(const ctype_char *this, short mask, char ch)
1652 {
1653     TRACE("(%p %x %c)\n", this, mask, ch);
1654     return (this->ctype.table[(unsigned char)ch] & mask) != 0;
1655 }
1656
1657 /* ?is@?$ctype@D@std@@QBEPBDPBD0PAF@Z */
1658 /* ?is@?$ctype@D@std@@QEBAPEBDPEBD0PEAF@Z */
1659 DEFINE_THISCALL_WRAPPER(ctype_char_is, 16)
1660 const char* __thiscall ctype_char_is(const ctype_char *this, const char *first, const char *last, short *dest)
1661 {
1662     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1663     for(; first<last; first++)
1664         *dest++ = this->ctype.table[(unsigned char)*first];
1665     return last;
1666 }
1667
1668 /* ?scan_is@?$ctype@D@std@@QBEPBDFPBD0@Z */
1669 /* ?scan_is@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1670 DEFINE_THISCALL_WRAPPER(ctype_char_scan_is, 16)
1671 const char* __thiscall ctype_char_scan_is(const ctype_char *this, short mask, const char *first, const char *last)
1672 {
1673     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1674     for(; first<last; first++)
1675         if(!ctype_char_is_ch(this, mask, *first))
1676             break;
1677     return first;
1678 }
1679
1680 /* ?scan_not@?$ctype@D@std@@QBEPBDFPBD0@Z */
1681 /* ?scan_not@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1682 DEFINE_THISCALL_WRAPPER(ctype_char_scan_not, 16)
1683 const char* __thiscall ctype_char_scan_not(const ctype_char *this, short mask, const char *first, const char *last)
1684 {
1685     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1686     for(; first<last; first++)
1687         if(ctype_char_is_ch(this, mask, *first))
1688             break;
1689     return first;
1690 }
1691
1692 /* ?table@?$ctype@D@std@@IBEPBFXZ */
1693 /* ?table@?$ctype@D@std@@IEBAPEBFXZ */
1694 DEFINE_THISCALL_WRAPPER(ctype_char_table, 4)
1695 const short* __thiscall ctype_char_table(const ctype_char *this)
1696 {
1697     TRACE("(%p)\n", this);
1698     return this->ctype.table;
1699 }
1700
1701 /* ?id@?$ctype@_W@std@@2V0locale@2@A */
1702 locale_id ctype_wchar_id = {0};
1703 /* ?id@?$ctype@G@std@@2V0locale@2@A */
1704 locale_id ctype_short_id = {0};
1705
1706 /* ??_7?$ctype@_W@std@@6B@ */
1707 extern const vtable_ptr MSVCP_ctype_wchar_vtable;
1708 /* ??_7?$ctype@G@std@@6B@ */
1709 extern const vtable_ptr MSVCP_ctype_short_vtable;
1710
1711 /* ?_Id_func@?$ctype@_W@std@@SAAAVid@locale@2@XZ */
1712 /* ?_Id_func@?$ctype@_W@std@@SAAEAVid@locale@2@XZ */
1713 locale_id* __cdecl ctype_wchar__Id_func(void)
1714 {
1715     TRACE("()\n");
1716     return &ctype_wchar_id;
1717 }
1718
1719 /* ?_Id_func@?$ctype@G@std@@SAAAVid@locale@2@XZ */
1720 /* ?_Id_func@?$ctype@G@std@@SAAEAVid@locale@2@XZ */
1721 locale_id* __cdecl ctype_short__Id_func(void)
1722 {
1723     TRACE("()\n");
1724     return &ctype_short_id;
1725 }
1726
1727 /* ?_Init@?$ctype@_W@std@@IAEXABV_Locinfo@2@@Z */
1728 /* ?_Init@?$ctype@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
1729 /* ?_Init@?$ctype@G@std@@IAEXABV_Locinfo@2@@Z */
1730 /* ?_Init@?$ctype@G@std@@IEAAXAEBV_Locinfo@2@@Z */
1731 DEFINE_THISCALL_WRAPPER(ctype_wchar__Init, 8)
1732 void __thiscall ctype_wchar__Init(ctype_wchar *this, _Locinfo *locinfo)
1733 {
1734     TRACE("(%p %p)\n", this, locinfo);
1735     _Locinfo__Getctype(locinfo, &this->ctype);
1736     _Locinfo__Getcvt(locinfo, &this->cvt);
1737 }
1738
1739 /* ??0?$ctype@_W@std@@QAE@ABV_Locinfo@1@I@Z */
1740 /* ??0?$ctype@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1741 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_locinfo, 12)
1742 ctype_wchar* __thiscall ctype_wchar_ctor_locinfo(ctype_wchar *this,
1743         _Locinfo *locinfo, MSVCP_size_t refs)
1744 {
1745     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1746     ctype_base_ctor_refs(&this->base, refs);
1747     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1748     ctype_wchar__Init(this, locinfo);
1749     return this;
1750 }
1751
1752 /* ??0?$ctype@G@std@@QAE@ABV_Locinfo@1@I@Z */
1753 /* ??0?$ctype@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1754 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_locinfo, 12)
1755 ctype_wchar* __thiscall ctype_short_ctor_locinfo(ctype_wchar *this,
1756         _Locinfo *locinfo, MSVCP_size_t refs)
1757 {
1758     ctype_wchar *ret = ctype_wchar_ctor_locinfo(this, locinfo, refs);
1759     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1760     return ret;
1761 }
1762
1763 /* ??0?$ctype@_W@std@@QAE@I@Z */
1764 /* ??0?$ctype@_W@std@@QEAA@_K@Z */
1765 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor_refs, 8)
1766 ctype_wchar* __thiscall ctype_wchar_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1767 {
1768     _Locinfo locinfo;
1769
1770     TRACE("(%p %lu)\n", this, refs);
1771
1772     ctype_base_ctor_refs(&this->base, refs);
1773     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1774
1775     _Locinfo_ctor(&locinfo);
1776     ctype_wchar__Init(this, &locinfo);
1777     _Locinfo_dtor(&locinfo);
1778     return this;
1779 }
1780
1781 /* ??0?$ctype@G@std@@QAE@I@Z */
1782 /* ??0?$ctype@G@std@@QEAA@_K@Z */
1783 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_refs, 8)
1784 ctype_wchar* __thiscall ctype_short_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1785 {
1786     ctype_wchar *ret = ctype_wchar_ctor_refs(this, refs);
1787     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1788     return ret;
1789 }
1790
1791 /* ??0?$ctype@G@std@@IAE@PBDI@Z */
1792 /* ??0?$ctype@G@std@@IEAA@PEBD_K@Z */
1793 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_name, 12)
1794 ctype_wchar* __thiscall ctype_short_ctor_name(ctype_wchar *this,
1795     const char *name, MSVCP_size_t refs)
1796 {
1797     _Locinfo locinfo;
1798
1799     TRACE("(%p %s %lu)\n", this, debugstr_a(name), refs);
1800
1801     ctype_base_ctor_refs(&this->base, refs);
1802     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1803
1804     _Locinfo_ctor_cstr(&locinfo, name);
1805     ctype_wchar__Init(this, &locinfo);
1806     _Locinfo_dtor(&locinfo);
1807     return this;
1808 }
1809
1810 /* ??_F?$ctype@_W@std@@QAEXXZ */
1811 /* ??_F?$ctype@_W@std@@QEAAXXZ */
1812 DEFINE_THISCALL_WRAPPER(ctype_wchar_ctor, 4)
1813 ctype_wchar* __thiscall ctype_wchar_ctor(ctype_wchar *this)
1814 {
1815     TRACE("(%p)\n", this);
1816     return ctype_short_ctor_refs(this, 0);
1817 }
1818
1819 /* ??_F?$ctype@G@std@@QAEXXZ */
1820 /* ??_F?$ctype@G@std@@QEAAXXZ */
1821 DEFINE_THISCALL_WRAPPER(ctype_short_ctor, 4)
1822 ctype_wchar* __thiscall ctype_short_ctor(ctype_wchar *this)
1823 {
1824     ctype_wchar *ret = ctype_wchar_ctor(this);
1825     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1826     return ret;
1827 }
1828
1829 /* ??1?$ctype@_W@std@@MAE@XZ */
1830 /* ??1?$ctype@_W@std@@MEAA@XZ */
1831 /* ??1?$ctype@G@std@@MAE@XZ */
1832 /* ??1?$ctype@G@std@@MEAA@XZ */
1833 DEFINE_THISCALL_WRAPPER(ctype_wchar_dtor, 4)
1834 void __thiscall ctype_wchar_dtor(ctype_wchar *this)
1835 {
1836     TRACE("(%p)\n", this);
1837     if(this->ctype.delfl)
1838         free((void*)this->ctype.table);
1839 }
1840
1841 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_wchar_vector_dtor, 8)
1842 ctype_wchar* __thiscall MSVCP_ctype_wchar_vector_dtor(ctype_wchar *this, unsigned int flags)
1843 {
1844     TRACE("(%p %x)\n", this, flags);
1845     if(flags & 2) {
1846         /* we have an array, with the number of elements stored before the first object */
1847         int i, *ptr = (int *)this-1;
1848
1849         for(i=*ptr-1; i>=0; i--)
1850             ctype_wchar_dtor(this+i);
1851         MSVCRT_operator_delete(ptr);
1852     } else {
1853         ctype_wchar_dtor(this);
1854         if(flags & 1)
1855             MSVCRT_operator_delete(this);
1856     }
1857
1858     return this;
1859 }
1860
1861 DEFINE_THISCALL_WRAPPER(MSVCP_ctype_short_vector_dtor, 8)
1862 ctype_wchar* __thiscall MSVCP_ctype_short_vector_dtor(ctype_wchar *this, unsigned int flags)
1863 {
1864     return MSVCP_ctype_wchar_vector_dtor(this, flags);
1865 }
1866
1867 /* _Wcrtomb */
1868 int __cdecl _Wcrtomb(char *s, wchar_t wch, int *state, const _Cvtvec *cvt)
1869 {
1870     int cp, size;
1871     BOOL def;
1872
1873     TRACE("%p %d %p %p\n", s, wch, state, cvt);
1874
1875     if(cvt)
1876         cp = cvt->page;
1877     else
1878         cp = ___lc_codepage_func();
1879
1880     if(!cp) {
1881         if(wch > 255) {
1882            *_errno() = EILSEQ;
1883            return -1;
1884         }
1885
1886         *s = wch & 255;
1887         return 1;
1888     }
1889
1890     size = WideCharToMultiByte(cp, 0, &wch, 1, s, MB_LEN_MAX, NULL, &def);
1891     if(!size || def) {
1892         *_errno() = EILSEQ;
1893         return -1;
1894     }
1895
1896     return size;
1897 }
1898
1899 /* ?_Donarrow@?$ctype@_W@std@@IBED_WD@Z */
1900 /* ?_Donarrow@?$ctype@_W@std@@IEBAD_WD@Z */
1901 /* ?_Donarrow@?$ctype@G@std@@IBEDGD@Z */
1902 /* ?_Donarrow@?$ctype@G@std@@IEBADGD@Z */
1903 DEFINE_THISCALL_WRAPPER(ctype_wchar__Donarrow, 12)
1904 char __thiscall ctype_wchar__Donarrow(const ctype_wchar *this, wchar_t ch, char dflt)
1905 {
1906     char buf[MB_LEN_MAX];
1907
1908     TRACE("(%p %d %d)\n", this, ch, dflt);
1909
1910     return _Wcrtomb(buf, ch, NULL, &this->cvt)==1 ? buf[0] : dflt;
1911 }
1912
1913 /* ?do_narrow@?$ctype@_W@std@@MBED_WD@Z */
1914 /* ?do_narrow@?$ctype@_W@std@@MEBAD_WD@Z */
1915 /* ?do_narrow@?$ctype@G@std@@MBEDGD@Z */
1916 /* ?do_narrow@?$ctype@G@std@@MEBADGD@Z */
1917 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow_ch, 12)
1918 #define call_ctype_wchar_do_narrow_ch(this, ch, dflt) CALL_VTBL_FUNC(this, 52, \
1919         char, (const ctype_wchar*, wchar_t, char), (this, ch, dflt))
1920 char __thiscall ctype_wchar_do_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
1921 {
1922     return ctype_wchar__Donarrow(this, ch, dflt);
1923 }
1924
1925 /* ?do_narrow@?$ctype@_W@std@@MBEPB_WPB_W0DPAD@Z */
1926 /* ?do_narrow@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD@Z */
1927 /* ?do_narrow@?$ctype@G@std@@MBEPBGPBG0DPAD@Z */
1928 /* ?do_narrow@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD@Z */
1929 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow, 20)
1930 #define call_ctype_wchar_do_narrow(this, first, last, dflt, dest) CALL_VTBL_FUNC(this, 48, \
1931         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*), \
1932         (this, first, last, dflt, dest))
1933 const wchar_t* __thiscall ctype_wchar_do_narrow(const ctype_wchar *this,
1934         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
1935 {
1936     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
1937     for(; first<last; first++)
1938         *dest++ = ctype_wchar__Donarrow(this, *first, dflt);
1939     return last;
1940 }
1941
1942 /* ?_Do_narrow_s@?$ctype@_W@std@@MBEPB_WPB_W0DPADI@Z */
1943 /* ?_Do_narrow_s@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD_K@Z */
1944 /* ?_Do_narrow_s@?$ctype@G@std@@MBEPBGPBG0DPADI@Z */
1945 /* ?_Do_narrow_s@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD_K@Z */
1946 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_narrow_s, 24)
1947 #define call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size) CALL_VTBL_FUNC(this, 56, \
1948         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*, MSVCP_size_t), \
1949         (this, first, last, dflt, dest, size))
1950 const wchar_t* __thiscall ctype_wchar__Do_narrow_s(const ctype_wchar *this,
1951         const wchar_t *first, const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
1952 {
1953     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
1954     /* This function converts all multi-byte characters to dflt,
1955      * thanks to it result size is known before converting */
1956     if(last-first > size)
1957         ctype_base__Xran();
1958     return ctype_wchar_do_narrow(this, first, last, dflt, dest);
1959 }
1960
1961 /* ?narrow@?$ctype@_W@std@@QBED_WD@Z */
1962 /* ?narrow@?$ctype@_W@std@@QEBAD_WD@Z */
1963 /* ?narrow@?$ctype@G@std@@QBEDGD@Z */
1964 /* ?narrow@?$ctype@G@std@@QEBADGD@Z */
1965 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow_ch, 12)
1966 char __thiscall ctype_wchar_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
1967 {
1968     TRACE("(%p %d %d)\n", this, ch, dflt);
1969     return call_ctype_wchar_do_narrow_ch(this, ch, dflt);
1970 }
1971
1972 /* ?narrow@?$ctype@_W@std@@QBEPB_WPB_W0DPAD@Z */
1973 /* ?narrow@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD@Z */
1974 /* ?narrow@?$ctype@G@std@@QBEPBGPBG0DPAD@Z */
1975 /* ?narrow@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD@Z */
1976 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow, 20)
1977 const wchar_t* __thiscall ctype_wchar_narrow(const ctype_wchar *this,
1978         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
1979 {
1980     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
1981     return call_ctype_wchar_do_narrow(this, first, last, dflt, dest);
1982 }
1983
1984 /* ?_Narrow_s@?$ctype@_W@std@@QBEPB_WPB_W0DPADI@Z */
1985 /* ?_Narrow_s@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD_K@Z */
1986 /* ?_Narrow_s@?$ctype@G@std@@QBEPBGPBG0DPADI@Z */
1987 /* ?_Narrow_s@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD_K@Z */
1988 DEFINE_THISCALL_WRAPPER(ctype_wchar__Narrow_s, 24)
1989 const wchar_t* __thiscall ctype_wchar__Narrow_s(const ctype_wchar *this, const wchar_t *first,
1990         const wchar_t *last, char dflt, char *dest, MSVCP_size_t size)
1991 {
1992     TRACE("(%p %p %p %d %p %lu)\n", this, first, last, dflt, dest, size);
1993     return call_ctype_wchar__Do_narrow_s(this, first, last, dflt, dest, size);
1994 }
1995
1996 /* _Mbrtowc */
1997 int __cdecl _Mbrtowc(wchar_t *out, const char *in, MSVCP_size_t len, int *state, const _Cvtvec *cvt)
1998 {
1999     int i, cp;
2000     CPINFO cp_info;
2001     BOOL is_lead;
2002
2003     TRACE("(%p %p %lu %p %p)\n", out, in, len, state, cvt);
2004
2005     if(!len)
2006         return 0;
2007
2008     if(cvt)
2009         cp = cvt->page;
2010     else
2011         cp = ___lc_codepage_func();
2012
2013     if(!cp) {
2014         if(out)
2015             *out = (unsigned char)*in;
2016
2017         *state = 0;
2018         return *in ? 1 : 0;
2019     }
2020
2021     if(*state) {
2022         ((char*)state)[1] = *in;
2023
2024         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, (char*)state, 2, out, out ? 1 : 0)) {
2025             *state = 0;
2026             *_errno() = EILSEQ;
2027             return -1;
2028         }
2029
2030         *state = 0;
2031         return 2;
2032     }
2033
2034     GetCPInfo(cp, &cp_info);
2035     is_lead = FALSE;
2036     for(i=0; i<MAX_LEADBYTES; i+=2) {
2037         if(!cp_info.LeadByte[i+1])
2038             break;
2039         if((unsigned char)*in>=cp_info.LeadByte[i] && (unsigned char)*in<=cp_info.LeadByte[i+1]) {
2040             is_lead = TRUE;
2041             break;
2042         }
2043     }
2044
2045     if(is_lead) {
2046         if(len == 1) {
2047             *state = (unsigned char)*in;
2048             return -2;
2049         }
2050
2051         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 2, out, out ? 1 : 0)) {
2052             *_errno() = EILSEQ;
2053             return -1;
2054         }
2055         return 2;
2056     }
2057
2058     if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 1, out, out ? 1 : 0)) {
2059         *_errno() = EILSEQ;
2060         return -1;
2061     }
2062     return 1;
2063 }
2064
2065 /* ?_Dowiden@?$ctype@_W@std@@IBE_WD@Z */
2066 /* ?_Dowiden@?$ctype@_W@std@@IEBA_WD@Z */
2067 /* ?_Dowiden@?$ctype@G@std@@IBEGD@Z */
2068 /* ?_Dowiden@?$ctype@G@std@@IEBAGD@Z */
2069 DEFINE_THISCALL_WRAPPER(ctype_wchar__Dowiden, 8)
2070 wchar_t __thiscall ctype_wchar__Dowiden(const ctype_wchar *this, char ch)
2071 {
2072     wchar_t ret;
2073     int state = 0;
2074     TRACE("(%p %d)\n", this, ch);
2075     return _Mbrtowc(&ret, &ch, 1, &state, &this->cvt)<0 ? WEOF : ret;
2076 }
2077
2078 /* ?do_widen@?$ctype@_W@std@@MBE_WD@Z */
2079 /* ?do_widen@?$ctype@_W@std@@MEBA_WD@Z */
2080 /* ?do_widen@?$ctype@G@std@@MBEGD@Z */
2081 /* ?do_widen@?$ctype@G@std@@MEBAGD@Z */
2082 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen_ch, 8)
2083 #define call_ctype_wchar_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 40, \
2084         wchar_t, (const ctype_wchar*, char), (this, ch))
2085 wchar_t __thiscall ctype_wchar_do_widen_ch(const ctype_wchar *this, char ch)
2086 {
2087     return ctype_wchar__Dowiden(this, ch);
2088 }
2089
2090 /* ?do_widen@?$ctype@_W@std@@MBEPBDPBD0PA_W@Z */
2091 /* ?do_widen@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W@Z */
2092 /* ?do_widen@?$ctype@G@std@@MBEPBDPBD0PAG@Z */
2093 /* ?do_widen@?$ctype@G@std@@MEBAPEBDPEBD0PEAG@Z */
2094 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen, 16)
2095 #define call_ctype_wchar_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 36, \
2096         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*), \
2097         (this, first, last, dest))
2098 const char* __thiscall ctype_wchar_do_widen(const ctype_wchar *this,
2099         const char *first, const char *last, wchar_t *dest)
2100 {
2101     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2102     for(; first<last; first++)
2103         *dest++ = ctype_wchar__Dowiden(this, *first);
2104     return last;
2105 }
2106
2107 /* ?_Do_widen_s@?$ctype@_W@std@@MBEPBDPBD0PA_WI@Z */
2108 /* ?_Do_widen_s@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W_K@Z */
2109 /* ?_Do_widen_s@?$ctype@G@std@@MBEPBDPBD0PAGI@Z */
2110 /* ?_Do_widen_s@?$ctype@G@std@@MEBAPEBDPEBD0PEAG_K@Z */
2111 DEFINE_THISCALL_WRAPPER(ctype_wchar__Do_widen_s, 20)
2112 #define call_ctype_wchar__Do_widen_s(this, first, last, dest, size) CALL_VTBL_FUNC(this, 44, \
2113         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*, MSVCP_size_t), \
2114         (this, first, last, dest, size))
2115 const char* __thiscall ctype_wchar__Do_widen_s(const ctype_wchar *this,
2116         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2117 {
2118     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2119     /* This function converts all multi-byte characters to WEOF,
2120      * thanks to it result size is known before converting */
2121     if(size < last-first)
2122         ctype_base__Xran();
2123     return ctype_wchar_do_widen(this, first, last, dest);
2124 }
2125
2126 /* ?widen@?$ctype@_W@std@@QBE_WD@Z */
2127 /* ?widen@?$ctype@_W@std@@QEBA_WD@Z */
2128 /* ?widen@?$ctype@G@std@@QBEGD@Z */
2129 /* ?widen@?$ctype@G@std@@QEBAGD@Z */
2130 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen_ch, 8)
2131 wchar_t __thiscall ctype_wchar_widen_ch(const ctype_wchar *this, char ch)
2132 {
2133     TRACE("(%p %d)\n", this, ch);
2134     return call_ctype_wchar_do_widen_ch(this, ch);
2135 }
2136
2137 /* ?widen@?$ctype@_W@std@@QBEPBDPBD0PA_W@Z */
2138 /* ?widen@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W@Z */
2139 /* ?widen@?$ctype@G@std@@QBEPBDPBD0PAG@Z */
2140 /* ?widen@?$ctype@G@std@@QEBAPEBDPEBD0PEAG@Z */
2141 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen, 16)
2142 const char* __thiscall ctype_wchar_widen(const ctype_wchar *this,
2143         const char *first, const char *last, wchar_t *dest)
2144 {
2145     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2146     return call_ctype_wchar_do_widen(this, first, last, dest);
2147 }
2148
2149 /* ?_Widen_s@?$ctype@_W@std@@QBEPBDPBD0PA_WI@Z */
2150 /* ?_Widen_s@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W_K@Z */
2151 /* ?_Widen_s@?$ctype@G@std@@QBEPBDPBD0PAGI@Z */
2152 /* ?_Widen_s@?$ctype@G@std@@QEBAPEBDPEBD0PEAG_K@Z */
2153 DEFINE_THISCALL_WRAPPER(ctype_wchar__Widen_s, 20)
2154 const char* __thiscall ctype_wchar__Widen_s(const ctype_wchar *this,
2155         const char *first, const char *last, wchar_t *dest, MSVCP_size_t size)
2156 {
2157     TRACE("(%p %p %p %p %lu)\n", this, first, last, dest, size);
2158     return call_ctype_wchar__Do_widen_s(this, first, last, dest, size);
2159 }
2160
2161 /* ?_Getcat@?$ctype@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2162 /* ?_Getcat@?$ctype@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2163 MSVCP_size_t __cdecl ctype_wchar__Getcat(const locale_facet **facet, const locale *loc)
2164 {
2165     TRACE("(%p %p)\n", facet, loc);
2166
2167     if(facet && !*facet) {
2168         _Locinfo locinfo;
2169
2170         *facet = MSVCRT_operator_new(sizeof(ctype_wchar));
2171         if(!*facet) {
2172             ERR("Out of memory\n");
2173             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2174             return 0;
2175         }
2176
2177         _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
2178         ctype_wchar_ctor_locinfo((ctype_wchar*)*facet, &locinfo, 0);
2179         _Locinfo_dtor(&locinfo);
2180     }
2181
2182     return LC_CTYPE;
2183 }
2184
2185 /* ?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2186 /* ?_Getcat@?$ctype@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2187 MSVCP_size_t __cdecl ctype_short__Getcat(const locale_facet **facet, const locale *loc)
2188 {
2189     if(facet && !*facet) {
2190         ctype_wchar__Getcat(facet, loc);
2191         (*(locale_facet**)facet)->vtable = &MSVCP_ctype_short_vtable;
2192     }
2193
2194     return LC_CTYPE;
2195 }
2196
2197 /* _Towlower */
2198 wchar_t __cdecl _Towlower(wchar_t ch, const _Ctypevec *ctype)
2199 {
2200     TRACE("(%d %p)\n", ch, ctype);
2201     return tolowerW(ch);
2202 }
2203
2204 /* ?do_tolower@?$ctype@_W@std@@MBE_W_W@Z */
2205 /* ?do_tolower@?$ctype@_W@std@@MEBA_W_W@Z */
2206 /* ?do_tolower@?$ctype@G@std@@MBEGG@Z */
2207 /* ?do_tolower@?$ctype@G@std@@MEBAGG@Z */
2208 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower_ch, 8)
2209 #define call_ctype_wchar_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
2210         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2211 wchar_t __thiscall ctype_wchar_do_tolower_ch(const ctype_wchar *this, wchar_t ch)
2212 {
2213     return _Towlower(ch, &this->ctype);
2214 }
2215
2216 /* ?do_tolower@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2217 /* ?do_tolower@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2218 /* ?do_tolower@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2219 /* ?do_tolower@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2220 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower, 12)
2221 #define call_ctype_wchar_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 20, \
2222         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2223         (this, first, last))
2224 const wchar_t* __thiscall ctype_wchar_do_tolower(const ctype_wchar *this,
2225         wchar_t *first, const wchar_t *last)
2226 {
2227     TRACE("(%p %p %p)\n", this, first, last);
2228     for(; first<last; first++)
2229         *first = _Towlower(*first, &this->ctype);
2230     return last;
2231 }
2232
2233 /* ?tolower@?$ctype@_W@std@@QBE_W_W@Z */
2234 /* ?tolower@?$ctype@_W@std@@QEBA_W_W@Z */
2235 /* ?tolower@?$ctype@G@std@@QBEGG@Z */
2236 /* ?tolower@?$ctype@G@std@@QEBAGG@Z */
2237 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower_ch, 8)
2238 wchar_t __thiscall ctype_wchar_tolower_ch(const ctype_wchar *this, wchar_t ch)
2239 {
2240     TRACE("(%p %d)\n", this, ch);
2241     return call_ctype_wchar_do_tolower_ch(this, ch);
2242 }
2243
2244 /* ?tolower@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2245 /* ?tolower@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2246 /* ?tolower@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2247 /* ?tolower@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2248 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower, 12)
2249 const wchar_t* __thiscall ctype_wchar_tolower(const ctype_wchar *this,
2250         wchar_t *first, const wchar_t *last)
2251 {
2252     TRACE("(%p %p %p)\n", this, first, last);
2253     return call_ctype_wchar_do_tolower(this, first, last);
2254 }
2255
2256 /* _Towupper */
2257 wchar_t __cdecl _Towupper(wchar_t ch, const _Ctypevec *ctype)
2258 {
2259     TRACE("(%d %p)\n", ch, ctype);
2260     return toupperW(ch);
2261 }
2262
2263 /* ?do_toupper@?$ctype@_W@std@@MBE_W_W@Z */
2264 /* ?do_toupper@?$ctype@_W@std@@MEBA_W_W@Z */
2265 /* ?do_toupper@?$ctype@G@std@@MBEGG@Z */
2266 /* ?do_toupper@?$ctype@G@std@@MEBAGG@Z */
2267 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper_ch, 8)
2268 #define call_ctype_wchar_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 32, \
2269         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2270 wchar_t __thiscall ctype_wchar_do_toupper_ch(const ctype_wchar *this, wchar_t ch)
2271 {
2272     return _Towupper(ch, &this->ctype);
2273 }
2274
2275 /* ?do_toupper@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2276 /* ?do_toupper@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2277 /* ?do_toupper@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2278 /* ?do_toupper@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2279 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper, 12)
2280 #define call_ctype_wchar_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 28, \
2281         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2282         (this, first, last))
2283 const wchar_t* __thiscall ctype_wchar_do_toupper(const ctype_wchar *this,
2284         wchar_t *first, const wchar_t *last)
2285 {
2286     TRACE("(%p %p %p)\n", this, first, last);
2287     for(; first<last; first++)
2288         *first = _Towupper(*first, &this->ctype);
2289     return last;
2290 }
2291
2292 /* ?toupper@?$ctype@_W@std@@QBE_W_W@Z */
2293 /* ?toupper@?$ctype@_W@std@@QEBA_W_W@Z */
2294 /* ?toupper@?$ctype@G@std@@QBEGG@Z */
2295 /* ?toupper@?$ctype@G@std@@QEBAGG@Z */
2296 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper_ch, 8)
2297 wchar_t __thiscall ctype_wchar_toupper_ch(const ctype_wchar *this, wchar_t ch)
2298 {
2299     TRACE("(%p %d)\n", this, ch);
2300     return call_ctype_wchar_do_toupper_ch(this, ch);
2301 }
2302
2303 /* ?toupper@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2304 /* ?toupper@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2305 /* ?toupper@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2306 /* ?toupper@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2307 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper, 12)
2308 const wchar_t* __thiscall ctype_wchar_toupper(const ctype_wchar *this,
2309         wchar_t *first, const wchar_t *last)
2310 {
2311     TRACE("(%p %p %p)\n", this, first, last);
2312     return call_ctype_wchar_do_toupper(this, first, last);
2313 }
2314
2315 /* _Getwctypes */
2316 const wchar_t* __cdecl _Getwctypes(const wchar_t *first, const wchar_t *last,
2317         short *mask, const _Ctypevec *ctype)
2318 {
2319     TRACE("(%p %p %p %p)\n", first, last, mask, ctype);
2320     GetStringTypeW(CT_CTYPE1, first, last-first, (WORD*)mask);
2321     return last;
2322 }
2323
2324 /* _Getwctype */
2325 short __cdecl _Getwctype(wchar_t ch, const _Ctypevec *ctype)
2326 {
2327     short mask = 0;
2328     _Getwctypes(&ch, &ch+1, &mask, ctype);
2329     return mask;
2330 }
2331
2332 /* ?do_is@?$ctype@_W@std@@MBE_NF_W@Z */
2333 /* ?do_is@?$ctype@_W@std@@MEBA_NF_W@Z */
2334 /* ?do_is@?$ctype@G@std@@MBE_NFG@Z */
2335 /* ?do_is@?$ctype@G@std@@MEBA_NFG@Z */
2336 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is_ch, 12)
2337 #define call_ctype_wchar_do_is_ch(this, mask, ch) CALL_VTBL_FUNC(this, 8, \
2338         MSVCP_bool, (const ctype_wchar*, short, wchar_t), (this, mask, ch))
2339 MSVCP_bool __thiscall ctype_wchar_do_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2340 {
2341     TRACE("(%p %x %d)\n", this, mask, ch);
2342     return (_Getwctype(ch, &this->ctype) & mask) != 0;
2343 }
2344
2345 /* ?do_is@?$ctype@_W@std@@MBEPB_WPB_W0PAF@Z */
2346 /* ?do_is@?$ctype@_W@std@@MEBAPEB_WPEB_W0PEAF@Z */
2347 /* ?do_is@?$ctype@G@std@@MBEPBGPBG0PAF@Z */
2348 /* ?do_is@?$ctype@G@std@@MEBAPEBGPEBG0PEAF@Z */
2349 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is, 16)
2350 #define call_ctype_wchar_do_is(this, first, last, dest) CALL_VTBL_FUNC(this, 4, \
2351         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, short*), \
2352         (this, first, last, dest))
2353 const wchar_t* __thiscall ctype_wchar_do_is(const ctype_wchar *this,
2354         const wchar_t *first, const wchar_t *last, short *dest)
2355 {
2356     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2357     return _Getwctypes(first, last, dest, &this->ctype);
2358 }
2359
2360 /* ?is@?$ctype@_W@std@@QBE_NF_W@Z */
2361 /* ?is@?$ctype@_W@std@@QEBA_NF_W@Z */
2362 /* ?is@?$ctype@G@std@@QBE_NFG@Z */
2363 /* ?is@?$ctype@G@std@@QEBA_NFG@Z */
2364 DEFINE_THISCALL_WRAPPER(ctype_wchar_is_ch, 12)
2365 MSVCP_bool __thiscall ctype_wchar_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2366 {
2367     TRACE("(%p %x %d)\n", this, mask, ch);
2368     return call_ctype_wchar_do_is_ch(this, mask, ch);
2369 }
2370
2371 /* ?is@?$ctype@_W@std@@QBEPB_WPB_W0PAF@Z */
2372 /* ?is@?$ctype@_W@std@@QEBAPEB_WPEB_W0PEAF@Z */
2373 /* ?is@?$ctype@G@std@@QBEPBGPBG0PAF@Z */
2374 /* ?is@?$ctype@G@std@@QEBAPEBGPEBG0PEAF@Z */
2375 DEFINE_THISCALL_WRAPPER(ctype_wchar_is, 16)
2376 const wchar_t* __thiscall ctype_wchar_is(const ctype_wchar *this,
2377         const wchar_t *first, const wchar_t *last, short *dest)
2378 {
2379     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2380     return call_ctype_wchar_do_is(this, first, last, dest);
2381 }
2382
2383 /* ?do_scan_is@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2384 /* ?do_scan_is@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2385 /* ?do_scan_is@?$ctype@G@std@@MBEPBGFPBG0@Z */
2386 /* ?do_scan_is@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2387 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_is, 16)
2388 #define call_ctype_wchar_do_scan_is(this, mask, first, last) CALL_VTBL_FUNC(this, 12, \
2389         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2390         (this, mask, first, last))
2391 const wchar_t* __thiscall ctype_wchar_do_scan_is(const ctype_wchar *this,
2392         short mask, const wchar_t *first, const wchar_t *last)
2393 {
2394     TRACE("(%p %d %p %p)\n", this, mask, first, last);
2395     for(; first<last; first++)
2396         if(!ctype_wchar_is_ch(this, mask, *first))
2397             break;
2398     return first;
2399 }
2400
2401 /* ?scan_is@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2402 /* ?scan_is@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2403 /* ?scan_is@?$ctype@G@std@@QBEPBGFPBG0@Z */
2404 /* ?scan_is@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2405 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_is, 16)
2406 const wchar_t* __thiscall ctype_wchar_scan_is(const ctype_wchar *this,
2407         short mask, const wchar_t *first, const wchar_t *last)
2408 {
2409     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2410     return call_ctype_wchar_do_scan_is(this, mask, first, last);
2411 }
2412
2413 /* ?do_scan_not@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2414 /* ?do_scan_not@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2415 /* ?do_scan_not@?$ctype@G@std@@MBEPBGFPBG0@Z */
2416 /* ?do_scan_not@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2417 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_not, 16)
2418 #define call_ctype_wchar_do_scan_not(this, mask, first, last) CALL_VTBL_FUNC(this, 16, \
2419         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2420         (this, mask, first, last))
2421 const wchar_t* __thiscall ctype_wchar_do_scan_not(const ctype_wchar *this,
2422         short mask, const wchar_t *first, const wchar_t *last)
2423 {
2424     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2425     for(; first<last; first++)
2426         if(ctype_wchar_is_ch(this, mask, *first))
2427             break;
2428     return first;
2429 }
2430
2431 /* ?scan_not@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2432 /* ?scan_not@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2433 /* ?scan_not@?$ctype@G@std@@QBEPBGFPBG0@Z */
2434 /* ?scan_not@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2435 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_not, 16)
2436 const wchar_t* __thiscall ctype_wchar_scan_not(const ctype_wchar *this,
2437         short mask, const wchar_t *first, const wchar_t *last)
2438 {
2439     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2440     return call_ctype_wchar_do_scan_not(this, mask, first, last);
2441 }
2442
2443 /* ?id@?$numpunct@D@std@@2V0locale@2@A */
2444 locale_id numpunct_char_id = {0};
2445
2446 /* ??_7?$numpunct@D@std@@6B@ */
2447 extern const vtable_ptr MSVCP_numpunct_char_vtable;
2448
2449 /* ?_Init@?$numpunct@D@std@@IAEXABV_Locinfo@2@_N@Z */
2450 /* ?_Init@?$numpunct@D@std@@IEAAXAEBV_Locinfo@2@_N@Z */
2451 DEFINE_THISCALL_WRAPPER(numpunct_char__Init, 12)
2452 void __thiscall numpunct_char__Init(numpunct_char *this, _Locinfo *locinfo, MSVCP_bool isdef)
2453 {
2454     const struct lconv *lc = _Locinfo__Getlconv(locinfo);
2455     int len;
2456
2457     TRACE("(%p %p %d)\n", this, locinfo, isdef);
2458
2459     len = strlen(_Locinfo__Getfalse(locinfo))+1;
2460     this->false_name = MSVCRT_operator_new(len);
2461     if(this->false_name)
2462         memcpy((char*)this->false_name, _Locinfo__Getfalse(locinfo), len);
2463
2464     len = strlen(_Locinfo__Gettrue(locinfo))+1;
2465     this->true_name = MSVCRT_operator_new(len);
2466     if(this->true_name)
2467         memcpy((char*)this->true_name, _Locinfo__Gettrue(locinfo), len);
2468
2469     if(isdef) {
2470         this->grouping = MSVCRT_operator_new(1);
2471         if(this->grouping)
2472             *(char*)this->grouping = 0;
2473
2474         this->dp = '.';
2475         this->sep = ',';
2476     } else {
2477         len = strlen(lc->grouping)+1;
2478         this->grouping = MSVCRT_operator_new(len);
2479         if(this->grouping)
2480             memcpy((char*)this->grouping, lc->grouping, len);
2481
2482         this->dp = lc->decimal_point[0];
2483         this->sep = lc->thousands_sep[0];
2484     }
2485
2486     if(!this->false_name || !this->true_name || !this->grouping) {
2487         MSVCRT_operator_delete((char*)this->grouping);
2488         MSVCRT_operator_delete((char*)this->false_name);
2489         MSVCRT_operator_delete((char*)this->true_name);
2490
2491         ERR("Out of memory\n");
2492         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2493     }
2494 }
2495
2496 /* ?_Tidy@?$numpunct@D@std@@AAEXXZ */
2497 /* ?_Tidy@?$numpunct@D@std@@AEAAXXZ */
2498 DEFINE_THISCALL_WRAPPER(numpunct_char__Tidy, 4)
2499 void __thiscall numpunct_char__Tidy(numpunct_char *this)
2500 {
2501     TRACE("(%p)\n", this);
2502
2503     MSVCRT_operator_delete((char*)this->grouping);
2504     MSVCRT_operator_delete((char*)this->false_name);
2505     MSVCRT_operator_delete((char*)this->true_name);
2506 }
2507
2508 /* ??0?$numpunct@D@std@@QAE@ABV_Locinfo@1@I_N@Z */
2509 /* ??0?$numpunct@D@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
2510 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_locinfo, 16)
2511 numpunct_char* __thiscall numpunct_char_ctor_locinfo(numpunct_char *this,
2512         _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
2513 {
2514     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
2515     locale_facet_ctor_refs(&this->facet, refs);
2516     this->facet.vtable = &MSVCP_numpunct_char_vtable;
2517     numpunct_char__Init(this, locinfo, usedef);
2518     return this;
2519 }
2520
2521 /* ??0?$numpunct@D@std@@IAE@PBDI_N@Z */
2522 /* ??0?$numpunct@D@std@@IEAA@PEBD_K_N@Z */
2523 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_name, 16)
2524 numpunct_char* __thiscall numpunct_char_ctor_name(numpunct_char *this,
2525         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
2526 {
2527     _Locinfo locinfo;
2528
2529     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
2530     locale_facet_ctor_refs(&this->facet, refs);
2531     this->facet.vtable = &MSVCP_numpunct_char_vtable;
2532
2533     _Locinfo_ctor_cstr(&locinfo, name);
2534     numpunct_char__Init(this, &locinfo, usedef);
2535     _Locinfo_dtor(&locinfo);
2536     return this;
2537 }
2538
2539 /* ??0?$numpunct@D@std@@QAE@I@Z */
2540 /* ??0?$numpunct@D@std@@QEAA@_K@Z */
2541 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_refs, 8)
2542 numpunct_char* __thiscall numpunct_char_ctor_refs(numpunct_char *this, MSVCP_size_t refs)
2543 {
2544     TRACE("(%p %lu)\n", this, refs);
2545     return numpunct_char_ctor_name(this, "C", refs, FALSE);
2546 }
2547
2548 /* ??_F?$numpunct@D@std@@QAEXXZ */
2549 /* ??_F?$numpunct@D@std@@QEAAXXZ */
2550 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor, 4)
2551 numpunct_char* __thiscall numpunct_char_ctor(numpunct_char *this)
2552 {
2553     return numpunct_char_ctor_refs(this, 0);
2554 }
2555
2556 /* ??1?$numpunct@D@std@@MAE@XZ */
2557 /* ??1?$numpunct@D@std@@MEAA@XZ */
2558 DEFINE_THISCALL_WRAPPER(numpunct_char_dtor, 4)
2559 void __thiscall numpunct_char_dtor(numpunct_char *this)
2560 {
2561     TRACE("(%p)\n", this);
2562     numpunct_char__Tidy(this);
2563 }
2564
2565 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_char_vector_dtor, 8)
2566 numpunct_char* __thiscall MSVCP_numpunct_char_vector_dtor(numpunct_char *this, unsigned int flags)
2567 {
2568     TRACE("(%p %x)\n", this, flags);
2569     if(flags & 2) {
2570         /* we have an array, with the number of elements stored before the first object */
2571         int i, *ptr = (int *)this-1;
2572
2573         for(i=*ptr-1; i>=0; i--)
2574             numpunct_char_dtor(this+i);
2575         MSVCRT_operator_delete(ptr);
2576     } else {
2577         numpunct_char_dtor(this);
2578         if(flags & 1)
2579             MSVCRT_operator_delete(this);
2580     }
2581
2582     return this;
2583 }
2584
2585 /* ?_Getcat@?$numpunct@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2586 /* ?_Getcat@?$numpunct@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2587 MSVCP_size_t __cdecl numpunct_char__Getcat(const locale_facet **facet, const locale *loc)
2588 {
2589     TRACE("(%p %p)\n", facet, loc);
2590
2591     if(facet && !*facet) {
2592         *facet = MSVCRT_operator_new(sizeof(numpunct_char));
2593         if(!*facet) {
2594             ERR("Out of memory\n");
2595             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2596             return 0;
2597         }
2598         numpunct_char_ctor_name((numpunct_char*)*facet,
2599                 MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
2600     }
2601
2602     return LC_NUMERIC;
2603 }
2604
2605 /* ?do_decimal_point@?$numpunct@D@std@@MBEDXZ */
2606 /* ?do_decimal_point@?$numpunct@D@std@@MEBADXZ */
2607 DEFINE_THISCALL_WRAPPER(numpunct_char_do_decimal_point, 4)
2608 #define call_numpunct_char_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
2609         char, (const numpunct_char *this), (this))
2610 char __thiscall numpunct_char_do_decimal_point(const numpunct_char *this)
2611 {
2612     TRACE("(%p)\n", this);
2613     return this->dp;
2614 }
2615
2616 /* ?decimal_point@?$numpunct@D@std@@QBEDXZ */
2617 /* ?decimal_point@?$numpunct@D@std@@QEBADXZ */
2618 DEFINE_THISCALL_WRAPPER(numpunct_char_decimal_point, 4)
2619 char __thiscall numpunct_char_decimal_point(const numpunct_char *this)
2620 {
2621     TRACE("(%p)\n", this);
2622     return call_numpunct_char_do_decimal_point(this);
2623 }
2624
2625 /* ?do_thousands_sep@?$numpunct@D@std@@MBEDXZ */
2626 /* ?do_thousands_sep@?$numpunct@D@std@@MEBADXZ */
2627 DEFINE_THISCALL_WRAPPER(numpunct_char_do_thousands_sep, 4)
2628 #define call_numpunct_char_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
2629         char, (const numpunct_char*), (this))
2630 char __thiscall numpunct_char_do_thousands_sep(const numpunct_char *this)
2631 {
2632     TRACE("(%p)\n", this);
2633     return this->sep;
2634 }
2635
2636 /* ?thousands_sep@?$numpunct@D@std@@QBEDXZ */
2637 /* ?thousands_sep@?$numpunct@D@std@@QEBADXZ */
2638 DEFINE_THISCALL_WRAPPER(numpunct_char_thousands_sep, 4)
2639 char __thiscall numpunct_char_thousands_sep(const numpunct_char *this)
2640 {
2641     TRACE("(%p)\n", this);
2642     return call_numpunct_char_do_thousands_sep(this);
2643 }
2644
2645 /* ?do_grouping@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2646 /* ?do_grouping@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2647 DEFINE_THISCALL_WRAPPER(numpunct_char_do_grouping, 8)
2648 #define call_numpunct_char_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
2649         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
2650 basic_string_char* __thiscall numpunct_char_do_grouping(
2651         const numpunct_char *this, basic_string_char *ret)
2652 {
2653     TRACE("(%p)\n", this);
2654     return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping);
2655 }
2656
2657 /* ?grouping@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2658 /* ?grouping@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2659 DEFINE_THISCALL_WRAPPER(numpunct_char_grouping, 8)
2660 basic_string_char* __thiscall numpunct_char_grouping(const numpunct_char *this, basic_string_char *ret)
2661 {
2662     TRACE("(%p)\n", this);
2663     return call_numpunct_char_do_grouping(this, ret);
2664 }
2665
2666 /* ?do_falsename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2667 /* ?do_falsename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2668 DEFINE_THISCALL_WRAPPER(numpunct_char_do_falsename, 8)
2669 #define call_numpunct_char_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
2670         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
2671 basic_string_char* __thiscall numpunct_char_do_falsename(
2672         const numpunct_char *this, basic_string_char *ret)
2673 {
2674     TRACE("(%p)\n", this);
2675     return MSVCP_basic_string_char_ctor_cstr(ret, this->false_name);
2676 }
2677
2678 /* ?falsename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2679 /* ?falsename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2680 DEFINE_THISCALL_WRAPPER(numpunct_char_falsename, 8)
2681 basic_string_char* __thiscall numpunct_char_falsename(const numpunct_char *this, basic_string_char *ret)
2682 {
2683     TRACE("(%p)\n", this);
2684     return call_numpunct_char_do_falsename(this, ret);
2685 }
2686
2687 /* ?do_truename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2688 /* ?do_truename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2689 DEFINE_THISCALL_WRAPPER(numpunct_char_do_truename, 8)
2690 #define call_numpunct_char_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
2691         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
2692 basic_string_char* __thiscall numpunct_char_do_truename(
2693         const numpunct_char *this, basic_string_char *ret)
2694 {
2695     TRACE("(%p)\n", this);
2696     return MSVCP_basic_string_char_ctor_cstr(ret, this->true_name);
2697 }
2698
2699 /* ?truename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2700 /* ?truename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2701 DEFINE_THISCALL_WRAPPER(numpunct_char_truename, 8)
2702 basic_string_char* __thiscall numpunct_char_truename(const numpunct_char *this, basic_string_char *ret)
2703 {
2704     TRACE("(%p)\n", this);
2705     return call_numpunct_char_do_truename(this, ret);
2706 }
2707
2708 /* ?id@?$numpunct@_W@std@@2V0locale@2@A */
2709 locale_id numpunct_wchar_id = {0};
2710 /* ?id@?$numpunct@G@std@@2V0locale@2@A */
2711 locale_id numpunct_short_id = {0};
2712
2713 /* ??_7?$numpunct@_W@std@@6B@ */
2714 extern const vtable_ptr MSVCP_numpunct_wchar_vtable;
2715 /* ??_7?$numpunct@G@std@@6B@ */
2716 extern const vtable_ptr MSVCP_numpunct_short_vtable;
2717
2718 /* ?_Init@?$numpunct@_W@std@@IAEXABV_Locinfo@2@_N@Z */
2719 /* ?_Init@?$numpunct@_W@std@@IEAAXAEBV_Locinfo@2@_N@Z */
2720 /* ?_Init@?$numpunct@G@std@@IAEXABV_Locinfo@2@_N@Z */
2721 /* ?_Init@?$numpunct@G@std@@IEAAXAEBV_Locinfo@2@_N@Z */
2722 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Init, 12)
2723 void __thiscall numpunct_wchar__Init(numpunct_wchar *this, _Locinfo *locinfo, MSVCP_bool isdef)
2724 {
2725     FIXME("(%p %p %d) stub\n", this, locinfo, isdef);
2726 }
2727
2728 /* ?_Tidy@?$numpunct@_W@std@@AAEXXZ */
2729 /* ?_Tidy@?$numpunct@_W@std@@AEAAXXZ */
2730 /* ?_Tidy@?$numpunct@G@std@@AAEXXZ */
2731 /* ?_Tidy@?$numpunct@G@std@@AEAAXXZ */
2732 DEFINE_THISCALL_WRAPPER(numpunct_wchar__Tidy, 4)
2733 void __thiscall numpunct_wchar__Tidy(numpunct_wchar *this)
2734 {
2735     FIXME("(%p) stub\n", this);
2736 }
2737
2738 /* ??0?$numpunct@_W@std@@QAE@ABV_Locinfo@1@I_N@Z */
2739 /* ??0?$numpunct@_W@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
2740 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_locinfo, 16)
2741 numpunct_wchar* __thiscall numpunct_wchar_ctor_locinfo(numpunct_wchar *this,
2742         _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
2743 {
2744     FIXME("(%p %p %lu %d) stub\n", this, locinfo, refs, usedef);
2745     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
2746     return NULL;
2747 }
2748
2749 /* ??0?$numpunct@G@std@@QAE@ABV_Locinfo@1@I_N@Z */
2750 /* ??0?$numpunct@G@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
2751 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_locinfo, 16)
2752 numpunct_wchar* __thiscall numpunct_short_ctor_locinfo(numpunct_wchar *this,
2753         _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
2754 {
2755     numpunct_wchar_ctor_locinfo(this, locinfo, refs, usedef);
2756     this->facet.vtable = &MSVCP_numpunct_short_vtable;
2757     return this;
2758 }
2759
2760 /* ??0?$numpunct@_W@std@@IAE@PBDI_N@Z */
2761 /* ??0?$numpunct@_W@std@@IEAA@PEBD_K_N@Z */
2762 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_name, 16)
2763 numpunct_wchar* __thiscall numpunct_wchar_ctor_name(numpunct_wchar *this,
2764         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
2765 {
2766     FIXME("(%p %s %lu %d) stub\n", this, debugstr_a(name), refs, usedef);
2767     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
2768     return NULL;
2769 }
2770
2771 /* ??0?$numpunct@G@std@@IAE@PBDI_N@Z */
2772 /* ??0?$numpunct@G@std@@IEAA@PEBD_K_N@Z */
2773 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_name, 16)
2774 numpunct_wchar* __thiscall numpunct_short_ctor_name(numpunct_wchar *this,
2775         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
2776 {
2777     numpunct_wchar_ctor_name(this, name, refs, usedef);
2778     this->facet.vtable = &MSVCP_numpunct_short_vtable;
2779     return this;
2780 }
2781
2782 /* ??0?$numpunct@_W@std@@QAE@I@Z */
2783 /* ??0?$numpunct@_W@std@@QEAA@_K@Z */
2784 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_refs, 8)
2785 numpunct_wchar* __thiscall numpunct_wchar_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
2786 {
2787     FIXME("(%p %lu) stub\n", this, refs);
2788     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
2789     return NULL;
2790 }
2791
2792 /* ??0?$numpunct@G@std@@QAE@I@Z */
2793 /* ??0?$numpunct@G@std@@QEAA@_K@Z */
2794 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_refs, 8)
2795 numpunct_wchar* __thiscall numpunct_short_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
2796 {
2797     numpunct_wchar_ctor_refs(this, refs);
2798     this->facet.vtable = &MSVCP_numpunct_short_vtable;
2799     return this;
2800 }
2801
2802 /* ??_F?$numpunct@_W@std@@QAEXXZ */
2803 /* ??_F?$numpunct@_W@std@@QEAAXXZ */
2804 DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor, 4)
2805 numpunct_wchar* __thiscall numpunct_wchar_ctor(numpunct_wchar *this)
2806 {
2807     return numpunct_wchar_ctor_refs(this, 0);
2808 }
2809
2810 /* ??_F?$numpunct@G@std@@QAEXXZ */
2811 /* ??_F?$numpunct@G@std@@QEAAXXZ */
2812 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor, 4)
2813 numpunct_wchar* __thiscall numpunct_short_ctor(numpunct_wchar *this)
2814 {
2815     return numpunct_short_ctor_refs(this, 0);
2816 }
2817
2818 /* ??1?$numpunct@_W@std@@MAE@XZ */
2819 /* ??1?$numpunct@_W@std@@MEAA@XZ */
2820 /* ??1?$numpunct@G@std@@MAE@XZ */
2821 /* ??1?$numpunct@G@std@@MEAA@XZ */
2822 DEFINE_THISCALL_WRAPPER(numpunct_wchar_dtor, 4)
2823 void __thiscall numpunct_wchar_dtor(numpunct_wchar *this)
2824 {
2825     FIXME("(%p) stub\n", this);
2826 }
2827
2828 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_wchar_vector_dtor, 8)
2829 numpunct_wchar* __thiscall MSVCP_numpunct_wchar_vector_dtor(numpunct_wchar *this, unsigned int flags)
2830 {
2831     TRACE("(%p %x)\n", this, flags);
2832     if(flags & 2) {
2833         /* we have an array, with the number of elements stored before the first object */
2834         int i, *ptr = (int *)this-1;
2835
2836         for(i=*ptr-1; i>=0; i--)
2837             numpunct_wchar_dtor(this+i);
2838         MSVCRT_operator_delete(ptr);
2839     } else {
2840         numpunct_wchar_dtor(this);
2841         if(flags & 1)
2842             MSVCRT_operator_delete(this);
2843     }
2844
2845     return this;
2846 }
2847
2848 DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_short_vector_dtor, 8)
2849 numpunct_wchar* __thiscall MSVCP_numpunct_short_vector_dtor(numpunct_wchar *this, unsigned int flags)
2850 {
2851     return MSVCP_numpunct_wchar_vector_dtor(this, flags);
2852 }
2853
2854 /* ?_Getcat@?$numpunct@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2855 /* ?_Getcat@?$numpunct@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2856 MSVCP_size_t __cdecl numpunct_wchar__Getcat(const locale_facet **facet, const locale *loc)
2857 {
2858     FIXME("(%p %p) stub\n", facet, loc);
2859     return 0;
2860 }
2861
2862 /* ?_Getcat@?$numpunct@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2863 /* ?_Getcat@?$numpunct@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2864 MSVCP_size_t __cdecl numpunct_short__Getcat(const locale_facet **facet, const locale *loc)
2865 {
2866     FIXME("(%p %p) stub\n", facet, loc);
2867     return 0;
2868 }
2869
2870 /* ?do_decimal_point@?$numpunct@_W@std@@MBE_WXZ */
2871 /* ?do_decimal_point@?$numpunct@_W@std@@MEBA_WXZ */
2872 /* ?do_decimal_point@?$numpunct@G@std@@MBEGXZ */
2873 /* ?do_decimal_point@?$numpunct@G@std@@MEBAGXZ */
2874 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_decimal_point, 4)
2875 wchar_t __thiscall numpunct_wchar_do_decimal_point(const numpunct_wchar *this)
2876 {
2877     FIXME("(%p) stub\n", this);
2878     return 0;
2879 }
2880
2881 /* ?decimal_point@?$numpunct@_W@std@@QBE_WXZ */
2882 /* ?decimal_point@?$numpunct@_W@std@@QEBA_WXZ */
2883 /* ?decimal_point@?$numpunct@G@std@@QBEGXZ */
2884 /* ?decimal_point@?$numpunct@G@std@@QEBAGXZ */
2885 DEFINE_THISCALL_WRAPPER(numpunct_wchar_decimal_point, 4)
2886 wchar_t __thiscall numpunct_wchar_decimal_point(const numpunct_wchar *this)
2887 {
2888     FIXME("(%p) stub\n", this);
2889     return 0;
2890 }
2891
2892 /* ?do_thousands_sep@?$numpunct@_W@std@@MBE_WXZ */
2893 /* ?do_thousands_sep@?$numpunct@_W@std@@MEBA_WXZ */
2894 /* ?do_thousands_sep@?$numpunct@G@std@@MBEGXZ */
2895 /* ?do_thousands_sep@?$numpunct@G@std@@MEBAGXZ */
2896 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_thousands_sep, 4)
2897 wchar_t __thiscall numpunct_wchar_do_thousands_sep(const numpunct_wchar *this)
2898 {
2899     FIXME("(%p) stub\n", this);
2900     return 0;
2901 }
2902
2903 /* ?thousands_sep@?$numpunct@_W@std@@QBE_WXZ */
2904 /* ?thousands_sep@?$numpunct@_W@std@@QEBA_WXZ */
2905 /* ?thousands_sep@?$numpunct@G@std@@QBEGXZ */
2906 /* ?thousands_sep@?$numpunct@G@std@@QEBAGXZ */
2907 DEFINE_THISCALL_WRAPPER(numpunct_wchar_thousands_sep, 4)
2908 wchar_t __thiscall numpunct_wchar_thousands_sep(const numpunct_wchar *this)
2909 {
2910     FIXME("(%p) stub\n", this);
2911     return 0;
2912 }
2913
2914 /* ?do_grouping@?$numpunct@_W@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2915 /* ?do_grouping@?$numpunct@_W@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2916 /* ?do_grouping@?$numpunct@G@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2917 /* ?do_grouping@?$numpunct@G@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2918 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_grouping, 8)
2919 basic_string_char* __thiscall numpunct_wchar_do_grouping(const numpunct_wchar *this, basic_string_char *ret)
2920 {
2921     FIXME("(%p) stub\n", this);
2922     return ret;
2923 }
2924
2925 /* ?grouping@?$numpunct@_W@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2926 /* ?grouping@?$numpunct@_W@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2927 /* ?grouping@?$numpunct@G@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2928 /* ?grouping@?$numpunct@G@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
2929 DEFINE_THISCALL_WRAPPER(numpunct_wchar_grouping, 8)
2930 basic_string_char* __thiscall numpunct_wchar_grouping(const numpunct_wchar *this, basic_string_char *ret)
2931 {
2932     FIXME("(%p) stub\n", this);
2933     return ret;
2934 }
2935
2936 /* ?do_falsename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2937 /* ?do_falsename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2938 /* ?do_falsename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2939 /* ?do_falsename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2940 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_falsename, 8)
2941 basic_string_wchar* __thiscall numpunct_wchar_do_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
2942 {
2943     FIXME("(%p) stub\n", this);
2944     return ret;
2945 }
2946
2947 /* ?falsename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2948 /* ?falsename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2949 /* ?falsename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2950 /* ?falsename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2951 DEFINE_THISCALL_WRAPPER(numpunct_wchar_falsename, 8)
2952 basic_string_wchar* __thiscall numpunct_wchar_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
2953 {
2954     FIXME("(%p) stub\n", this);
2955     return ret;
2956 }
2957
2958 /* ?do_truename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2959 /* ?do_truename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2960 /* ?do_truename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2961 /* ?do_truename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2962 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_truename, 8)
2963 basic_string_wchar* __thiscall numpunct_wchar_do_truename(const numpunct_wchar *this, basic_string_wchar *ret)
2964 {
2965     FIXME("(%p) stub\n", this);
2966     return ret;
2967 }
2968
2969 /* ?truename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2970 /* ?truename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2971 /* ?truename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2972 /* ?truename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
2973 DEFINE_THISCALL_WRAPPER(numpunct_wchar_truename, 8)
2974 basic_string_wchar* __thiscall numpunct_wchar_truename(const numpunct_wchar *this, basic_string_wchar *ret)
2975 {
2976     FIXME("(%p) stub\n", this);
2977     return ret;
2978 }
2979
2980 /* ?id@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
2981 locale_id num_get_wchar_id = {0};
2982
2983 /* ??_7?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
2984 extern const vtable_ptr MSVCP_num_get_wchar_vtable;
2985
2986 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
2987 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
2988 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor__Init, 8)
2989 void __thiscall num_get_wchar_ctor__Init(num_get_wchar *this, const _Locinfo *locinfo)
2990 {
2991     FIXME("(%p %p) stub\n", this, locinfo);
2992 }
2993
2994 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
2995 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2996 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_locinfo, 12)
2997 num_get_wchar* __thiscall num_get_wchar_ctor_locinfo(num_get_wchar *this,
2998         _Locinfo *locinfo, MSVCP_size_t refs)
2999 {
3000     FIXME("(%p %p %lu) stub\n", this, locinfo, refs);
3001     return NULL;
3002 }
3003
3004 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
3005 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
3006 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor_refs, 8)
3007 num_get_wchar* __thiscall num_get_wchar_ctor_refs(num_get_wchar *this, MSVCP_size_t refs)
3008 {
3009     FIXME("(%p %lu) stub\n", this, refs);
3010     return NULL;
3011 }
3012
3013 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
3014 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
3015 DEFINE_THISCALL_WRAPPER(num_get_wchar_ctor, 4)
3016 num_get_wchar* __thiscall num_get_wchar_ctor(num_get_wchar *this)
3017 {
3018     FIXME("(%p) stub\n", this);
3019     return NULL;
3020 }
3021
3022 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
3023 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
3024 DEFINE_THISCALL_WRAPPER(num_get_wchar_dtor, 4)
3025 void __thiscall num_get_wchar_dtor(num_get_wchar *this)
3026 {
3027     FIXME("(%p) stub\n", this);
3028 }
3029
3030 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_wchar_vector_dtor, 8)
3031 num_get_wchar* __thiscall MSVCP_num_get_wchar_vector_dtor(num_get_wchar *this, unsigned int flags)
3032 {
3033     TRACE("(%p %x)\n", this, flags);
3034     if(flags & 2) {
3035         /* we have an array, with the number of elements stored before the first object */
3036         int i, *ptr = (int *)this-1;
3037
3038         for(i=*ptr-1; i>=0; i--)
3039             num_get_wchar_dtor(this+i);
3040         MSVCRT_operator_delete(ptr);
3041     } else {
3042         num_get_wchar_dtor(this);
3043         if(flags & 1)
3044             MSVCRT_operator_delete(this);
3045     }
3046
3047     return this;
3048 }
3049
3050 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3051 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3052 MSVCP_size_t __cdecl num_get_wchar__Getcat(const locale_facet **facet, const locale *loc)
3053 {
3054     FIXME("(%p %p) stub\n", facet, loc);
3055     return -1;
3056 }
3057
3058 /* ?_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 */
3059 /* ?_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 */
3060 int __cdecl num_get_wchar__Getffld(char *dest, istreambuf_iterator_wchar *first,
3061     istreambuf_iterator_wchar *last, const locale *loc)
3062 {
3063     FIXME("(%p %p %p %p) stub\n", dest, first, last, loc);
3064     return -1;
3065 }
3066
3067 /* ?_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 */
3068 /* ?_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 */
3069 int __cdecl num_get_wchar__Getffldx(char *dest, istreambuf_iterator_wchar *first,
3070     istreambuf_iterator_wchar *last, struct _ios_base *ios, int *phexexp)
3071 {
3072     FIXME("(%p %p %p %p %p) stub\n", dest, first, last, ios, phexexp);
3073     return -1;
3074 }
3075
3076 /* ?_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 */
3077 /* ?_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 */
3078 int __cdecl num_get_wchar__Getifld(char *dest, istreambuf_iterator_wchar *first,
3079     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
3080 {
3081     FIXME("(%p %p %p %04x %p) stub\n", dest, first, last, fmtflags, loc);
3082     return -1;
3083 }
3084
3085 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABEH_W000@Z */
3086 /* ?_Hexdig@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAH_W000@Z */
3087 DEFINE_THISCALL_WRAPPER(MSVCP_num_get_wchar__Hexdig, 20)
3088 int __thiscall MSVCP_num_get_wchar__Hexdig(num_get_wchar *this, wchar_t dig, wchar_t e0, wchar_t al, wchar_t au)
3089 {
3090     FIXME("(%p %c %c %c %c) stub\n", this, dig, e0, al, au);
3091     return -1;
3092 }
3093
3094 /* ?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 */
3095 /* ?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 */
3096 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_void,28)
3097 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_void(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3098     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, void **pval)
3099 {
3100     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3101     return ret;
3102 }
3103
3104 /* ?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 */
3105 /* ?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 */
3106 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_void,28)
3107 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_void(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3108     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, void **pval)
3109 {
3110     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3111     return ret;
3112 }
3113
3114 /* ?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 */
3115 /* ?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 */
3116 /* ?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 */
3117 /* ?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 */
3118 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_double,28)
3119 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_double(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3120     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, double *pval)
3121 {
3122     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3123     return ret;
3124 }
3125
3126 /* ?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 */
3127 /* ?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 */
3128 /* ?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 */
3129 /* ?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 */
3130 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_double,28)
3131 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_double(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3132     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, double *pval)
3133 {
3134     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3135     return ret;
3136 }
3137
3138 /* ?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 */
3139 /* ?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 */
3140 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_float,28)
3141 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_float(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3142     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, float *pval)
3143 {
3144     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3145     return ret;
3146 }
3147
3148 /* ?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 */
3149 /* ?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 */
3150 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_float,28)
3151 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_float(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3152     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, float *pval)
3153 {
3154     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3155     return ret;
3156 }
3157
3158 /* ?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 */
3159 /* ?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 */
3160 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint64,28)
3161 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint64(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3162     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, ULONGLONG *pval)
3163 {
3164     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3165     return ret;
3166 }
3167
3168 /* ?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 */
3169 /* ?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 */
3170 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint64,28)
3171 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint64(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3172     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, ULONGLONG *pval)
3173 {
3174     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3175     return ret;
3176 }
3177
3178 /* ?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 */
3179 /* ?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 */
3180 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_int64,28)
3181 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_int64(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3182     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, LONGLONG *pval)
3183 {
3184     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3185     return ret;
3186 }
3187
3188 /* ?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 */
3189 /* ?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 */
3190 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_int64,28)
3191 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_int64(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3192     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, LONGLONG *pval)
3193 {
3194     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3195     return ret;
3196 }
3197
3198 /* ?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 */
3199 /* ?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 */
3200 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ulong,28)
3201 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ulong(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3202     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, ULONG *pval)
3203 {
3204     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3205     return ret;
3206 }
3207
3208 /* ?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 */
3209 /* ?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 */
3210 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ulong,28)
3211 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ulong(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3212     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, ULONG *pval)
3213 {
3214     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3215     return ret;
3216 }
3217
3218 /* ?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 */
3219 /* ?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 */
3220 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_long,28)
3221 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_long(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3222     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, LONG *pval)
3223 {
3224     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3225     return ret;
3226 }
3227
3228 /* ?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 */
3229 /* ?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 */
3230 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_long,28)
3231 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_long(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3232     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, LONG *pval)
3233 {
3234     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3235     return ret;
3236 }
3237
3238 /* ?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 */
3239 /* ?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 */
3240 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint,28)
3241 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3242     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, unsigned int *pval)
3243 {
3244     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3245     return ret;
3246 }
3247
3248 /* ?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 */
3249 /* ?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 */
3250 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint,28)
3251 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3252     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, unsigned int *pval)
3253 {
3254     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3255     return ret;
3256 }
3257
3258 /* ?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 */
3259 /* ?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 */
3260 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ushort,28)
3261 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ushort(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3262     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, unsigned short *pval)
3263 {
3264     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3265     return ret;
3266 }
3267
3268 /* ?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 */
3269 /* ?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 */
3270 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ushort,28)
3271 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ushort(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3272     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, unsigned short *pval)
3273 {
3274     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3275     return ret;
3276 }
3277
3278 /* ?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 */
3279 /* ?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 */
3280 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_bool,28)
3281 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_bool(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3282     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, MSVCP_bool *pval)
3283 {
3284     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3285     return ret;
3286 }
3287
3288 /* ?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 */
3289 /* ?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 */
3290 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_bool,28)
3291 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_bool(const num_get_wchar *this, istreambuf_iterator_wchar *ret,
3292     istreambuf_iterator_wchar *first, istreambuf_iterator_wchar *last, struct _ios_base *base, int *state, MSVCP_bool *pval)
3293 {
3294     FIXME("(%p %p %p %p %p %p %p) stub\n", this, ret, first, last, base, state, pval);
3295     return ret;
3296 }
3297
3298 /* ??0_Locimp@locale@std@@AAE@_N@Z */
3299 /* ??0_Locimp@locale@std@@AEAA@_N@Z */
3300 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor_transparent, 8)
3301 locale__Locimp* __thiscall locale__Locimp_ctor_transparent(locale__Locimp *this, MSVCP_bool transparent)
3302 {
3303     TRACE("(%p %d)\n", this, transparent);
3304
3305     memset(this, 0, sizeof(locale__Locimp));
3306     locale_facet_ctor_refs(&this->facet, 1);
3307     this->transparent = transparent;
3308     MSVCP_basic_string_char_ctor_cstr(&this->name, "*");
3309     return this;
3310 }
3311
3312 /* ??_F_Locimp@locale@std@@QAEXXZ */
3313 /* ??_F_Locimp@locale@std@@QEAAXXZ */
3314 DEFINE_THISCALL_WRAPPER(locale__Locimp_ctor, 4)
3315 locale__Locimp* __thiscall locale__Locimp_ctor(locale__Locimp *this)
3316 {
3317     return locale__Locimp_ctor_transparent(this, FALSE);
3318 }
3319
3320 /* ??0_Locimp@locale@std@@AAE@ABV012@@Z */
3321 /* ??0_Locimp@locale@std@@AEAA@AEBV012@@Z */
3322 DEFINE_THISCALL_WRAPPER(locale__Locimp_copy_ctor, 8)
3323 locale__Locimp* __thiscall locale__Locimp_copy_ctor(locale__Locimp *this, const locale__Locimp *copy)
3324 {
3325     _Lockit lock;
3326     MSVCP_size_t i;
3327
3328     TRACE("(%p %p)\n", this, copy);
3329
3330     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3331     memcpy(this, copy, sizeof(locale__Locimp));
3332     locale_facet_ctor_refs(&this->facet, 1);
3333     if(copy->facetvec) {
3334         this->facetvec = MSVCRT_operator_new(copy->facet_cnt*sizeof(locale_facet*));
3335         if(!this->facetvec) {
3336             _Lockit_dtor(&lock);
3337             ERR("Out of memory\n");
3338             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3339             return NULL;
3340         }
3341         for(i=0; i<this->facet_cnt; i++)
3342             if(this->facetvec[i])
3343                 locale_facet__Incref(this->facetvec[i]);
3344     }
3345     MSVCP_basic_string_char_copy_ctor(&this->name, &copy->name);
3346     _Lockit_dtor(&lock);
3347     return this;
3348 }
3349
3350 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPAV123@ABV123@@Z */
3351 /* ?_Locimp_ctor@_Locimp@locale@std@@CAXPEAV123@AEBV123@@Z */
3352 locale__Locimp* __cdecl locale__Locimp__Locimp_ctor(locale__Locimp *this, const locale__Locimp *copy)
3353 {
3354     return locale__Locimp_copy_ctor(this, copy);
3355 }
3356
3357 /* ??1_Locimp@locale@std@@MAE@XZ */
3358 /* ??1_Locimp@locale@std@@MEAA@XZ */
3359 DEFINE_THISCALL_WRAPPER(locale__Locimp_dtor, 4)
3360 void __thiscall locale__Locimp_dtor(locale__Locimp *this)
3361 {
3362     TRACE("(%p)\n", this);
3363
3364     if(locale_facet__Decref(&this->facet)) {
3365         MSVCP_size_t i;
3366         for(i=0; i<this->facet_cnt; i++)
3367             if(this->facetvec[i] && locale_facet__Decref(this->facetvec[i]))
3368                 call_locale_facet_vector_dtor(this->facetvec[i], 0);
3369
3370         MSVCRT_operator_delete(this->facetvec);
3371         MSVCP_basic_string_char_dtor(&this->name);
3372     }
3373 }
3374
3375 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPAV123@@Z */
3376 /* ?_Locimp_dtor@_Locimp@locale@std@@CAXPEAV123@@Z */
3377 void __cdecl locale__Locimp__Locimp_dtor(locale__Locimp *this)
3378 {
3379     locale__Locimp_dtor(this);
3380 }
3381
3382 DEFINE_THISCALL_WRAPPER(MSVCP_locale__Locimp_vector_dtor, 8)
3383 locale__Locimp* __thiscall MSVCP_locale__Locimp_vector_dtor(locale__Locimp *this, unsigned int flags)
3384 {
3385     TRACE("(%p %x)\n", this, flags);
3386     if(flags & 2) {
3387         /* we have an array, with the number of elements stored before the first object */
3388         int i, *ptr = (int *)this-1;
3389
3390         for(i=*ptr-1; i>=0; i--)
3391             locale__Locimp_dtor(this+i);
3392         MSVCRT_operator_delete(ptr);
3393     } else {
3394         locale__Locimp_dtor(this);
3395         if(flags & 1)
3396             MSVCRT_operator_delete(this);
3397     }
3398
3399     return this;
3400 }
3401
3402 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPAV123@PAVfacet@23@I@Z */
3403 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPEAV123@PEAVfacet@23@_K@Z */
3404 void __cdecl locale__Locimp__Locimp_Addfac(locale__Locimp *locimp, locale_facet *facet, MSVCP_size_t id)
3405 {
3406     _Lockit lock;
3407
3408     TRACE("(%p %p %lu)\n", locimp, facet, id);
3409
3410     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3411     if(id >= locimp->facet_cnt) {
3412         MSVCP_size_t new_size = id+1;
3413         locale_facet **new_facetvec;
3414
3415         if(new_size < locale_id__Id_cnt+1)
3416             new_size = locale_id__Id_cnt+1;
3417
3418         new_facetvec = MSVCRT_operator_new(sizeof(locale_facet*)*new_size);
3419         if(!new_facetvec) {
3420             _Lockit_dtor(&lock);
3421             ERR("Out of memory\n");
3422             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3423             return;
3424         }
3425
3426         memset(new_facetvec, 0, sizeof(locale_facet*)*new_size);
3427         memcpy(new_facetvec, locimp->facetvec, sizeof(locale_facet*)*locimp->facet_cnt);
3428         MSVCRT_operator_delete(locimp->facetvec);
3429         locimp->facetvec = new_facetvec;
3430         locimp->facet_cnt = new_size;
3431     }
3432
3433     if(locimp->facetvec[id] && locale_facet__Decref(locimp->facetvec[id]))
3434         call_locale_facet_vector_dtor(locimp->facetvec[id], 0);
3435
3436     locimp->facetvec[id] = facet;
3437     if(facet)
3438         locale_facet__Incref(facet);
3439     _Lockit_dtor(&lock);
3440 }
3441
3442 /* ?_Addfac@_Locimp@locale@std@@AAEXPAVfacet@23@I@Z */
3443 /* ?_Addfac@_Locimp@locale@std@@AEAAXPEAVfacet@23@_K@Z */
3444 DEFINE_THISCALL_WRAPPER(locale__Locimp__Addfac, 12)
3445 void __thiscall locale__Locimp__Addfac(locale__Locimp *this, locale_facet *facet, MSVCP_size_t id)
3446 {
3447     locale__Locimp__Locimp_Addfac(this, facet, id);
3448 }
3449
3450 /* ?_Clocptr_func@_Locimp@locale@std@@CAAAPAV123@XZ */
3451 /* ?_Clocptr_func@_Locimp@locale@std@@CAAEAPEAV123@XZ */
3452 locale__Locimp** __cdecl locale__Locimp__Clocptr_func(void)
3453 {
3454     FIXME("stub\n");
3455     return NULL;
3456 }
3457
3458 /* ?_Makeloc@_Locimp@locale@std@@CAPAV123@ABV_Locinfo@3@HPAV123@PBV23@@Z */
3459 /* ?_Makeloc@_Locimp@locale@std@@CAPEAV123@AEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
3460 locale__Locimp* __cdecl locale__Locimp__Makeloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
3461 {
3462     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
3463     return NULL;
3464 }
3465
3466 /* ?_Makeushloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
3467 /* ?_Makeushloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
3468 void __cdecl locale__Locimp__Makeushloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
3469 {
3470     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
3471 }
3472
3473 /* ?_Makewloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
3474 /* ?_Makewloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
3475 void __cdecl locale__Locimp__Makewloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
3476 {
3477     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
3478 }
3479
3480 /* ?_Makexloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
3481 /* ?_Makexloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
3482 void __cdecl locale__Locimp__Makexloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
3483 {
3484     FIXME("(%p %d %p %p) stub\n", locinfo, cat, locimp, loc);
3485 }
3486
3487 /* ??_7_Locimp@locale@std@@6B@ */
3488 const vtable_ptr MSVCP_locale__Locimp_vtable[] = {
3489     (vtable_ptr)THISCALL_NAME(MSVCP_locale__Locimp_vector_dtor)
3490 };
3491
3492 /* ??0locale@std@@AAE@PAV_Locimp@01@@Z */
3493 /* ??0locale@std@@AEAA@PEAV_Locimp@01@@Z */
3494 DEFINE_THISCALL_WRAPPER(locale_ctor_locimp, 8)
3495 locale* __thiscall locale_ctor_locimp(locale *this, locale__Locimp *locimp)
3496 {
3497     TRACE("(%p %p)\n", this, locimp);
3498     /* Don't change locimp reference counter */
3499     this->ptr = locimp;
3500     return this;
3501 }
3502
3503 /* ??0locale@std@@QAE@ABV01@0H@Z */
3504 /* ??0locale@std@@QEAA@AEBV01@0H@Z */
3505 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_locale, 16)
3506 locale* __thiscall locale_ctor_locale_locale(locale *this, const locale *loc, const locale *other, category cat)
3507 {
3508     FIXME("(%p %p %p %d) stub\n", this, loc, other, cat);
3509     return NULL;
3510 }
3511
3512 /* ??0locale@std@@QAE@ABV01@@Z */
3513 /* ??0locale@std@@QEAA@AEBV01@@Z */
3514 DEFINE_THISCALL_WRAPPER(locale_copy_ctor, 8)
3515 locale* __thiscall locale_copy_ctor(locale *this, const locale *copy)
3516 {
3517     TRACE("(%p %p)\n", this, copy);
3518     this->ptr = copy->ptr;
3519     locale_facet__Incref(&this->ptr->facet);
3520     return this;
3521 }
3522
3523 /* ??0locale@std@@QAE@ABV01@PBDH@Z */
3524 /* ??0locale@std@@QEAA@AEBV01@PEBDH@Z */
3525 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_cstr, 16)
3526 locale* __thiscall locale_ctor_locale_cstr(locale *this, const locale *loc, const char *locname, category cat)
3527 {
3528     FIXME("(%p %p %s %d) stub\n", this, loc, locname, cat);
3529     return NULL;
3530 }
3531
3532 /* ??0locale@std@@QAE@PBDH@Z */
3533 /* ??0locale@std@@QEAA@PEBDH@Z */
3534 DEFINE_THISCALL_WRAPPER(locale_ctor_cstr, 12)
3535 locale* __thiscall locale_ctor_cstr(locale *this, const char *locname, category cat)
3536 {
3537     FIXME("(%p %s %d) stub\n", this, locname, cat);
3538     return NULL;
3539 }
3540
3541 /* ??0locale@std@@QAE@W4_Uninitialized@1@@Z */
3542 /* ??0locale@std@@QEAA@W4_Uninitialized@1@@Z */
3543 DEFINE_THISCALL_WRAPPER(locale_ctor_uninitialized, 8)
3544 locale* __thiscall locale_ctor_uninitialized(locale *this, int uninitialized)
3545 {
3546     TRACE("(%p)\n", this);
3547     this->ptr = NULL;
3548     return this;
3549 }
3550
3551 /* ??0locale@std@@QAE@XZ */
3552 /* ??0locale@std@@QEAA@XZ */
3553 DEFINE_THISCALL_WRAPPER(locale_ctor, 4)
3554 locale* __thiscall locale_ctor(locale *this)
3555 {
3556     TRACE("(%p)\n", this);
3557     this->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
3558     if(!this->ptr) {
3559         ERR("Out of memory\n");
3560         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3561         return NULL;
3562     }
3563
3564     locale__Locimp_ctor(this->ptr);
3565     return this;
3566 }
3567
3568 /* ??1locale@std@@QAE@XZ */
3569 /* ??1locale@std@@QEAA@XZ */
3570 DEFINE_THISCALL_WRAPPER(locale_dtor, 4)
3571 void __thiscall locale_dtor(locale *this)
3572 {
3573     TRACE("(%p)\n", this);
3574     if(this->ptr)
3575         locale__Locimp_dtor(this->ptr);
3576 }
3577
3578 DEFINE_THISCALL_WRAPPER(MSVCP_locale_vector_dtor, 8)
3579 locale* __thiscall MSVCP_locale_vector_dtor(locale *this, unsigned int flags)
3580 {
3581     TRACE("(%p %x)\n", this, flags);
3582     if(flags & 2) {
3583         /* we have an array, with the number of elements stored before the first object */
3584         int i, *ptr = (int *)this-1;
3585
3586         for(i=*ptr-1; i>=0; i--)
3587             locale_dtor(this+i);
3588         MSVCRT_operator_delete(ptr);
3589     } else {
3590         locale_dtor(this);
3591         if(flags & 1)
3592             MSVCRT_operator_delete(this);
3593     }
3594
3595     return this;
3596 }
3597
3598 /* ??4locale@std@@QAEAAV01@ABV01@@Z */
3599 /* ??4locale@std@@QEAAAEAV01@AEBV01@@Z */
3600 DEFINE_THISCALL_WRAPPER(locale_operator_assign, 8)
3601 locale* __thiscall locale_operator_assign(locale *this, const locale *loc)
3602 {
3603     FIXME("(%p %p) stub\n", this, loc);
3604     return NULL;
3605 }
3606
3607 /* ??8locale@std@@QBE_NABV01@@Z */
3608 /* ??8locale@std@@QEBA_NAEBV01@@Z */
3609 DEFINE_THISCALL_WRAPPER(locale_operator_equal, 8)
3610 MSVCP_bool __thiscall locale_operator_equal(const locale *this, const locale *loc)
3611 {
3612     FIXME("(%p %p) stub\n", this, loc);
3613     return 0;
3614 }
3615
3616 /* ??9locale@std@@QBE_NABV01@@Z */
3617 /* ??9locale@std@@QEBA_NAEBV01@@Z */
3618 DEFINE_THISCALL_WRAPPER(locale_operator_not_equal, 8)
3619 MSVCP_bool __thiscall locale_operator_not_equal(const locale *this, locale const *loc)
3620 {
3621     FIXME("(%p %p) stub\n", this, loc);
3622     return 0;
3623 }
3624
3625 /* ?_Addfac@locale@std@@QAEAAV12@PAVfacet@12@II@Z */
3626 /* ?_Addfac@locale@std@@QEAAAEAV12@PEAVfacet@12@_K1@Z */
3627 DEFINE_THISCALL_WRAPPER(locale__Addfac, 16)
3628 locale* __thiscall locale__Addfac(locale *this, locale_facet *facet, MSVCP_size_t id, MSVCP_size_t catmask)
3629 {
3630     TRACE("(%p %p %lu %lu)\n", this, facet, id, catmask);
3631
3632     if(this->ptr->facet.refs > 1) {
3633         locale__Locimp *new_ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
3634         if(!new_ptr) {
3635             ERR("Out of memory\n");
3636             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3637             return NULL;
3638         }
3639         locale__Locimp_copy_ctor(new_ptr, this->ptr);
3640         locale_facet__Decref(&this->ptr->facet);
3641         this->ptr = new_ptr;
3642     }
3643
3644     locale__Locimp__Addfac(this->ptr, facet, id);
3645
3646     if(catmask) {
3647         MSVCP_basic_string_char_dtor(&this->ptr->name);
3648         MSVCP_basic_string_char_ctor_cstr(&this->ptr->name, "*");
3649     }
3650     return this;
3651 }
3652
3653 /* ?_Getfacet@locale@std@@QBEPBVfacet@12@I@Z */
3654 /* ?_Getfacet@locale@std@@QEBAPEBVfacet@12@_K@Z */
3655 DEFINE_THISCALL_WRAPPER(locale__Getfacet, 8)
3656 const locale_facet* __thiscall locale__Getfacet(const locale *this, MSVCP_size_t id)
3657 {
3658     FIXME("(%p %lu) stub\n", this, id);
3659     return NULL;
3660 }
3661
3662 /* ?_Init@locale@std@@CAPAV_Locimp@12@XZ */
3663 /* ?_Init@locale@std@@CAPEAV_Locimp@12@XZ */
3664 locale__Locimp* __cdecl locale__Init(void)
3665 {
3666     FIXME("stub\n");
3667     return NULL;
3668 }
3669
3670 /* ?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ */
3671 /* ?_Getgloballocale@locale@std@@CAPEAV_Locimp@12@XZ */
3672 locale__Locimp* __cdecl locale__Getgloballocale(void)
3673 {
3674     FIXME("stub\n");
3675     return NULL;
3676 }
3677
3678 /* ?_Setgloballocale@locale@std@@CAXPAX@Z */
3679 /* ?_Setgloballocale@locale@std@@CAXPEAX@Z */
3680 void __cdecl locale__Setgloballocale(void *locimp)
3681 {
3682     FIXME("(%p) stub\n", locimp);
3683 }
3684
3685 /* ?classic@locale@std@@SAABV12@XZ */
3686 /* ?classic@locale@std@@SAAEBV12@XZ */
3687 const locale* __cdecl locale_classic(void)
3688 {
3689     FIXME("stub\n");
3690     return NULL;
3691 }
3692
3693 /* ?name@locale@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3694 /* ?name@locale@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3695 DEFINE_THISCALL_WRAPPER(locale_name, 8)
3696 basic_string_char* __thiscall locale_name(const locale *this, basic_string_char *ret)
3697 {
3698     TRACE( "(%p)\n", this);
3699     MSVCP_basic_string_char_copy_ctor(ret, &this->ptr->name);
3700     return ret;
3701 }
3702
3703 static const rtti_base_descriptor locale_facet_rtti_base_descriptor = {
3704     &locale_facet_type_info,
3705     0,
3706     { 0, -1, 0},
3707     64
3708 };
3709
3710 DEFINE_RTTI_DATA(collate_char, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AV?$collate@D@std@@");
3711 DEFINE_RTTI_DATA(collate_wchar, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AV?$collate@_W@std@@");
3712 DEFINE_RTTI_DATA(collate_short, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AV?$collate@G@std@@");
3713 DEFINE_RTTI_DATA(ctype_base, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AUctype_base@std@@");
3714 DEFINE_RTTI_DATA(ctype_char, 0, 2, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, NULL, ".?AV?$ctype@D@std@@");
3715 DEFINE_RTTI_DATA(ctype_wchar, 0, 2, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, NULL, ".?AV?$ctype@_W@std@@");
3716 DEFINE_RTTI_DATA(ctype_short, 0, 2, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, NULL, ".?AV?$ctype@G@std@@");
3717 DEFINE_RTTI_DATA(numpunct_char, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AV?$numpunct@D@std@@");
3718 DEFINE_RTTI_DATA(numpunct_wchar, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AV?$numpunct@_W@std@@");
3719 DEFINE_RTTI_DATA(numpunct_short, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AV?$numpunct@G@std@@");
3720 DEFINE_RTTI_DATA(num_get_wchar, 0, 1, &locale_facet_rtti_base_descriptor, NULL, NULL, ".?AV?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@");
3721
3722 #ifndef __GNUC__
3723 void __asm_dummy_vtables(void) {
3724 #endif
3725     __ASM_VTABLE(collate_char,
3726             VTABLE_ADD_FUNC(collate_char_do_compare)
3727             VTABLE_ADD_FUNC(collate_char_do_transform)
3728             VTABLE_ADD_FUNC(collate_char_do_hash));
3729     __ASM_VTABLE(collate_wchar,
3730             VTABLE_ADD_FUNC(collate_wchar_do_compare)
3731             VTABLE_ADD_FUNC(collate_wchar_do_transform)
3732             VTABLE_ADD_FUNC(collate_wchar_do_hash));
3733     __ASM_VTABLE(collate_short,
3734             VTABLE_ADD_FUNC(collate_wchar_do_compare)
3735             VTABLE_ADD_FUNC(collate_wchar_do_transform)
3736             VTABLE_ADD_FUNC(collate_wchar_do_hash));
3737     __ASM_VTABLE(ctype_base, "");
3738     __ASM_VTABLE(ctype_char,
3739             VTABLE_ADD_FUNC(ctype_char_do_tolower)
3740             VTABLE_ADD_FUNC(ctype_char_do_tolower_ch)
3741             VTABLE_ADD_FUNC(ctype_char_do_toupper)
3742             VTABLE_ADD_FUNC(ctype_char_do_toupper_ch)
3743             VTABLE_ADD_FUNC(ctype_char_do_widen)
3744             VTABLE_ADD_FUNC(ctype_char_do_widen_ch)
3745             VTABLE_ADD_FUNC(ctype_char__Do_widen_s)
3746             VTABLE_ADD_FUNC(ctype_char_do_narrow)
3747             VTABLE_ADD_FUNC(ctype_char_do_narrow_ch)
3748             VTABLE_ADD_FUNC(ctype_char__Do_narrow_s));
3749     __ASM_VTABLE(ctype_wchar,
3750             VTABLE_ADD_FUNC(ctype_wchar_do_is)
3751             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
3752             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
3753             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
3754             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
3755             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
3756             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
3757             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
3758             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
3759             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
3760             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
3761             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
3762             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
3763             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
3764     __ASM_VTABLE(ctype_short,
3765             VTABLE_ADD_FUNC(ctype_wchar_do_is)
3766             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
3767             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
3768             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
3769             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
3770             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
3771             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
3772             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
3773             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
3774             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
3775             VTABLE_ADD_FUNC(ctype_wchar__Do_widen_s)
3776             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
3777             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch)
3778             VTABLE_ADD_FUNC(ctype_wchar__Do_narrow_s));
3779     __ASM_VTABLE(numpunct_char,
3780             VTABLE_ADD_FUNC(numpunct_char_do_decimal_point)
3781             VTABLE_ADD_FUNC(numpunct_char_do_thousands_sep)
3782             VTABLE_ADD_FUNC(numpunct_char_do_grouping)
3783             VTABLE_ADD_FUNC(numpunct_char_do_falsename)
3784             VTABLE_ADD_FUNC(numpunct_char_do_truename));
3785     __ASM_VTABLE(numpunct_wchar,
3786             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
3787             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
3788             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
3789             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
3790             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
3791     __ASM_VTABLE(numpunct_short,
3792             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
3793             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
3794             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
3795             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
3796             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
3797     __ASM_VTABLE(num_get_wchar,
3798             VTABLE_ADD_FUNC(num_get_wchar_do_get_void)
3799             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
3800             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
3801             VTABLE_ADD_FUNC(num_get_wchar_do_get_float)
3802             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint64)
3803             VTABLE_ADD_FUNC(num_get_wchar_do_get_int64)
3804             VTABLE_ADD_FUNC(num_get_wchar_do_get_long)
3805             VTABLE_ADD_FUNC(num_get_wchar_do_get_ulong)
3806             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint)
3807             VTABLE_ADD_FUNC(num_get_wchar_do_get_ushort)
3808             VTABLE_ADD_FUNC(num_get_wchar_do_get_bool));
3809 #ifndef __GNUC__
3810 }
3811 #endif