On Thu, 19 Feb 2004 08:27, Eric Pouech wrote:
Ivan Leo Murray-Smith a écrit :
Apparently there is a problem with wine's scanf. this code
the main issue is that MSVCRT_scanf calls MSVCRT_fscanf while it thinks it's actually fvscanf. All the scanf internal functions should be implemented as vscanf not scanf A+
What he said, except they should all be implemented using vfscanf. There's no reason to have all of the *scanf functions listed using the macro tricks currently used (dlls/msvcrt/scanf.h) - all these should be capable of being turned into a call to vfscanf or vwscanf (this might still justify the macro tricks, but only once for vfscanf and once for vwscanf, as is done in glibc. In the case of sscanf and vsscanf, this is done by creating a dummy FILE instance that has the string as its buffer.
Try the following patch (compiles, but not tested - I don't use msvcrt).
? dlls/msvcrt/.file.c.swp ? dlls/msvcrt/.scanf.c.swp ? dlls/msvcrt/.scanf.h.swp ? include/msvcrt/.stdio.h.swp Index: dlls/msvcrt/file.c =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/file.c,v retrieving revision 1.62 diff -u -r1.62 file.c --- dlls/msvcrt/file.c 13 Jan 2004 05:45:05 -0000 1.62 +++ dlls/msvcrt/file.c 18 Feb 2004 22:24:44 -0000 @@ -2383,7 +2383,7 @@ int res;
va_start(valist, format); - res = MSVCRT_fscanf(MSVCRT_stdin, format, valist); + res = MSVCRT_vfscanf(MSVCRT_stdin, format, valist); va_end(valist); return res; } @@ -2397,7 +2397,7 @@ int res;
va_start(valist, format); - res = MSVCRT_fwscanf(MSVCRT_stdin, format, valist); + res = MSVCRT_vfwscanf(MSVCRT_stdin, format, valist); va_end(valist); return res; } Index: dlls/msvcrt/scanf.c =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/scanf.c,v retrieving revision 1.5 diff -u -r1.5 scanf.c --- dlls/msvcrt/scanf.c 5 Sep 2003 23:08:35 -0000 1.5 +++ dlls/msvcrt/scanf.c 18 Feb 2004 22:24:44 -0000 @@ -67,6 +67,7 @@ #undef WIDE_SCANF #undef CONSOLE #undef STRING +#undef VECTOR #include "scanf.h"
/********************************************************************* @@ -75,6 +76,25 @@ #define WIDE_SCANF 1 #undef CONSOLE #undef STRING +#undef VECTOR +#include "scanf.h" + +/********************************************************************* + * vfscanf (MSVCRT.@) + */ +#undef WIDE_SCANF +#undef CONSOLE +#undef STRING +#define VECTOR 1 +#include "scanf.h" + +/********************************************************************* + * vfwscanf (MSVCRT.@) + */ +#define WIDE_SCANF 1 +#undef CONSOLE +#undef STRING +#define VECTOR 1 #include "scanf.h"
/********************************************************************* @@ -83,6 +103,7 @@ #undef WIDE_SCANF #undef CONSOLE #define STRING 1 +#undef VECTOR #include "scanf.h"
/********************************************************************* @@ -91,6 +112,7 @@ #define WIDE_SCANF 1 #undef CONSOLE #define STRING 1 +#undef VECTOR #include "scanf.h"
/********************************************************************* @@ -99,4 +121,5 @@ #undef WIDE_SCANF #define CONSOLE 1 #undef STRING +#undef VECTOR #include "scanf.h" Index: dlls/msvcrt/scanf.h =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/scanf.h,v retrieving revision 1.14 diff -u -r1.14 scanf.h --- dlls/msvcrt/scanf.h 6 Jan 2004 21:36:10 -0000 1.14 +++ dlls/msvcrt/scanf.h 18 Feb 2004 22:24:44 -0000 @@ -61,6 +61,17 @@ #define _FUNCTION_ MSVCRT_sscanf(const char *file, const char *format, ...) #endif /* WIDE_SCANF */ #else /* STRING */ +#ifdef VECTOR +#ifdef WIDE_SCANF +#define _GETC_(file) (consumed++, MSVCRT_fgetwc(file)) +#define _UNGETC_(nch, file) do { MSVCRT_ungetwc(nch, file); consumed--; } while(0) +#define _FUNCTION_ MSVCRT_vfwscanf(MSVCRT_FILE* file, const MSVCRT_wchar_t *format, va_list ap) +#else /* WIDE_SCANF */ +#define _GETC_(file) (consumed++, MSVCRT_fgetc(file)) +#define _UNGETC_(nch, file) do { MSVCRT_ungetc(nch, file); consumed--; } while(0) +#define _FUNCTION_ MSVCRT_vfscanf(MSVCRT_FILE* file, const char *format, va_list ap) +#endif /* WIDE_SCANF */ +#else #ifdef WIDE_SCANF #define _GETC_(file) (consumed++, MSVCRT_fgetwc(file)) #define _UNGETC_(nch, file) do { MSVCRT_ungetwc(nch, file); consumed--; } while(0) @@ -70,6 +81,7 @@ #define _UNGETC_(nch, file) do { MSVCRT_ungetc(nch, file); consumed--; } while(0) #define _FUNCTION_ MSVCRT_fscanf(MSVCRT_FILE* file, const char *format, ...) #endif /* WIDE_SCANF */ +#endif /* VECTOR */ #endif /* STRING */ #endif /* CONSOLE */
@@ -82,7 +94,9 @@ int _FUNCTION_ { int rd = 0, consumed = 0; int nch; +#ifndef VECTOR va_list ap; +#endif /* VECTOR */ if (!*format) return 0; #ifndef WIDE_SCANF #ifdef CONSOLE @@ -98,7 +112,9 @@ nch = _GETC_(file); if (nch == _EOF_) return _EOF_RET;
+#ifndef VECTOR va_start(ap, format); +#endif /* VECTOR */ while (*format) { /* a whitespace character in the format string causes scanf to read, * but not store, all consecutive white-space characters in the input @@ -512,7 +528,9 @@ if (nch!=_EOF_) { _UNGETC_(nch, file); } +#ifndef VECTOR va_end(ap); +#endif /* VECTOR */ TRACE("returning %d\n", rd); return rd; } Index: include/msvcrt/stdio.h =================================================================== RCS file: /home/wine/wine/include/msvcrt/stdio.h,v retrieving revision 1.15 diff -u -r1.15 stdio.h --- include/msvcrt/stdio.h 24 Oct 2003 00:23:51 -0000 1.15 +++ include/msvcrt/stdio.h 18 Feb 2004 22:24:44 -0000 @@ -184,6 +184,7 @@ MSVCRT(size_t) MSVCRT(fread)(void*,MSVCRT(size_t),MSVCRT(size_t),MSVCRT(FILE)*); MSVCRT(FILE)* MSVCRT(freopen)(const char*,const char*,MSVCRT(FILE)*); int MSVCRT(fscanf)(MSVCRT(FILE)*,const char*,...); +int MSVCRT(fvscanf)(MSVCRT(FILE)*,const char*,va_list); int MSVCRT(fseek)(MSVCRT(FILE)*,long,int); int MSVCRT(fsetpos)(MSVCRT(FILE)*,MSVCRT(fpos_t)*); long MSVCRT(ftell)(MSVCRT(FILE)*); @@ -236,6 +237,7 @@ int MSVCRT(fwprintf)(MSVCRT(FILE)*,const MSVCRT(wchar_t)*,...); int MSVCRT(fputws)(const MSVCRT(wchar_t)*,MSVCRT(FILE)*); int MSVCRT(fwscanf)(MSVCRT(FILE)*,const MSVCRT(wchar_t)*,...); +int MSVCRT(vfwscanf)(MSVCRT(FILE)*,const MSVCRT(wchar_t)*,va_list); MSVCRT(wint_t) MSVCRT(getwc)(MSVCRT(FILE)*); MSVCRT(wint_t) MSVCRT(getwchar)(void); MSVCRT(wchar_t)*MSVCRT(getws)(MSVCRT(wchar_t)*);