imm32: Retrieve the graphics driver module from gdi32.
[wine] / dlls / msvcp60 / tests / ios.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 <stdio.h>
20 #include <locale.h>
21 #include <sys/stat.h>
22
23 #include <windef.h>
24 #include <winbase.h>
25 #include <share.h>
26 #include "wine/test.h"
27
28 #undef __thiscall
29 #ifdef __i386__
30 #define __thiscall __stdcall
31 #else
32 #define __thiscall __cdecl
33 #endif
34
35 typedef unsigned char MSVCP_bool;
36 typedef SIZE_T MSVCP_size_t;
37 typedef SSIZE_T streamoff;
38 typedef SSIZE_T streamsize;
39
40 typedef void (*vtable_ptr)(void);
41
42 /* basic_string<char, char_traits<char>, allocator<char>> */
43 typedef struct
44 {
45     void *allocator;
46     char *ptr;
47     MSVCP_size_t size;
48     MSVCP_size_t res;
49 } basic_string_char;
50
51 typedef struct
52 {
53     void *allocator;
54     wchar_t *ptr;
55     MSVCP_size_t size;
56     MSVCP_size_t res;
57 } basic_string_wchar;
58
59 /* class locale */
60 typedef struct
61 {
62     struct _locale__Locimp *ptr;
63 } locale;
64
65 /* class locale::facet */
66 typedef struct {
67     const vtable_ptr *vtable;
68     MSVCP_size_t refs;
69 } locale_facet;
70
71 /* class codecvt_base */
72 typedef struct {
73     locale_facet facet;
74 } codecvt_base;
75
76 /* class codecvt<char> */
77 typedef struct {
78     codecvt_base base;
79 } codecvt_char;
80
81 typedef struct {
82     LCID handle;
83     unsigned page;
84 } _Cvtvec;
85
86 /* class codecvt<wchar> */
87 typedef struct {
88     codecvt_base base;
89     _Cvtvec cvt;
90 } codecvt_wchar;
91
92 typedef enum {
93     FMTFLAG_skipws      = 0x0001,
94     FMTFLAG_unitbuf     = 0x0002,
95     FMTFLAG_uppercase   = 0x0004,
96     FMTFLAG_showbase    = 0x0008,
97     FMTFLAG_showpoint   = 0x0010,
98     FMTFLAG_showpos     = 0x0020,
99     FMTFLAG_left        = 0x0040,
100     FMTFLAG_right       = 0x0080,
101     FMTFLAG_internal    = 0x0100,
102     FMTFLAG_dec         = 0x0200,
103     FMTFLAG_oct         = 0x0400,
104     FMTFLAG_hex         = 0x0800,
105     FMTFLAG_scientific  = 0x1000,
106     FMTFLAG_fixed       = 0x2000,
107     FMTFLAG_hexfloat    = 0x3000,
108     FMTFLAG_boolalpha   = 0x4000,
109     FMTFLAG_stdio       = 0x8000,
110     FMTFLAG_adjustfield = FMTFLAG_left|FMTFLAG_right|FMTFLAG_internal,
111     FMTFLAG_basefield   = FMTFLAG_dec|FMTFLAG_oct|FMTFLAG_hex,
112     FMTFLAG_floatfield  = FMTFLAG_scientific|FMTFLAG_fixed,
113     FMTFLAG_mask        = 0xffff
114 } IOSB_fmtflags;
115
116 typedef enum {
117     OPENMODE_in         = 0x01,
118     OPENMODE_out        = 0x02,
119     OPENMODE_ate        = 0x04,
120     OPENMODE_app        = 0x08,
121     OPENMODE_trunc      = 0x10,
122     OPENMODE__Nocreate  = 0x40,
123     OPENMODE__Noreplace = 0x80,
124     OPENMODE_binary     = 0x20,
125     OPENMODE_mask       = 0xff
126 } IOSB_openmode;
127
128 typedef enum {
129     SEEKDIR_beg  = 0x0,
130     SEEKDIR_cur  = 0x1,
131     SEEKDIR_end  = 0x2,
132     SEEKDIR_mask = 0x3
133 } IOSB_seekdir;
134
135 typedef enum {
136     IOSTATE_goodbit   = 0x00,
137     IOSTATE_eofbit    = 0x01,
138     IOSTATE_failbit   = 0x02,
139     IOSTATE_badbit    = 0x04,
140     IOSTATE__Hardfail = 0x10,
141     IOSTATE_mask      = 0x17
142 } IOSB_iostate;
143
144 typedef struct _iosarray {
145     struct _iosarray *next;
146     int index;
147     int long_val;
148     void *ptr_val;
149 } IOS_BASE_iosarray;
150
151 typedef enum {
152     EVENT_erase_event,
153     EVENT_imbue_event,
154     EVENT_copyfmt_event
155 } IOS_BASE_event;
156
157 struct _ios_base;
158 typedef void (CDECL *IOS_BASE_event_callback)(IOS_BASE_event, struct _ios_base*, int);
159 typedef struct _fnarray {
160     struct _fnarray *next;
161     int index;
162     IOS_BASE_event_callback event_handler;
163 } IOS_BASE_fnarray;
164
165 /* class ios_base */
166 typedef struct _ios_base {
167     const vtable_ptr *vtable;
168     IOSB_iostate state;
169     IOSB_iostate except;
170     IOSB_fmtflags fmtfl;
171     streamsize prec;
172     streamsize wide;
173     IOS_BASE_iosarray *arr;
174     IOS_BASE_fnarray *calls;
175     locale loc;
176     MSVCP_size_t stdstr;
177 } ios_base;
178
179 /* class basic_streambuf<char> */
180 typedef struct {
181     const vtable_ptr *vtable;
182     char *rbuf;
183     char *wbuf;
184     char **prbuf;
185     char **pwbuf;
186     char *rpos;
187     char *wpos;
188     char **prpos;
189     char **pwpos;
190     int rsize;
191     int wsize;
192     int *prsize;
193     int *pwsize;
194     locale loc;
195 } basic_streambuf_char;
196
197 /* class basic_streambuf<wchar> */
198 typedef struct {
199     const vtable_ptr *vtable;
200     wchar_t *rbuf;
201     wchar_t *wbuf;
202     wchar_t **prbuf;
203     wchar_t **pwbuf;
204     wchar_t *rpos;
205     wchar_t *wpos;
206     wchar_t **prpos;
207     wchar_t **pwpos;
208     int rsize;
209     int wsize;
210     int *prsize;
211     int *pwsize;
212     locale loc;
213 } basic_streambuf_wchar;
214
215 typedef struct {
216     basic_streambuf_char base;
217     codecvt_char *cvt;
218     int state0;
219     int state;
220     basic_string_char *str;
221     MSVCP_bool close;
222     locale loc;
223     FILE *file;
224 } basic_filebuf_char;
225
226 typedef struct {
227     basic_streambuf_wchar base;
228     codecvt_wchar *cvt;
229     int state0;
230     int state;
231     basic_string_char *str;
232     MSVCP_bool close;
233     locale loc;
234     FILE *file;
235 } basic_filebuf_wchar;
236
237 typedef struct {
238     basic_streambuf_char base;
239     char *pendsave;
240     char *seekhigh;
241     int alsize;
242     int state;
243     char allocator; /* empty struct */
244 } basic_stringbuf_char;
245
246 typedef struct {
247     basic_streambuf_wchar base;
248     wchar_t *pendsave;
249     wchar_t *seekhigh;
250     int alsize;
251     int state;
252     char allocator; /* empty struct */
253 } basic_stringbuf_wchar;
254
255 typedef struct {
256     ios_base base;
257     basic_streambuf_char *strbuf;
258     struct _basic_ostream_char *stream;
259     char fillch;
260 } basic_ios_char;
261
262 typedef struct {
263     ios_base base;
264     basic_streambuf_wchar *strbuf;
265     struct _basic_ostream_wchar *stream;
266     wchar_t fillch;
267 } basic_ios_wchar;
268
269 typedef struct _basic_ostream_char {
270     const int *vbtable;
271     /* virtual inheritance
272      * basic_ios_char basic_ios;
273      */
274 } basic_ostream_char;
275
276 typedef struct _basic_ostream_wchar {
277     const int *vbtable;
278     /* virtual inheritance
279      * basic_ios_wchar basic_ios;
280      */
281 } basic_ostream_wchar;
282
283 typedef struct {
284     const int *vbtable;
285     streamsize count;
286     /* virtual inheritance
287      * basic_ios_char basic_ios;
288      */
289 } basic_istream_char;
290
291 typedef struct {
292     const int *vbtable;
293     streamsize count;
294     /* virtual inheritance
295      * basic_ios_wchar basic_ios;
296      */
297 } basic_istream_wchar;
298
299 typedef struct {
300     basic_istream_char base1;
301     basic_ostream_char base2;
302     /* virtual inheritance
303      * basic_ios_char basic_ios;
304      */
305 } basic_iostream_char;
306
307 typedef struct {
308     basic_istream_wchar base1;
309     basic_ostream_wchar base2;
310     /* virtual inheritance
311      * basic_ios_wchar basic_ios;
312      */
313 } basic_iostream_wchar;
314
315 typedef struct {
316     basic_ostream_char base;
317     basic_filebuf_char filebuf;
318     /* virtual inheritance
319      * basic_ios_char basic_ios;
320      */
321 } basic_ofstream_char;
322
323 typedef struct {
324     basic_ostream_wchar base;
325     basic_filebuf_wchar filebuf;
326     /* virtual inheritance
327      * basic_ios_wchar basic_ios;
328      */
329 } basic_ofstream_wchar;
330
331 typedef struct {
332     basic_istream_char base;
333     basic_filebuf_char filebuf;
334     /* virtual inheritance
335      * basic_ios_char basic_ios;
336      */
337 } basic_ifstream_char;
338
339 typedef struct {
340     basic_istream_wchar base;
341     basic_filebuf_wchar filebuf;
342     /* virtual inheritance
343      * basic_ios_wchar basic_ios;
344      */
345 } basic_ifstream_wchar;
346
347 typedef struct {
348     basic_iostream_char base;
349     basic_filebuf_char filebuf;
350     /* virtual inheritance */
351     basic_ios_char basic_ios; /* here to reserve correct stack size */
352 } basic_fstream_char;
353
354 typedef struct {
355     basic_iostream_wchar base;
356     basic_filebuf_wchar filebuf;
357     /* virtual inheritance */
358     basic_ios_wchar basic_ios; /* here to reserve correct stack size */
359 } basic_fstream_wchar;
360
361 typedef struct {
362     basic_ostream_char base;
363     basic_stringbuf_char strbuf;
364     /* virtual inheritance
365      * basic_ios_char basic_ios;
366      */
367 } basic_ostringstream_char;
368
369 typedef struct {
370     basic_ostream_wchar base;
371     basic_stringbuf_wchar strbuf;
372     /* virtual inheritance
373      * basic_ios_wchar basic_ios;
374      */
375 } basic_ostringstream_wchar;
376
377 typedef struct {
378     basic_istream_char base;
379     basic_stringbuf_char strbuf;
380     /* virtual inheritance
381      * basic_ios_char basic_ios;
382      */
383 } basic_istringstream_char;
384
385 typedef struct {
386     basic_istream_wchar base;
387     basic_stringbuf_wchar strbuf;
388     /* virtual inheritance
389      * basic_ios_wchar basic_ios;
390      */
391 } basic_istringstream_wchar;
392
393 typedef struct {
394     basic_iostream_char base;
395     basic_stringbuf_char strbuf;
396     /* virtual inheritance */
397     basic_ios_char basic_ios; /* here to reserve correct stack size */
398 } basic_stringstream_char;
399
400 typedef struct {
401     basic_iostream_wchar base;
402     basic_stringbuf_wchar strbuf;
403     /* virtual inheritance */
404     basic_ios_wchar basic_ios; /* here to reserve correct stack size */
405 } basic_stringstream_wchar;
406
407 typedef struct {
408     streamoff off;
409     __int64 DECLSPEC_ALIGN(8) pos;
410     int state;
411 } fpos_int;
412
413 /* stringstream */
414 static basic_stringstream_char* (*__thiscall p_basic_stringstream_char_ctor_mode)(basic_stringstream_char*, int, MSVCP_bool);
415 static basic_stringstream_char* (*__thiscall p_basic_stringstream_char_ctor_str)(basic_stringstream_char*, const basic_string_char*, int, MSVCP_bool);
416 static basic_string_char* (*__thiscall p_basic_stringstream_char_str_get)(const basic_stringstream_char*, basic_string_char*);
417 static void (*__thiscall p_basic_stringstream_char_vbase_dtor)(basic_stringstream_char*);
418
419 static basic_stringstream_wchar* (*__thiscall p_basic_stringstream_wchar_ctor_mode)(basic_stringstream_wchar*, int, MSVCP_bool);
420 static basic_stringstream_wchar* (*__thiscall p_basic_stringstream_wchar_ctor_str)(basic_stringstream_wchar*, const basic_string_wchar*, int, MSVCP_bool);
421 static basic_string_wchar* (*__thiscall p_basic_stringstream_wchar_str_get)(const basic_stringstream_wchar*, basic_string_wchar*);
422 static void (*__thiscall p_basic_stringstream_wchar_vbase_dtor)(basic_stringstream_wchar*);
423
424 /* fstream */
425 static basic_fstream_char* (*__thiscall p_basic_fstream_char_ctor_name)(basic_fstream_char*, const char*, int, MSVCP_bool);
426 static void (*__thiscall p_basic_fstream_char_vbase_dtor)(basic_fstream_char*);
427
428 static basic_fstream_wchar* (*__thiscall p_basic_fstream_wchar_ctor_name)(basic_fstream_wchar*, const char*, int, MSVCP_bool);
429 static void (*__thiscall p_basic_fstream_wchar_vbase_dtor)(basic_fstream_wchar*);
430
431 /* istream */
432 static basic_istream_char* (*__thiscall p_basic_istream_char_read_double)(basic_istream_char*, double*);
433 static int                 (*__thiscall p_basic_istream_char_get)(basic_istream_char*);
434 static MSVCP_bool          (*__thiscall p_basic_istream_char_ipfx)(basic_istream_char*, MSVCP_bool);
435 static basic_istream_char* (*__thiscall p_basic_istream_char_ignore)(basic_istream_char*, streamsize, int);
436 static basic_istream_char* (*__thiscall p_basic_istream_char_seekg)(basic_istream_char*, streamoff, int);
437 static basic_istream_char* (*__thiscall p_basic_istream_char_seekg_fpos)(basic_istream_char*, fpos_int);
438 static int                 (*__thiscall p_basic_istream_char_peek)(basic_istream_char*);
439 static fpos_int*           (*__thiscall p_basic_istream_char_tellg)(basic_istream_char*, fpos_int*);
440 static basic_istream_char* (*__cdecl    p_basic_istream_char_getline_bstr_delim)(basic_istream_char*, basic_string_char*, char);
441
442 static basic_istream_wchar* (*__thiscall p_basic_istream_wchar_read_double)(basic_istream_wchar*, double *);
443 static int                  (*__thiscall p_basic_istream_wchar_get)(basic_istream_wchar*);
444 static MSVCP_bool           (*__thiscall p_basic_istream_wchar_ipfx)(basic_istream_wchar*, MSVCP_bool);
445 static basic_istream_wchar* (*__thiscall p_basic_istream_wchar_ignore)(basic_istream_wchar*, streamsize, unsigned short);
446 static basic_istream_wchar* (*__thiscall p_basic_istream_wchar_seekg)(basic_istream_wchar*, streamoff, int);
447 static basic_istream_wchar* (*__thiscall p_basic_istream_wchar_seekg_fpos)(basic_istream_wchar*, fpos_int);
448 static unsigned short       (*__thiscall p_basic_istream_wchar_peek)(basic_istream_wchar*);
449 static fpos_int*            (*__thiscall p_basic_istream_wchar_tellg)(basic_istream_wchar*, fpos_int*);
450 static basic_istream_wchar* (*__cdecl    p_basic_istream_wchar_getline_bstr_delim)(basic_istream_wchar*, basic_string_wchar*, wchar_t);
451
452 /* ostream */
453 static basic_ostream_char* (*__thiscall p_basic_ostream_char_print_double)(basic_ostream_char*, double);
454
455 static basic_ostream_wchar* (*__thiscall p_basic_ostream_wchar_print_double)(basic_ostream_wchar*, double);
456
457 /* basic_ios */
458 static locale*  (*__thiscall p_basic_ios_char_imbue)(basic_ios_char*, locale*, const locale*);
459
460 static locale*  (*__thiscall p_basic_ios_wchar_imbue)(basic_ios_wchar*, locale*, const locale*);
461
462 /* ios_base */
463 static IOSB_iostate  (*__thiscall p_ios_base_rdstate)(const ios_base*);
464 static IOSB_fmtflags (*__thiscall p_ios_base_setf_mask)(ios_base*, IOSB_fmtflags, IOSB_fmtflags);
465 static void          (*__thiscall p_ios_base_unsetf)(ios_base*, IOSB_fmtflags);
466 static streamsize    (*__thiscall p_ios_base_precision_set)(ios_base*, streamsize);
467
468 /* locale */
469 static locale*  (*__thiscall p_locale_ctor_cstr)(locale*, const char*, int /* FIXME: category */);
470 static void     (*__thiscall p_locale_dtor)(locale *this);
471
472 /* basic_string */
473 static basic_string_char* (__thiscall *p_basic_string_char_ctor_cstr_alloc)(basic_string_char*, const char*, void*);
474 static const char* (__thiscall *p_basic_string_char_cstr)(basic_string_char*);
475 static void (__thiscall *p_basic_string_char_dtor)(basic_string_char*);
476
477 static basic_string_wchar* (__thiscall *p_basic_string_wchar_ctor_cstr_alloc)(basic_string_wchar*, const wchar_t*, void*);
478 static const wchar_t* (__thiscall *p_basic_string_wchar_cstr)(basic_string_wchar*);
479 static void (__thiscall *p_basic_string_wchar_dtor)(basic_string_wchar*);
480
481 static inline const char* debugstr_longlong(ULONGLONG ll)
482 {
483     /* return a different string if called up to 4 times in the same ok() */
484     static char string[4][17];
485     static int which;
486
487     if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
488         sprintf(string[which & 3], "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
489     else
490         sprintf(string[which & 3], "%lx", (unsigned long)ll);
491     return string[which++ & 3];
492 }
493
494 /* Emulate a __thiscall */
495 #ifdef __i386__
496
497 #include "pshpack1.h"
498 struct thiscall_thunk
499 {
500     BYTE pop_eax;    /* popl  %eax (ret addr) */
501     BYTE pop_edx;    /* popl  %edx (func) */
502     BYTE pop_ecx;    /* popl  %ecx (this) */
503     BYTE push_eax;   /* pushl %eax */
504     WORD jmp_edx;    /* jmp  *%edx */
505 };
506 #include "poppack.h"
507
508 static void * (WINAPI *call_thiscall_func1)( void *func, void *this );
509 static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a );
510 static void * (WINAPI *call_thiscall_func3)( void *func, void *this, const void *a, const void *b );
511 static void * (WINAPI *call_thiscall_func4)( void *func, void *this, const void *a, const void *b,
512         const void *c );
513 static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void *a, const void *b,
514         const void *c, const void *d );
515
516 /* to silence compiler errors */
517 static void * (WINAPI *call_thiscall_func2_ptr_dbl)( void *func, void *this, double a );
518 static void * (WINAPI *call_thiscall_func2_ptr_fpos)( void *func, void *this, fpos_int a );
519
520 struct thiscall_thunk_retptr *thunk_retptr;
521
522 static void init_thiscall_thunk(void)
523 {
524     struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
525                                                  MEM_COMMIT, PAGE_EXECUTE_READWRITE );
526     thunk->pop_eax  = 0x58;   /* popl  %eax */
527     thunk->pop_edx  = 0x5a;   /* popl  %edx */
528     thunk->pop_ecx  = 0x59;   /* popl  %ecx */
529     thunk->push_eax = 0x50;   /* pushl %eax */
530     thunk->jmp_edx  = 0xe2ff; /* jmp  *%edx */
531     call_thiscall_func1 = (void *)thunk;
532     call_thiscall_func2 = (void *)thunk;
533     call_thiscall_func3 = (void *)thunk;
534     call_thiscall_func4 = (void *)thunk;
535     call_thiscall_func5 = (void *)thunk;
536
537     call_thiscall_func2_ptr_dbl  = (void *)thunk;
538     call_thiscall_func2_ptr_fpos = (void *)thunk;
539 }
540
541 #define call_func1(func,_this) call_thiscall_func1(func,_this)
542 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
543 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),(const void*)(b))
544 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),(const void*)(b), \
545         (const void*)(c))
546 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),(const void*)(b), \
547         (const void*)(c), (const void *)(d))
548
549 #define call_func2_ptr_dbl(func,_this,a)  call_thiscall_func2_ptr_dbl(func,_this,a)
550 #define call_func2_ptr_fpos(func,_this,a) call_thiscall_func2_ptr_fpos(func,_this,a)
551
552 #else
553
554 #define init_thiscall_thunk()
555 #define call_func1(func,_this) func(_this)
556 #define call_func2(func,_this,a) func(_this,a)
557 #define call_func3(func,_this,a,b) func(_this,a,b)
558 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
559 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
560
561 #define call_func2_ptr_dbl   call_func2
562 #define call_func2_ptr_fpos  call_func2
563
564 #endif /* __i386__ */
565
566 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
567 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
568 static BOOL init(void)
569 {
570     HMODULE msvcp = LoadLibraryA("msvcp60.dll");
571     if(!msvcp) {
572         win_skip("msvcp60.dll not installed\n");
573         return FALSE;
574     }
575
576     if(sizeof(void*) == 8) { /* 64-bit initialization */
577         SET(p_basic_stringstream_char_ctor_mode,
578             "??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@H@Z");
579         SET(p_basic_stringstream_char_ctor_str,
580             "??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@H@Z");
581         SET(p_basic_stringstream_char_str_get,
582             "?str@?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ");
583         SET(p_basic_stringstream_char_vbase_dtor,
584             "??_D?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXXZ");
585
586         SET(p_basic_stringstream_wchar_ctor_mode,
587             "??0?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@H@Z");
588         SET(p_basic_stringstream_wchar_ctor_str,
589             "??0?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@AEBV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@1@H@Z");
590         SET(p_basic_stringstream_wchar_str_get,
591             "?str@?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ");
592         SET(p_basic_stringstream_wchar_vbase_dtor,
593             "??_D?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAXXZ");
594
595         SET(p_basic_fstream_char_ctor_name,
596             "??0?$basic_fstream@DU?$char_traits@D@std@@@std@@QEAA@PEBDH@Z");
597         SET(p_basic_fstream_char_vbase_dtor,
598             "??_D?$basic_fstream@DU?$char_traits@D@std@@@std@@QEAAXXZ");
599
600         SET(p_basic_fstream_wchar_ctor_name,
601             "??0?$basic_fstream@GU?$char_traits@G@std@@@std@@QEAA@PEBDH@Z");
602         SET(p_basic_fstream_wchar_vbase_dtor,
603             "??_D?$basic_fstream@GU?$char_traits@G@std@@@std@@QEAAXXZ");
604
605         SET(p_basic_istream_char_read_double,
606             "??5?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@AEAN@Z");
607         SET(p_basic_istream_char_get,
608             "?get@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAHXZ");
609         SET(p_basic_istream_char_ipfx,
610             "?ipfx@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAA_N_N@Z");
611         SET(p_basic_istream_char_ignore,
612             "?ignore@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@_JH@Z");
613         SET(p_basic_istream_char_seekg,
614             "?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@_JW4seekdir@ios_base@2@@Z");
615         SET(p_basic_istream_char_seekg_fpos,
616             "?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@V?$fpos@H@2@@Z");
617         SET(p_basic_istream_char_peek,
618             "?peek@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAHXZ");
619         SET(p_basic_istream_char_tellg,
620             "?tellg@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAA?AV?$fpos@H@2@XZ");
621         SETNOFAIL(p_basic_istream_char_getline_bstr_delim,
622             "??$getline@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@YAAEAV?$basic_istream@DU?$char_traits@D@std@@@0@AEAV10@AEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@D@Z");
623
624         SET(p_basic_istream_wchar_read_double,
625             "??5?$basic_istream@GU?$char_traits@G@std@@@std@@QEAAAEAV01@AEAN@Z");
626         SET(p_basic_istream_wchar_get,
627             "?get@?$basic_istream@GU?$char_traits@G@std@@@std@@QEAAGXZ");
628         SET(p_basic_istream_wchar_ipfx,
629             "?ipfx@?$basic_istream@GU?$char_traits@G@std@@@std@@QEAA_N_N@Z");
630         SET(p_basic_istream_wchar_ignore,
631             "?ignore@?$basic_istream@GU?$char_traits@G@std@@@std@@QEAAAEAV12@_JG@Z");
632         SET(p_basic_istream_wchar_seekg,
633             "?seekg@?$basic_istream@GU?$char_traits@G@std@@@std@@QEAAAEAV12@_JW4seekdir@ios_base@2@@Z");
634         SET(p_basic_istream_wchar_seekg_fpos,
635             "?seekg@?$basic_istream@GU?$char_traits@G@std@@@std@@QEAAAEAV12@V?$fpos@H@2@@Z");
636         SET(p_basic_istream_wchar_peek,
637             "?peek@?$basic_istream@GU?$char_traits@G@std@@@std@@QEAAGXZ");
638         SET(p_basic_istream_wchar_tellg,
639             "?tellg@?$basic_istream@GU?$char_traits@G@std@@@std@@QEAA?AV?$fpos@H@2@XZ");
640         SETNOFAIL(p_basic_istream_wchar_getline_bstr_delim,
641             "??$getline@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@YAAEAV?$basic_istream@GU?$char_traits@G@std@@@0@AEAV10@AEAV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@0@G@Z");
642
643         SET(p_basic_ostream_char_print_double,
644             "??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@N@Z");
645
646         SET(p_basic_ostream_wchar_print_double,
647             "??6?$basic_ostream@GU?$char_traits@G@std@@@std@@QEAAAEAV01@N@Z");
648
649         SET(p_ios_base_rdstate,
650             "?rdstate@ios_base@std@@QEBAHXZ");
651         SET(p_ios_base_setf_mask,
652             "?setf@ios_base@std@@QEAAHHH@Z");
653         SET(p_ios_base_unsetf,
654             "?unsetf@ios_base@std@@QEAAXH@Z");
655         SET(p_ios_base_precision_set,
656             "?precision@ios_base@std@@QEAA_JH@Z");
657
658         SET(p_basic_ios_char_imbue,
659             "?imbue@?$basic_ios@DU?$char_traits@D@std@@@std@@QEAA?AVlocale@2@AEBV32@@Z");
660
661         SET(p_basic_ios_wchar_imbue,
662             "?imbue@?$basic_ios@GU?$char_traits@G@std@@@std@@QEAA?AVlocale@2@AEBV32@@Z");
663
664         SET(p_locale_ctor_cstr,
665             "??0locale@std@@QEAA@PEBDH@Z");
666         SET(p_locale_dtor,
667             "??1locale@std@@QEAA@XZ");
668
669         SET(p_basic_string_char_ctor_cstr_alloc,
670                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBDAEBV?$allocator@D@1@@Z");
671         SET(p_basic_string_char_cstr,
672                 "?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ");
673         SET(p_basic_string_char_dtor,
674                 "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ");
675
676         SET(p_basic_string_wchar_ctor_cstr_alloc,
677                 "??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@PEBGAEBV?$allocator@G@1@@Z");
678         SET(p_basic_string_wchar_cstr,
679                 "?c_str@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBAPEBGXZ");
680         SET(p_basic_string_wchar_dtor,
681                 "??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@XZ");
682     } else {
683         SET(p_basic_stringstream_char_ctor_mode,
684             "??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@H@Z");
685         SET(p_basic_stringstream_char_ctor_str,
686             "??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@H@Z");
687         SET(p_basic_stringstream_char_str_get,
688             "?str@?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ");
689         SET(p_basic_stringstream_char_vbase_dtor,
690             "??_D?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXXZ");
691
692         SET(p_basic_stringstream_wchar_ctor_mode,
693             "??0?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@H@Z");
694         SET(p_basic_stringstream_wchar_ctor_str,
695             "??0?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@ABV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@1@H@Z");
696         SET(p_basic_stringstream_wchar_str_get,
697             "?str@?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ");
698         SET(p_basic_stringstream_wchar_vbase_dtor,
699             "??_D?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEXXZ");
700
701         SET(p_basic_fstream_char_ctor_name,
702             "??0?$basic_fstream@DU?$char_traits@D@std@@@std@@QAE@PBDH@Z");
703         SET(p_basic_fstream_char_vbase_dtor,
704             "??_D?$basic_fstream@DU?$char_traits@D@std@@@std@@QAEXXZ");
705
706         SET(p_basic_fstream_wchar_ctor_name,
707             "??0?$basic_fstream@GU?$char_traits@G@std@@@std@@QAE@PBDH@Z");
708         SET(p_basic_fstream_wchar_vbase_dtor,
709             "??_D?$basic_fstream@GU?$char_traits@G@std@@@std@@QAEXXZ");
710
711         SET(p_basic_istream_char_read_double,
712             "??5?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV01@AAN@Z");
713         SET(p_basic_istream_char_get,
714             "?get@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEHXZ");
715         SET(p_basic_istream_char_ipfx,
716             "?ipfx@?$basic_istream@DU?$char_traits@D@std@@@std@@QAE_N_N@Z");
717         SET(p_basic_istream_char_ignore,
718             "?ignore@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@HH@Z");
719         SET(p_basic_istream_char_seekg,
720             "?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@JW4seekdir@ios_base@2@@Z");
721         SET(p_basic_istream_char_seekg_fpos,
722             "?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@V?$fpos@H@2@@Z");
723         SET(p_basic_istream_char_peek,
724             "?peek@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEHXZ");
725         SET(p_basic_istream_char_tellg,
726             "?tellg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAE?AV?$fpos@H@2@XZ");
727         SETNOFAIL(p_basic_istream_char_getline_bstr_delim,
728             "??$getline@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@0@AAV10@AAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@D@Z");
729
730         SET(p_basic_istream_wchar_read_double,
731             "??5?$basic_istream@GU?$char_traits@G@std@@@std@@QAEAAV01@AAN@Z");
732         SET(p_basic_istream_wchar_get,
733             "?get@?$basic_istream@GU?$char_traits@G@std@@@std@@QAEGXZ");
734         SET(p_basic_istream_wchar_ipfx,
735             "?ipfx@?$basic_istream@GU?$char_traits@G@std@@@std@@QAE_N_N@Z");
736         SET(p_basic_istream_wchar_ignore,
737             "?ignore@?$basic_istream@GU?$char_traits@G@std@@@std@@QAEAAV12@HG@Z");
738         SET(p_basic_istream_wchar_seekg,
739             "?seekg@?$basic_istream@GU?$char_traits@G@std@@@std@@QAEAAV12@JW4seekdir@ios_base@2@@Z");
740         SET(p_basic_istream_wchar_seekg_fpos,
741             "?seekg@?$basic_istream@GU?$char_traits@G@std@@@std@@QAEAAV12@V?$fpos@H@2@@Z");
742         SET(p_basic_istream_wchar_peek,
743             "?peek@?$basic_istream@GU?$char_traits@G@std@@@std@@QAEGXZ");
744         SET(p_basic_istream_wchar_tellg,
745             "?tellg@?$basic_istream@GU?$char_traits@G@std@@@std@@QAE?AV?$fpos@H@2@XZ");
746         SETNOFAIL(p_basic_istream_wchar_getline_bstr_delim,
747             "??$getline@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@YAAAV?$basic_istream@GU?$char_traits@G@std@@@0@AAV10@AAV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@0@G@Z");
748
749         SET(p_basic_ostream_char_print_double,
750             "??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@N@Z");
751
752         SET(p_basic_ostream_wchar_print_double,
753             "??6?$basic_ostream@GU?$char_traits@G@std@@@std@@QAEAAV01@N@Z");
754
755         SET(p_ios_base_rdstate,
756             "?rdstate@ios_base@std@@QBEHXZ");
757         SET(p_ios_base_setf_mask,
758             "?setf@ios_base@std@@QAEHHH@Z");
759         SET(p_ios_base_unsetf,
760             "?unsetf@ios_base@std@@QAEXH@Z");
761         SET(p_ios_base_precision_set,
762             "?precision@ios_base@std@@QAEHH@Z");
763
764         SET(p_basic_ios_char_imbue,
765             "?imbue@?$basic_ios@DU?$char_traits@D@std@@@std@@QAE?AVlocale@2@ABV32@@Z");
766
767         SET(p_basic_ios_wchar_imbue,
768             "?imbue@?$basic_ios@GU?$char_traits@G@std@@@std@@QAE?AVlocale@2@ABV32@@Z");
769
770         SET(p_locale_ctor_cstr,
771             "??0locale@std@@QAE@PBDH@Z");
772         SET(p_locale_dtor,
773             "??1locale@std@@QAE@XZ");
774
775         SET(p_basic_string_char_ctor_cstr_alloc,
776                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBDABV?$allocator@D@1@@Z");
777         SET(p_basic_string_char_cstr,
778                 "?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ");
779         SET(p_basic_string_char_dtor,
780                 "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ");
781
782         SET(p_basic_string_wchar_ctor_cstr_alloc,
783                 "??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@PBGABV?$allocator@G@1@@Z");
784         SET(p_basic_string_wchar_cstr,
785                 "?c_str@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEPBGXZ");
786         SET(p_basic_string_wchar_dtor,
787                 "??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@XZ");
788     }
789
790     init_thiscall_thunk();
791     return TRUE;
792 }
793
794 char fake_allocator;
795
796 /* convert a dll name A->W without depending on the current codepage */
797 static wchar_t *AtoW( wchar_t *nameW, const char *nameA, unsigned int len )
798 {
799     unsigned int i;
800
801     for (i = 0; i < len; i++) nameW[i] = nameA[i];
802     nameW[i] = 0;
803     return nameW;
804 }
805
806 static void test_num_get_get_double(void)
807 {
808     unsigned short testus, nextus;
809     basic_stringstream_wchar wss;
810     basic_stringstream_char ss;
811     basic_string_wchar wstr;
812     basic_string_char str;
813     IOSB_iostate state;
814     locale lcl, retlcl;
815     wchar_t wide[64];
816     int i, next;
817     double val;
818
819     /* makes tables narrower */
820     const IOSB_iostate IOSTATE_faileof = IOSTATE_failbit|IOSTATE_eofbit;
821
822     struct _test_num_get {
823         const char    *str;
824         const char    *lcl;
825         IOSB_iostate  state;
826         double        val;
827         int           next;
828     } tests[] = {
829         /* simple cases */
830         { "0",     NULL, IOSTATE_eofbit,  0.0,  EOF },
831         { "10",    NULL, IOSTATE_eofbit,  10.0, EOF },
832         { "+10",   NULL, IOSTATE_eofbit,  10.0, EOF },
833         { "-10",   NULL, IOSTATE_eofbit, -10.0, EOF },
834         { "+010",  NULL, IOSTATE_eofbit,  10.0, EOF }, /* leading zero */
835
836         /* test grouping - default/"C" has no grouping, named English/German locales do */
837         { "1,000", NULL,         IOSTATE_goodbit,  1.0,      ',' }, /* with comma */
838         { "1,000", "English",    IOSTATE_goodbit,  1.0,      ',' }, /* msvcp60 doesn't support grouping */
839         { "1,000", "German",     IOSTATE_eofbit,   1.0,      EOF },
840
841         /* extra digits and stuff */
842         { "00000.123456", NULL,  IOSTATE_eofbit,  0.123456, EOF },
843         { "0.1234560000", NULL,  IOSTATE_eofbit,  0.123456, EOF },
844         { "100aaaa",      NULL,  IOSTATE_goodbit, 100.0,    'a' },
845
846         /* exponent */
847         { "10e10",       NULL,      IOSTATE_eofbit,    10e10,      EOF }, /* lowercase e */
848         { "10E10",       NULL,      IOSTATE_eofbit,    10E10,      EOF }, /* uppercase E */
849         { "10e+10",      NULL,      IOSTATE_eofbit,    10e10,      EOF }, /* sign */
850         { "10e-10",      NULL,      IOSTATE_eofbit,    10e-10,     EOF },
851         { "10.e10",      NULL,      IOSTATE_eofbit,    10e10,      EOF }, /* trailing decimal before exponent */
852         { "-10.e-10",    NULL,      IOSTATE_eofbit,   -10e-10,     EOF },
853         { "-12.345e-10", NULL,      IOSTATE_eofbit,   -12.345e-10, EOF },
854         { "1,234e10",    NULL,      IOSTATE_goodbit,   1.0,        ',' },
855         { "1,234e10",    "German",  IOSTATE_eofbit,    1.234e10,   EOF },
856         { "1.0e999",     NULL,      IOSTATE_faileof,   42.0,       EOF }, /* too big   */
857         { "1.0e-999",    NULL,      IOSTATE_faileof,   42.0,       EOF }, /* too small */
858
859         /* bad form */
860         { "1.0ee10", NULL,      IOSTATE_failbit, 42.0,  EOF }, /* dup exp */
861         { "1.0e1.0", NULL,      IOSTATE_goodbit, 10.0,  '.' }, /* decimal in exponent */
862         { "1.0e1,0", NULL,      IOSTATE_goodbit, 10.0,  ',' }, /* group in exponent */
863     };
864
865     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
866         /* char version */
867         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
868         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
869
870         if(tests[i].lcl) {
871             call_func3(p_locale_ctor_cstr, &lcl, tests[i].lcl, 0x3f /* FIXME: support categories */);
872             call_func3(p_basic_ios_char_imbue, &ss.basic_ios, &retlcl, &lcl);
873         }
874
875         val = 42.0;
876         call_func2(p_basic_istream_char_read_double, &ss.base.base1, &val);
877         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
878         next  = (int)call_func1(p_basic_istream_char_get, &ss.base.base1);
879
880         if(tests[i].lcl && state==IOSTATE_badbit) {
881             win_skip("strange behavior when non-C locale is used\n");
882             continue;
883         }
884
885         ok(tests[i].state == state, "%d) wrong state, expected = %x found = %x\n", i, tests[i].state, state);
886         ok(tests[i].val   == val,   "%d) wrong val, expected = %g found %g\n", i, tests[i].val, val);
887         ok(tests[i].next  == next,  "%d) wrong next, expected = %c (%i) found = %c (%i)\n", i, tests[i].next, tests[i].next, next, next);
888
889         if(tests[i].lcl)
890             call_func1(p_locale_dtor, &lcl);
891
892         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
893         call_func1(p_basic_string_char_dtor, &str);
894
895         /* wchar_t version */
896         AtoW(wide, tests[i].str, strlen(tests[i].str));
897         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
898         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
899
900         if(tests[i].lcl) {
901             call_func3(p_locale_ctor_cstr, &lcl, tests[i].lcl, 0x3f /* FIXME: support categories */);
902             call_func3(p_basic_ios_wchar_imbue, &wss.basic_ios, &retlcl, &lcl);
903         }
904
905         val = 42.0;
906         call_func2(p_basic_istream_wchar_read_double, &wss.base.base1, &val);
907         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
908         nextus = (unsigned short)(int)call_func1(p_basic_istream_wchar_get, &wss.base.base1);
909
910         ok(tests[i].state == state, "%d) wrong state, expected = %x found = %x\n", i, tests[i].state, state);
911         ok(tests[i].val == val, "%d) wrong val, expected = %g found %g\n", i, tests[i].val, val);
912         testus = tests[i].next == EOF ? WEOF : (unsigned short)tests[i].next;
913         ok(testus == nextus, "%d) wrong next, expected = %c (%i) found = %c (%i)\n", i, testus, testus, nextus, nextus);
914
915         if(tests[i].lcl)
916             call_func1(p_locale_dtor, &lcl);
917
918         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
919         call_func1(p_basic_string_wchar_dtor, &wstr);
920     }
921 }
922
923
924 static void test_num_put_put_double(void)
925 {
926     basic_stringstream_wchar wss;
927     basic_stringstream_char ss;
928     basic_string_wchar pwstr;
929     basic_string_char pstr;
930     locale lcl, retlcl;
931     const wchar_t *wstr;
932     const char *str;
933     wchar_t wide[64];
934     int i;
935
936     struct _test_num_get {
937         double        val;
938         const char    *lcl;
939         streamsize    prec;  /* set to -1 for default */
940         IOSB_fmtflags fmtfl; /* FMTFLAG_scientific, FMTFLAG_fixed */
941         const char    *str;
942     } tests[] = {
943         { 0.0, NULL, -1, 0, "0" },
944
945         /* simple cases */
946         { 0.123, NULL, -1, 0, "0.123" },
947         { 0.123, NULL,  6, 0, "0.123" },
948         { 0.123, NULL,  0, 0, "0.123" },
949
950         /* fixed format */
951         { 0.123, NULL, -1, FMTFLAG_fixed, "0.123000" },
952         { 0.123, NULL,  6, FMTFLAG_fixed, "0.123000" },
953         { 0.123, NULL,  0, FMTFLAG_fixed, "0" },
954
955         /* scientific format */
956         { 123456.789, NULL,    -1, FMTFLAG_scientific, "1.234568e+005"    },
957         { 123456.789, NULL,     0, FMTFLAG_scientific, "1.234568e+005"    },
958         { 123456.789, NULL,     9, FMTFLAG_scientific, "1.234567890e+005" },
959         { 123456.789, "German", 9, FMTFLAG_scientific, "1,234567890e+005" },
960
961         /* different locales */
962         { 0.123, "C",       -1, 0, "0.123" },
963         { 0.123, "English", -1, 0, "0.123" },
964         { 0.123, "German",  -1, 0, "0,123" },
965
966         { 123456.789, "C",       -1, 0, "123457"  },
967         { 123456.789, "English", -1, 0, "123457" },
968         { 123456.789, "German",  -1, 0, "123457" },
969
970         /* signs and exponents */
971         {  1.0e-9, NULL, -1, 0, "1e-009"  },
972         {  1.0e-9, NULL,  9, 0, "1e-009"  },
973         { -1.0e9,  NULL, -1, 0, "-1e+009" },
974         { -1.0e9,  NULL,  9, 0, "-1e+009" },
975
976         {  1.0e-9, NULL, 0, FMTFLAG_fixed, "0"                  },
977         {  1.0e-9, NULL, 6, FMTFLAG_fixed, "0.000000"           },
978         {  1.0e-9, NULL, 9, FMTFLAG_fixed, "0.000000001"        },
979         { -1.0e9,  NULL, 0, FMTFLAG_fixed, "-1000000000"        },
980         { -1.0e9,  NULL, 6, FMTFLAG_fixed, "-1000000000.000000" },
981
982         { -1.23456789e9,  NULL, 0, 0,             "-1.23457e+009"      },
983         { -1.23456789e9,  NULL, 0, FMTFLAG_fixed, "-1234567890"        },
984         { -1.23456789e9,  NULL, 6, FMTFLAG_fixed, "-1234567890.000000" },
985         { -1.23456789e-9, NULL, 6, FMTFLAG_fixed, "-0.000000"          },
986         { -1.23456789e-9, NULL, 9, FMTFLAG_fixed, "-0.000000001"       }
987     };
988
989     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
990         /* char version */
991         call_func3(p_basic_stringstream_char_ctor_mode, &ss, OPENMODE_in|OPENMODE_out, TRUE);
992
993         if(tests[i].lcl) {
994             call_func3(p_locale_ctor_cstr, &lcl, tests[i].lcl, 0x3f /* FIXME: support categories */);
995             call_func3(p_basic_ios_char_imbue, &ss.basic_ios, &retlcl, &lcl);
996         }
997
998         /* set format and precision only if specified, so we can try defaults */
999         if(tests[i].fmtfl)
1000             call_func3(p_ios_base_setf_mask, &ss.basic_ios.base, tests[i].fmtfl, FMTFLAG_floatfield);
1001         if(tests[i].prec != -1)
1002             call_func2(p_ios_base_precision_set, &ss.basic_ios.base, tests[i].prec);
1003         call_func2_ptr_dbl(p_basic_ostream_char_print_double, &ss.base.base2, tests[i].val);
1004
1005         call_func2(p_basic_stringstream_char_str_get, &ss, &pstr);
1006         str = call_func1(p_basic_string_char_cstr, &pstr);
1007
1008         ok(!strcmp(tests[i].str, str), "wrong output, expected = %s found = %s\n", tests[i].str, str);
1009         call_func1(p_basic_string_char_dtor, &pstr);
1010
1011         if(tests[i].lcl)
1012             call_func1(p_locale_dtor, &lcl);
1013
1014         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1015
1016         /* wchar_t version */
1017         call_func3(p_basic_stringstream_wchar_ctor_mode, &wss, OPENMODE_in|OPENMODE_out, TRUE);
1018
1019         if(tests[i].lcl) {
1020             call_func3(p_locale_ctor_cstr, &lcl, tests[i].lcl, 0x3f /* FIXME: support categories */);
1021             call_func3(p_basic_ios_wchar_imbue, &wss.basic_ios, &retlcl, &lcl);
1022         }
1023
1024         /* set format and precision only if specified, so we can try defaults */
1025         if(tests[i].fmtfl)
1026             call_func3(p_ios_base_setf_mask, &wss.basic_ios.base, tests[i].fmtfl, FMTFLAG_floatfield);
1027         if(tests[i].prec != -1)
1028             call_func2(p_ios_base_precision_set, &wss.basic_ios.base, tests[i].prec);
1029         call_func2_ptr_dbl(p_basic_ostream_wchar_print_double, &wss.base.base2, tests[i].val);
1030
1031         call_func2(p_basic_stringstream_wchar_str_get, &wss, &pwstr);
1032         wstr = call_func1(p_basic_string_wchar_cstr, &pwstr);
1033
1034         AtoW(wide, tests[i].str, strlen(tests[i].str));
1035         ok(!lstrcmpW(wide, wstr), "wrong output, expected = %s found = %s\n", tests[i].str, wine_dbgstr_w(wstr));
1036         call_func1(p_basic_string_wchar_dtor, &pwstr);
1037
1038         if(tests[i].lcl)
1039             call_func1(p_locale_dtor, &lcl);
1040
1041         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1042     }
1043 }
1044
1045
1046 static void test_istream_ipfx(void)
1047 {
1048     unsigned short testus, nextus;
1049     basic_stringstream_wchar wss;
1050     basic_stringstream_char ss;
1051     basic_string_wchar wstr;
1052     basic_string_char str;
1053     IOSB_iostate state;
1054     wchar_t wide[64];
1055     int i, next;
1056     MSVCP_bool ret;
1057
1058     struct _test_istream_ipfx {
1059         const char  *str;
1060         int          unset_skipws;
1061         int          noskip;
1062         MSVCP_bool   ret;
1063         IOSB_iostate state;
1064         int          next;
1065     } tests[] = {
1066         /* string       unset  noskip return state            next char */
1067         { "",           FALSE, FALSE, TRUE,  IOSTATE_goodbit, EOF  }, /* empty string */
1068         { "   ",        FALSE, FALSE, TRUE,  IOSTATE_goodbit, EOF  }, /* just ws */
1069         { "\t \n \f ",  FALSE, FALSE, TRUE,  IOSTATE_goodbit, EOF  }, /* different ws */
1070         { "simple",     FALSE, FALSE, TRUE,  IOSTATE_goodbit, 's'  },
1071         { "  simple",   FALSE, FALSE, TRUE,  IOSTATE_goodbit, 's'  },
1072         { "  simple",   TRUE,  FALSE, TRUE,  IOSTATE_goodbit, ' '  }, /* unset skipws */
1073         { "  simple",   FALSE, TRUE,  TRUE,  IOSTATE_goodbit, ' '  }, /* ipfx(true) */
1074         { "  simple",   TRUE,  TRUE,  TRUE,  IOSTATE_goodbit, ' '  }, /* both */
1075         { "\n\t ws",    FALSE, FALSE, TRUE,  IOSTATE_goodbit, 'w'  },
1076         { "\n\t ws",    TRUE,  FALSE, TRUE,  IOSTATE_goodbit, '\n' },
1077     };
1078
1079     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1080         /* char version */
1081         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
1082         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
1083
1084         /* set format and precision only if specified, so we can try defaults */
1085         if(tests[i].unset_skipws)
1086             call_func2(p_ios_base_unsetf, &ss.basic_ios.base, TRUE);
1087
1088         ret   = (MSVCP_bool)(INT_PTR)call_func2(p_basic_istream_char_ipfx, &ss.base.base1, tests[i].noskip);
1089         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
1090         next  = (int)call_func1(p_basic_istream_char_get, &ss.base.base1);
1091
1092         ok(tests[i].ret   == ret,   "%d) wrong return, expected = %i found = %i\n", i, tests[i].ret, ret);
1093         ok(tests[i].state == state, "%d) wrong state, expected = %x found = %x\n", i, tests[i].state, state);
1094         ok(tests[i].next  == next,  "%d) wrong next, expected = %c (%i) found = %c (%i)\n", i, tests[i].next, tests[i].next, next, next);
1095
1096         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1097         call_func1(p_basic_string_char_dtor, &str);
1098
1099         /* wchar_t version */
1100         AtoW(wide, tests[i].str, strlen(tests[i].str));
1101         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
1102         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
1103
1104         /* set format and precision only if specified, so we can try defaults */
1105         if(tests[i].unset_skipws)
1106             call_func2(p_ios_base_unsetf, &wss.basic_ios.base, TRUE);
1107
1108         ret    = (MSVCP_bool)(INT_PTR)call_func2(p_basic_istream_wchar_ipfx, &wss.base.base1, tests[i].noskip);
1109         state  = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
1110         nextus = (unsigned short)(int)call_func1(p_basic_istream_wchar_get, &wss.base.base1);
1111
1112         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1113         ok(tests[i].ret == ret, "wrong return, expected = %i found = %i\n", tests[i].ret, ret);
1114         testus = tests[i].next == EOF ? WEOF : (unsigned short)tests[i].next;
1115         ok(testus == nextus, "wrong next, expected = %c (%i) found = %c (%i)\n", testus, testus, nextus, nextus);
1116
1117         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1118         call_func1(p_basic_string_wchar_dtor, &wstr);
1119     }
1120 }
1121
1122
1123 static void test_istream_ignore(void)
1124 {
1125     unsigned short testus, nextus;
1126     basic_stringstream_wchar wss;
1127     basic_stringstream_char ss;
1128     basic_string_wchar wstr;
1129     basic_string_char str;
1130     IOSB_iostate state;
1131     wchar_t wide[64];
1132     int i, next;
1133
1134     struct _test_istream_ignore {
1135         const char  *str;
1136         streamsize   count;
1137         int          delim;
1138         IOSB_iostate state;
1139         int          next;
1140     } tests[] = {
1141         /* string       count delim state            next */
1142         { "",           0,    '\n', IOSTATE_goodbit, EOF }, /* empty string */
1143
1144         /* different counts */
1145         { "ABCDEF",     2,    '\n', IOSTATE_goodbit, 'C' }, /* easy case */
1146         { "ABCDEF",     42,   '\n', IOSTATE_eofbit,  EOF }, /* ignore too much */
1147         { "ABCDEF",    -2,    '\n', IOSTATE_goodbit, 'A' }, /* negative count */
1148         { "ABCDEF",     6,    '\n', IOSTATE_goodbit, EOF }, /* is eof not set at end */
1149         { "ABCDEF",     7,    '\n', IOSTATE_eofbit,  EOF }, /* eof is set just after end */
1150
1151         /* different delimiters */
1152         { "ABCDEF",       42, '\0', IOSTATE_eofbit,  EOF }, /* null as delim */
1153         { "ABC DEF GHI",  0,  ' ',  IOSTATE_goodbit, 'A' },
1154         { "ABC DEF GHI",  42, ' ',  IOSTATE_goodbit, 'D' },
1155         { "ABC DEF\tGHI", 42, '\t', IOSTATE_goodbit, 'G' },
1156         { "ABC ",         42, ' ',  IOSTATE_goodbit, EOF }, /* delim at end */
1157     };
1158
1159     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1160         /* char version */
1161         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
1162         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
1163
1164         call_func3(p_basic_istream_char_ignore, &ss.base.base1, tests[i].count, tests[i].delim);
1165         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
1166         next  = (int)call_func1(p_basic_istream_char_get, &ss.base.base1);
1167
1168         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1169         ok(tests[i].next  == next,  "wrong next, expected = %c (%i) found = %c (%i)\n", tests[i].next, tests[i].next, next, next);
1170
1171         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1172         call_func1(p_basic_string_char_dtor, &str);
1173
1174         /* wchar_t version */
1175         AtoW(wide, tests[i].str, strlen(tests[i].str));
1176         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
1177         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
1178
1179         call_func3(p_basic_istream_wchar_ignore, &wss.base.base1, tests[i].count, tests[i].delim);
1180         state  = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
1181         nextus = (unsigned short)(int)call_func1(p_basic_istream_wchar_get, &wss.base.base1);
1182
1183         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1184         testus = tests[i].next == EOF ? WEOF : (unsigned short)tests[i].next;
1185         ok(testus == nextus, "wrong next, expected = %c (%i) found = %c (%i)\n", testus, testus, nextus, nextus);
1186
1187         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1188         call_func1(p_basic_string_wchar_dtor, &wstr);
1189     }
1190 }
1191
1192
1193 static void test_istream_seekg(void)
1194 {
1195     unsigned short testus, nextus;
1196     basic_stringstream_wchar wss;
1197     basic_stringstream_char ss;
1198     basic_string_wchar wstr;
1199     basic_string_char str;
1200     IOSB_iostate state;
1201     wchar_t wide[64];
1202     int i, next;
1203
1204     struct _test_istream_seekg {
1205         const char  *str;
1206         streamoff    off;
1207         IOSB_seekdir dir;
1208         IOSB_iostate state;
1209         int          next;
1210     } tests[] = {
1211         { "ABCDEFGHIJ",  0, SEEKDIR_beg, IOSTATE_goodbit, 'A' },
1212         { "ABCDEFGHIJ",  1, SEEKDIR_beg, IOSTATE_goodbit, 'B' },
1213         { "ABCDEFGHIJ",  5, SEEKDIR_cur, IOSTATE_goodbit, 'F' },
1214         { "ABCDEFGHIJ", -3, SEEKDIR_end, IOSTATE_goodbit, 'H' },
1215
1216         /* bad offsets */
1217         { "ABCDEFGHIJ", -1, SEEKDIR_beg, IOSTATE_goodbit, 'A' },
1218         { "ABCDEFGHIJ", 42, SEEKDIR_cur, IOSTATE_goodbit, 'A' },
1219         { "ABCDEFGHIJ", 42, SEEKDIR_end, IOSTATE_goodbit, 'A' },
1220         { "",            0, SEEKDIR_beg, IOSTATE_goodbit, EOF },
1221     };
1222
1223     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1224         /* char version */
1225         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
1226         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
1227
1228         call_func3(p_basic_istream_char_seekg, &ss.base.base1, tests[i].off, tests[i].dir);
1229         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
1230         next  = (int)call_func1(p_basic_istream_char_get, &ss.base.base1);
1231
1232         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1233         ok(tests[i].next  == next,  "wrong next, expected = %c (%i) found = %c (%i)\n", tests[i].next, tests[i].next, next, next);
1234
1235         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1236         call_func1(p_basic_string_char_dtor, &str);
1237
1238         /* wchar_t version */
1239         AtoW(wide, tests[i].str, strlen(tests[i].str));
1240         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
1241         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
1242
1243         call_func3(p_basic_istream_wchar_seekg, &wss.base.base1, tests[i].off, tests[i].dir);
1244         state  = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
1245         nextus = (unsigned short)(int)call_func1(p_basic_istream_wchar_get, &wss.base.base1);
1246
1247         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1248         testus = tests[i].next == EOF ? WEOF : (unsigned short)tests[i].next;
1249         ok(testus == nextus, "wrong next, expected = %c (%i) found = %c (%i)\n", testus, testus, nextus, nextus);
1250
1251         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1252         call_func1(p_basic_string_wchar_dtor, &wstr);
1253     }
1254 }
1255
1256
1257 static void test_istream_seekg_fpos(void)
1258 {
1259     unsigned short testus, nextus;
1260     basic_stringstream_wchar wss;
1261     basic_stringstream_char ss;
1262     basic_string_wchar wstr;
1263     basic_string_char str;
1264     IOSB_iostate state;
1265     wchar_t wide[64];
1266     fpos_int pos;
1267     int i, next;
1268
1269     struct _test_istream_seekg_fpos {
1270         const char  *str;
1271         streamoff    off;
1272         IOSB_iostate state;
1273         int          next;
1274     } tests[] = {
1275         { "ABCDEFGHIJ", 0,  IOSTATE_goodbit, 'A' },
1276         { "ABCDEFGHIJ", 9,  IOSTATE_goodbit, 'J' },
1277         { "ABCDEFGHIJ", 10, IOSTATE_goodbit, EOF }, /* beyond end, but still good */
1278         { "ABCDEFGHIJ", -1, IOSTATE_goodbit, 'A' },
1279         { "",           0,  IOSTATE_goodbit, EOF },
1280     };
1281
1282     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1283         /* char version */
1284         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
1285         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
1286
1287         pos.off   = tests[i].off;
1288         pos.pos   = 0; /* FIXME: a later patch will test this with filebuf */
1289         pos.state = 0;
1290         call_func2_ptr_fpos(p_basic_istream_char_seekg_fpos, &ss.base.base1, pos);
1291         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
1292         next  = (int)call_func1(p_basic_istream_char_get, &ss.base.base1);
1293
1294         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1295         ok(tests[i].next  == next,  "wrong next, expected = %c (%i) found = %c (%i)\n", tests[i].next, tests[i].next, next, next);
1296
1297         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1298         call_func1(p_basic_string_char_dtor, &str);
1299
1300         /* wchar_t version */
1301         AtoW(wide, tests[i].str, strlen(tests[i].str));
1302         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
1303         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
1304
1305         pos.off   = tests[i].off;
1306         pos.pos   = 0; /* FIXME: a later patch will test this with filebuf */
1307         pos.state = 0;
1308         call_func2_ptr_fpos(p_basic_istream_wchar_seekg_fpos, &wss.base.base1, pos);
1309         state  = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
1310         nextus = (unsigned short)(int)call_func1(p_basic_istream_wchar_get, &wss.base.base1);
1311
1312         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1313         testus = tests[i].next == EOF ? WEOF : (unsigned short)tests[i].next;
1314         ok(testus == nextus, "wrong next, expected = %c (%i) found = %c (%i)\n", testus, testus, nextus, nextus);
1315
1316         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1317         call_func1(p_basic_string_wchar_dtor, &wstr);
1318     }
1319 }
1320
1321
1322 static void test_istream_peek(void)
1323 {
1324     unsigned short testus, nextus, peekus;
1325     basic_stringstream_wchar wss;
1326     basic_stringstream_char ss;
1327     basic_string_wchar wstr;
1328     basic_string_char str;
1329     IOSB_iostate state;
1330     int i, next, peek;
1331     wchar_t wide[64];
1332
1333     struct _test_istream_peek {
1334         const char  *str;
1335         int          peek;
1336         int          next;
1337         IOSB_iostate state;
1338     } tests[] = {
1339         { "",       EOF, EOF, IOSTATE_eofbit  },
1340         { "ABCDEF", 'A', 'A', IOSTATE_goodbit },
1341     };
1342
1343     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1344         /* char version */
1345         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
1346         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
1347
1348         peek  = (int)call_func1(p_basic_istream_char_peek, &ss.base.base1);
1349         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
1350         next  = (int)call_func1(p_basic_istream_char_get, &ss.base.base1);
1351
1352         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1353         ok(tests[i].next  == next,  "wrong next, expected = %c (%i) found = %c (%i)\n", tests[i].next, tests[i].next, next, next);
1354         ok(peek == next, "wrong peek, expected %c (%i) found = %c (%i)\n", peek, peek, next, next);
1355
1356         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1357         call_func1(p_basic_string_char_dtor, &str);
1358
1359         /* wchar_t version */
1360         AtoW(wide, tests[i].str, strlen(tests[i].str));
1361         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
1362         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
1363
1364         peekus = (unsigned short)(int)call_func1(p_basic_istream_wchar_peek, &wss.base.base1);
1365         state  = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
1366         nextus = (unsigned short)(int)call_func1(p_basic_istream_wchar_get, &wss.base.base1);
1367
1368         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1369         testus = tests[i].next == EOF ? WEOF : (unsigned short)tests[i].next;
1370         ok(testus == nextus, "wrong next, expected = %c (%i) found = %c (%i)\n", testus, testus, nextus, nextus);
1371         ok(peekus == nextus, "wrong peek, expected %c (%i) found = %c (%i)\n", peekus, peekus, nextus, nextus);
1372
1373         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1374         call_func1(p_basic_string_wchar_dtor, &wstr);
1375     }
1376 }
1377
1378
1379 static void test_istream_tellg(void)
1380 {
1381     basic_stringstream_wchar wss;
1382     basic_stringstream_char ss;
1383     basic_fstream_wchar wfs;
1384     basic_fstream_char fs;
1385     basic_string_wchar wstr;
1386     basic_string_char str;
1387     fpos_int spos, tpos, *rpos;
1388     wchar_t wide[64];
1389     FILE *file;
1390     int i;
1391
1392     const char *testfile = "file.txt";
1393
1394     struct _test_istream_tellg_fpos {
1395         const char  *str;
1396         streamoff    seekoff;
1397         streamoff    telloff_ss; /* offset for stringstream */
1398         streamoff    telloff_fs; /* offset for fstream */
1399         __int64      tellpos;
1400     } tests[] = {
1401         /* empty strings */
1402         { "", -1, -1,  0,  0 }, /* tellg on defaults */
1403         { "",  0, -1,  0,  0 }, /* tellg after seek 0 */
1404         { "", 42, -1,  0, 42 }, /* tellg after seek beyond end */
1405         { "", -6, -1,  0,  0 }, /* tellg after seek beyond beg */
1406
1407         /* non-empty strings */
1408         { "ABCDEFGHIJ", -1,  0,  0,  0 },
1409         { "ABCDEFGHIJ",  3,  3,  0,  3 },
1410         { "ABCDEFGHIJ", 42,  0,  0, 42 },
1411         { "ABCDEFGHIJ", -6,  0,  0,  0 }
1412     };
1413
1414     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1415         /* stringstream<char> version */
1416         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
1417         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
1418
1419         spos.off   = tests[i].seekoff;
1420         spos.pos   = 0;
1421         spos.state = 0;
1422
1423         tpos.off   = 0xdeadbeef;
1424         tpos.pos   = 0xdeadbeef;
1425         tpos.state = 0xdeadbeef;
1426
1427         if (tests[i].seekoff != -1) /* to test without seek */
1428             call_func2_ptr_fpos(p_basic_istream_char_seekg_fpos, &ss.base.base1, spos);
1429         rpos = (fpos_int *)call_func2(p_basic_istream_char_tellg, &ss.base.base1, &tpos);
1430
1431         ok(tests[i].telloff_ss == tpos.off, "wrong offset, expected = %ld found = %ld\n", tests[i].telloff_ss, tpos.off);
1432         ok(rpos == &tpos, "wrong return fpos, expected = %p found = %p\n", rpos, &tpos);
1433         ok(tpos.pos == 0, "wrong position, expected = 0 found = %s\n", debugstr_longlong(tpos.pos));
1434         ok(tpos.state == 0, "wrong state, expected = 0 found = %d\n", tpos.state);
1435
1436         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1437         call_func1(p_basic_string_char_dtor, &str);
1438
1439         /* stringstream<wchar_t> version */
1440         AtoW(wide, tests[i].str, strlen(tests[i].str));
1441         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
1442         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
1443
1444         spos.off   = tests[i].seekoff;
1445         spos.pos   = 0; /* FIXME: a later patch will test this with filebuf */
1446         spos.state = 0;
1447
1448         tpos.off   = 0xdeadbeef;
1449         tpos.pos   = 0xdeadbeef;
1450         tpos.state = 0xdeadbeef;
1451
1452         if (tests[i].seekoff != -1) /* to test without seek */
1453             call_func2_ptr_fpos(p_basic_istream_wchar_seekg_fpos, &wss.base.base1, spos);
1454         rpos = (fpos_int *)call_func2(p_basic_istream_wchar_tellg, &wss.base.base1, &tpos);
1455
1456         ok(tests[i].telloff_ss == tpos.off, "wrong offset, expected = %ld found = %ld\n", tests[i].telloff_ss, tpos.off);
1457         ok(rpos == &tpos, "wrong return fpos, expected = %p found = %p\n", rpos, &tpos);
1458         ok(tpos.pos == 0, "wrong position, expected = 0 found = %s\n", debugstr_longlong(tpos.pos));
1459         ok(tpos.state == 0, "wrong state, expected = 0 found = %d\n", tpos.state);
1460
1461         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1462         call_func1(p_basic_string_wchar_dtor, &wstr);
1463
1464         /* filebuf */
1465         file = fopen(testfile, "wt");
1466         fprintf(file, tests[i].str);
1467         fclose(file);
1468
1469         /* fstream<char> version */
1470         call_func4(p_basic_fstream_char_ctor_name, &fs, testfile, OPENMODE_out|OPENMODE_in, TRUE);
1471
1472         spos.off   = tests[i].seekoff;
1473         spos.pos   = 0;
1474         spos.state = 0;
1475
1476         tpos.off   = 0xdeadbeef;
1477         tpos.pos   = 0xdeadbeef;
1478         tpos.state = 0xdeadbeef;
1479
1480         if (tests[i].seekoff != -1) /* to test without seek */
1481             call_func2_ptr_fpos(p_basic_istream_char_seekg_fpos, &fs.base.base1, spos);
1482         rpos = (fpos_int *)call_func2(p_basic_istream_char_tellg, &fs.base.base1, &tpos);
1483
1484         ok(tests[i].tellpos == tpos.pos, "wrong filepos, expected = %s found = %s\n",
1485             debugstr_longlong(tests[i].tellpos), debugstr_longlong(tpos.pos));
1486         ok(rpos == &tpos, "wrong return fpos, expected = %p found = %p\n", rpos, &tpos);
1487         ok(tpos.off == tests[i].telloff_fs, "wrong offset, expected %ld found %ld\n", tests[i].telloff_fs, tpos.off);
1488         ok(tpos.state == 0, "wrong state, expected = 0 found = %d\n", tpos.state);
1489
1490         call_func1(p_basic_fstream_char_vbase_dtor, &fs);
1491
1492         /* fstream<wchar_t> version */
1493         call_func4(p_basic_fstream_wchar_ctor_name, &wfs, testfile, OPENMODE_out|OPENMODE_in, TRUE);
1494
1495         spos.off   = tests[i].seekoff;
1496         spos.pos   = 0;
1497         spos.state = 0;
1498
1499         tpos.off   = 0xdeadbeef;
1500         tpos.pos   = 0xdeadbeef;
1501         tpos.state = 0xdeadbeef;
1502
1503         if (tests[i].seekoff != -1) /* to test without seek */
1504             call_func2_ptr_fpos(p_basic_istream_wchar_seekg_fpos, &wfs.base.base1, spos);
1505         rpos = (fpos_int *)call_func2(p_basic_istream_wchar_tellg, &wfs.base.base1, &tpos);
1506
1507         ok(tests[i].tellpos == tpos.pos, "wrong filepos, expected = %s found = %s\n",
1508             debugstr_longlong(tests[i].tellpos), debugstr_longlong(tpos.pos));
1509         ok(rpos == &tpos, "wrong return fpos, expected = %p found = %p\n", rpos, &tpos);
1510         ok(tpos.off == tests[i].telloff_fs, "wrong offset, expected %ld found %ld\n", tests[i].telloff_fs, tpos.off);
1511         ok(tpos.state == 0, "wrong state, expected = 0 found = %d\n", tpos.state);
1512
1513         call_func1(p_basic_fstream_wchar_vbase_dtor, &wfs);
1514
1515         unlink(testfile);
1516     }
1517 }
1518
1519
1520 static void test_istream_getline(void)
1521 {
1522     basic_stringstream_wchar wss;
1523     basic_stringstream_char ss;
1524     basic_string_wchar wstr;
1525     basic_string_char str;
1526     IOSB_iostate state;
1527     wchar_t wide[64];
1528     int i;
1529     const char *cstr;
1530     const wchar_t *wcstr;
1531
1532     /* makes tables narrower */
1533     const IOSB_iostate IOSTATE_faileof = IOSTATE_failbit|IOSTATE_eofbit;
1534
1535     struct _test_istream_getline {
1536         const char  *str;
1537         const char  *line;
1538         int          delim;
1539         IOSB_iostate state;
1540         const char  *nextline;
1541         int          nextdelim;
1542         IOSB_iostate nextstate;
1543     } tests[] = {
1544         { "", "", '\n', IOSTATE_faileof, "", '\n', IOSTATE_faileof },
1545
1546         { "this\n",                 "this", '\n', IOSTATE_goodbit, "",   '\n', IOSTATE_faileof },
1547         { "this\nis\nsome\ntext\n", "this", '\n', IOSTATE_goodbit, "is", '\n', IOSTATE_goodbit },
1548
1549         { "this is some text\n", "this", ' ',  IOSTATE_goodbit, "is",           ' ',  IOSTATE_goodbit },
1550         { "this is some text\n", "this", ' ',  IOSTATE_goodbit, "is some text", '\n', IOSTATE_goodbit },
1551
1552         { "this is some text\n", "this is some text",   '\n', IOSTATE_goodbit, "",                    '\n', IOSTATE_faileof },
1553         { "this is some text\n", "this is some text\n", '\0', IOSTATE_eofbit,  "", '\n', IOSTATE_faileof },
1554     };
1555
1556     if(!p_basic_istream_char_getline_bstr_delim || !p_basic_istream_wchar_getline_bstr_delim) {
1557         win_skip("basic_istream::getline(basic_string, delim) is not available\n");
1558         return;
1559     }
1560
1561     for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
1562         /* char version */
1563         call_func3(p_basic_string_char_ctor_cstr_alloc, &str, tests[i].str, &fake_allocator);
1564         call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
1565
1566         p_basic_istream_char_getline_bstr_delim(&ss.base.base1, &str, tests[i].delim);
1567         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
1568         cstr  = call_func1(p_basic_string_char_cstr, &str);
1569
1570         ok(!strcmp(tests[i].line, cstr), "wrong line, expected = %s found = %s\n", tests[i].line, cstr);
1571         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1572
1573         /* next line */
1574         p_basic_istream_char_getline_bstr_delim(&ss.base.base1, &str, tests[i].nextdelim);
1575         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
1576         cstr  = call_func1(p_basic_string_char_cstr, &str);
1577
1578         ok(!strcmp(tests[i].nextline, cstr), "wrong next line, expected = %s found = %s\n", tests[i].nextline, cstr);
1579         ok(tests[i].nextstate == state, "wrong next state, expected = %x found = %x\n", tests[i].nextstate, state);
1580
1581         call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
1582         call_func1(p_basic_string_char_dtor, &str);
1583
1584         /* wchar_t version */
1585         AtoW(wide, tests[i].str, strlen(tests[i].str));
1586         call_func3(p_basic_string_wchar_ctor_cstr_alloc, &wstr, wide, &fake_allocator);
1587         call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
1588
1589         p_basic_istream_wchar_getline_bstr_delim(&wss.base.base1, &wstr, tests[i].delim);
1590         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
1591         wcstr = call_func1(p_basic_string_wchar_cstr, &wstr);
1592
1593         AtoW(wide, tests[i].line, strlen(tests[i].line));
1594         ok(!lstrcmpW(wide, wcstr), "wrong line, expected = %s found = %s\n", tests[i].line, wine_dbgstr_w(wcstr));
1595         ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
1596
1597         /* next line */
1598         p_basic_istream_wchar_getline_bstr_delim(&wss.base.base1, &wstr, tests[i].nextdelim);
1599         state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
1600         wcstr = call_func1(p_basic_string_wchar_cstr, &wstr);
1601
1602         AtoW(wide, tests[i].nextline, strlen(tests[i].nextline));
1603         ok(!lstrcmpW(wide, wcstr), "wrong line, expected = %s found = %s\n", tests[i].nextline, wine_dbgstr_w(wcstr));
1604         ok(tests[i].nextstate == state, "wrong state, expected = %x found = %x\n", tests[i].nextstate, state);
1605
1606         call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
1607         call_func1(p_basic_string_wchar_dtor, &wstr);
1608     }
1609 }
1610
1611
1612 START_TEST(ios)
1613 {
1614     if(!init())
1615         return;
1616
1617     test_num_get_get_double();
1618     test_num_put_put_double();
1619     test_istream_ipfx();
1620     test_istream_ignore();
1621     test_istream_seekg();
1622     test_istream_seekg_fpos();
1623     test_istream_peek();
1624     test_istream_tellg();
1625     test_istream_getline();
1626 }