Apparently there is a problem with wine's scanf. this code
#include <stdio.h>
int main() { int a; printf ("Type a number\n"); scanf ("%d", &a); printf ("You've entered %d\n", a); return 0; }
works as expected on linux, but on wine returns [ivan@localhost ivan]$ wine test.exe Type a number 5 You've entered 1076166144 [ivan@localhost ivan]$ Dimi thinks it's a bug and asked me to fwd this to wine-devel, a very similar program that has the same problem works on windows, I can't test this one because I do't currently have access to a windows box, but unless I've some badly bugged header or something like that, this is a bug.
a msvcrt.dll trace follows [ivan@localhost ivan]$ wine test.exe --debugmsg +msvcrt trace:msvcrt:DllMain (0x407d0000, DLL_PROCESS_ATTACH, 0x1) pid(8), tid(9), tls(0) trace:msvcrt:msvcrt_init_mt_locks initializing mtlocks trace:msvcrt:msvcrt_init_io :handles (0x14)(0x24)(0x2c) trace:msvcrt:msvcrt_init_console :Opening console handles warn:msvcrt:msvcrt_init_console :Console handle Initialisation FAILED! trace:msvcrt:msvcrt_init_args got 'test.exe', wide = L"test.exe" argc=1 trace:msvcrt:MSVCRT_setlocale (0 C) trace:msvcrt:_lock (19) trace:msvcrt:_lock (17) trace:msvcrt:_lock : creating lock #19 trace:msvcrt:_unlock (17) trace:msvcrt:_unlock (19) trace:msvcrt:DllMain finished process init trace:msvcrt:MSVCRT___set_app_type (1) Console application trace:msvcrt:__getmainargs (0x403000,0x403004,0x407bff10,-1,0x407bff14). trace:msvcrt:_lock (9) trace:msvcrt:_lock (17) trace:msvcrt:_lock : creating lock #9 trace:msvcrt:_unlock (17) trace:msvcrt:_unlock (9) trace:msvcrt:MSVCRT_atexit (0x4013b0) trace:msvcrt:_onexit (0x4013b0) trace:msvcrt:_lock (13) trace:msvcrt:_lock (17) trace:msvcrt:_lock : creating lock #13 trace:msvcrt:_unlock (17) trace:msvcrt:_onexit expanding table trace:msvcrt:_unlock (13) Type a number warn:msvcrt:MSVCRT_fscanf 0x408068e0 ("%d"): semi-stub trace:msvcrt:_read :fd (0) handle (0x14) buf (0x40363f18) len (512) 5 trace:msvcrt:_read :EOF trace:msvcrt:_read "5\n" trace:msvcrt:MSVCRT_fscanf returning 1 You've entered 1076166144 trace:msvcrt:MSVCRT__cexit (void) trace:msvcrt:DllMain (0x407d0000, DLL_PROCESS_DETACH, 0x1) pid(8), tid(9), tls(0) trace:msvcrt:msvcrt_free_mt_locks : uninitializing all mtlocks trace:msvcrt:_fcloseall :closed (0) handles trace:msvcrt:_close :fd (0) handle (0x14) trace:msvcrt:msvcrt_free_fd :fd (0) freed trace:msvcrt:_close :ok trace:msvcrt:_close :fd (1) handle (0x24) trace:msvcrt:msvcrt_free_fd :fd (1) freed trace:msvcrt:_close :ok trace:msvcrt:_close :fd (2) handle (0x2c) trace:msvcrt:msvcrt_free_fd :fd (2) freed trace:msvcrt:_close :ok trace:msvcrt:msvcrt_free_console :Closing console handles trace:msvcrt:DllMain finished process free [ivan@localhost ivan]$
Ivan.
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+
On Wed, 18 Feb 2004, Eric Pouech wrote:
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
Eric, how about a patch for the Janitorial page, so we can keep track of this info?
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)*);