From bdce06f0056cc3987c7c8076af1b0c00fff08ea9 Mon Sep 17 00:00:00 2001 From: Gunnar Dalsnes Date: Wed, 16 Feb 2005 22:30:50 +0000 Subject: [PATCH] ntdll: -critical.c: catch (more) invalid use -impl. sscanf (stolen from wine) crt: -use native mingw headers and not private copies of them -converted some routines to using tchar == impl. many missing unicode routines -impl. sscanf and friends correctly (stolen from wine) tchar.h: -added lotsa missin stuff svn path=/trunk/; revision=13609 --- reactos/lib/crtdll/crtdll.def | 2 +- reactos/lib/crtdll/dllmain.c | 2 +- reactos/lib/msvcrt/dllmain.c | 8 +- reactos/lib/msvcrt/msvcrt.def | 271 +++++++-------- reactos/lib/ntdll/rtl/critical.c | 18 +- reactos/lib/ntdll/stdio/scanf.h | 537 +++++++++++++++++++++++++++++ reactos/lib/ntdll/stdio/sscanf.c | 39 ++- reactos/lib/ntdll/stdlib/bsearch.c | 2 +- reactos/lib/ntdll/stdlib/lfind.c | 4 +- 9 files changed, 736 insertions(+), 147 deletions(-) create mode 100644 reactos/lib/ntdll/stdio/scanf.h diff --git a/reactos/lib/crtdll/crtdll.def b/reactos/lib/crtdll/crtdll.def index 22c89ef9969..f184df937a5 100644 --- a/reactos/lib/crtdll/crtdll.def +++ b/reactos/lib/crtdll/crtdll.def @@ -145,7 +145,7 @@ _findnext _finite _flsbuf _flushall -_fmode_dll=__fmode DATA +_fmode_dll=_fmode DATA _fpclass _fpieee_flt _fpreset diff --git a/reactos/lib/crtdll/dllmain.c b/reactos/lib/crtdll/dllmain.c index 3607c4b9fb1..0b38ee09de4 100644 --- a/reactos/lib/crtdll/dllmain.c +++ b/reactos/lib/crtdll/dllmain.c @@ -22,7 +22,7 @@ #include "precomp.h" #include -#include +#include #include #include diff --git a/reactos/lib/msvcrt/dllmain.c b/reactos/lib/msvcrt/dllmain.c index 091f5ebc09f..5c32a1fdbc4 100644 --- a/reactos/lib/msvcrt/dllmain.c +++ b/reactos/lib/msvcrt/dllmain.c @@ -22,7 +22,7 @@ #include "precomp.h" #include -#include +#include #include #define NDEBUG @@ -66,7 +66,8 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) { case DLL_PROCESS_ATTACH://1 /* initialize version info */ - DPRINT("Attach %d\n", nAttachCount); + //DPRINT1("Process Attach %d\n", nAttachCount); + //DPRINT1("Process Attach\n"); _osver = GetVersion(); _winmajor = (_osver >> 8) & 0xFF; _winminor = _osver & 0xFF; @@ -110,7 +111,8 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) break; case DLL_PROCESS_DETACH://0 - DPRINT("Detach %d\n", nAttachCount); + //DPRINT1("Detach %d\n", nAttachCount); + //DPRINT("Detach\n"); /* FIXME: more cleanup... */ _fcloseall(); diff --git a/reactos/lib/msvcrt/msvcrt.def b/reactos/lib/msvcrt/msvcrt.def index cc17d63d370..1156b11368b 100644 --- a/reactos/lib/msvcrt/msvcrt.def +++ b/reactos/lib/msvcrt/msvcrt.def @@ -92,24 +92,24 @@ _Gettnames _HUGE DATA _Strftime _XcptFilter -;__CxxCallUnwindDtor +__CxxCallUnwindDtor=stub __CxxDetectRethrow -;__CxxExceptionFilter +__CxxExceptionFilter=stub __CxxFrameHandler -;__CxxLongjmpUnwind +__CxxLongjmpUnwind=stub __CxxQueryExceptionSize -;__CxxRegisterExceptionObject -;__CxxUnregisterExceptionObject -;__DestructExceptionObject +__CxxRegisterExceptionObject=stub +__CxxUnregisterExceptionObject=stub +__DestructExceptionObject=stub __RTCastToVoid=MSVCRT___RTCastToVoid __RTDynamicCast=MSVCRT___RTDynamicCast __RTtypeid=MSVCRT___RTtypeid -;__STRINGTOLD +__STRINGTOLD=stub __argc DATA __argv DATA __badioinfo DATA -;__crtCompareStringA ;=NTDLL.RtlCompareString -;__crtGetLocaleInfoW +__crtCompareStringA +__crtGetLocaleInfoW __crtLCMapStringA __dllonexit __doserrno @@ -122,37 +122,37 @@ __iscsymf __lc_codepage __lc_collate_cp __lc_handle -;__lconv_init +__lconv_init __mb_cur_max DATA __p___argc __p___argv -;__p___wargv +__p___wargv __p___initenv __p___mb_cur_max __p___winitenv __p__acmdln -;__p__amblksiz +__p__amblksiz __p__commode -;__p__daylight -;__p__dstbias +__p__daylight +__p__dstbias __p__environ -;__p__fileinfo +__p__fileinfo=stub __p__fmode __p__iob -;__p__mbcasemap -;__p__mbctype +__p__mbcasemap=stub +__p__mbctype=stub __p__osver __p__pctype __p__pgmptr __p__pwctype -;__p__timezone -;__p__tzname -;__p__wcmdln +__p__timezone +__p__tzname=stub +__p__wcmdln=stub __p__wenviron __p__winmajor __p__winminor __p__winver -;__p__wpgmptr +__p__wpgmptr=stub __pioinfo __pxcptinfoptrs __set_app_type @@ -161,65 +161,65 @@ __setusermatherr __threadhandle __threadid __toascii -;__unDName -;__unDNameEx +__unDName=stub +__unDNameEx=stub __unguarded_readlc_active DATA __wargv __wgetmainargs __winitenv -;___lc_codepage_func -;___lc_handle_func -;___mb_cur_max_func -;___setlc_active_func -;___unguarded_readlc_active_add_func -;__crtCompareStringW -;__crtGetStringTypeW -;__crtLCMapStringW -;__iob_func -;__pctype_func -;__uncaught_exception -;__wcserror +___lc_codepage_func=stub +___lc_handle_func=stub +___mb_cur_max_func=stub +___setlc_active_func=stub +___unguarded_readlc_active_add_func=stub +__crtCompareStringW=stub +__crtGetStringTypeW=stub +__crtLCMapStringW=stub +__iob_func=stub +__pctype_func=stub +__uncaught_exception=stub +__wcserror=stub _abnormal_termination _access _acmdln DATA -;_adj_fdiv_m16i +_adj_fdiv_m16i=stub _adj_fdiv_m32 = _adj_fdiv_m32@4 _adj_fdiv_m32i = _adj_fdiv_m32i@4 _adj_fdiv_m64 = _adj_fdiv_m64@8 _adj_fdiv_r -;_adj_fdivr_m16i +_adj_fdivr_m16i=stub _adj_fdivr_m32 = _adj_fdivr_m32@4 _adj_fdivr_m32i = _adj_fdivr_m32i@4 _adj_fdivr_m64 = _adj_fdivr_m64@8 _adj_fpatan -;_adj_fprem -;_adj_fprem1 -;_adj_fptan +_adj_fprem=stub +_adj_fprem1=stub +_adj_fptan=stub _adjust_fdiv DATA _aexit_rtn -;_aligned_free -;_aligned_malloc -;_aligned_offset_malloc -;_aligned_offset_realloc -;_aligned_realloc +_aligned_free=stub +_aligned_malloc=stub +_aligned_offset_malloc=stub +_aligned_offset_realloc=stub +_aligned_realloc=stub _amsg_exit _assert -;_atodbl +_atodbl=stub _atoi64 -;_atoldbl +_atoldbl=stub _beep _beginthread _beginthreadex _c_exit _cabs -;_callnewh +_callnewh=stub _cexit _cgets -;_cgetws +_cgetws=stub _chdir _chdrive _chgsign -;_chkesp +_chkesp=stub _chmod _chsize _clearfp @@ -231,22 +231,22 @@ _controlfp _copysign _cprintf _cputs -;_cputws +_cputws=stub _creat _cscanf -;_ctime64 +_ctime64=stub _ctype DATA _cwait -;_cwprintf -;_cwscanf +_cwprintf=stub +_cwscanf=stub _daylight DATA -;_dstbias +_dstbias=stub _dup _dup2 _ecvt _endthread _endthreadex -;_environ +_environ=stub _eof _errno _except_handler2 @@ -267,21 +267,21 @@ _fdopen _fgetchar _fgetwchar _filbuf -;_fileinfo DATA +_fileinfo=stub DATA _filelength _filelengthi64 _fileno _findclose _findfirst -;_findfirst64 +_findfirst64=stub _findfirsti64 _findnext -;_findnext64 +_findnext64=stub _findnexti64 _finite _flsbuf _flushall -_fmode=__fmode DATA +_fmode DATA _fpclass _fpieee_flt _fpreset @@ -289,17 +289,17 @@ _fputchar _fputwchar _fsopen _fstat -;_fstat64 +_fstat64=stub _fstati64 _ftime -;_ftime64 +_ftime64=stub _ftol=NTDLL._ftol _fullpath _futime -;_futime64 +_futime64=stub _gcvt _get_osfhandle -;_get_sbh_threshold +_get_sbh_threshold=stub _getch _getche _getcwd @@ -308,29 +308,30 @@ _getdiskfree _getdllprocaddr _getdrive _getdrives -;_getmaxstdio -;_getmbcp +_get_heap_handle=stub +_getmaxstdio=stub +_getmbcp=stub _getpid _getsystime _getw -;_getwch -;_getwche -;_getws -;_gmtime64 +_getwch=stub +_getwche=stub +_getws=stub +_gmtime64=stub _global_unwind2 _heapadd _heapchk _heapmin _heapset -;_heapused +_heapused=stub _heapwalk _hypot _i64toa _i64tow _initterm -;_inp -;_inpd -;_inpw +_inp=stub +_inpd=stub +_inpw=stub _iob _isatty _isctype @@ -339,7 +340,7 @@ _ismbbalpha _ismbbgraph _ismbbkalnum _ismbbkana -;_ismbbkprint +_ismbbkprint=stub _ismbbkpunct _ismbblead _ismbbprint @@ -348,7 +349,7 @@ _ismbbtrail _ismbcalnum _ismbcalpha _ismbcdigit -;_ismbcgraph +_ismbcgraph=stub _ismbchira _ismbckata _ismbcl0 @@ -357,7 +358,7 @@ _ismbcl2 _ismbclegal _ismbclower _ismbcprint -;_ismbcpunct +_ismbcpunct=stub _ismbcspace _ismbcsymbol _ismbcupper @@ -370,13 +371,14 @@ _j0 _j1 _jn _kbhit +_localtime64=stub _lfind _loaddll _local_unwind2 _lock _locking _logb -;_longjmpex +_longjmpex=stub _lrotl _lrotr _lsearch @@ -387,7 +389,7 @@ _ltow _makepath _mbbtombc _mbbtype -;_mbcasemap +_mbcasemap=stub _mbccpy _mbcjistojms _mbcjmstojis @@ -444,17 +446,17 @@ _memccpy _memicmp _mkdir _mktemp -;_mktime64 +_mktime64=stub _msize _nextafter _onexit _open _open_osfhandle _osver DATA -;_osplatform -;_outp -;_outpd -;_outpw +_osplatform=stub +_outp=stub +_outpd=stub +_outpw=stub _pclose _pctype DATA _pgmptr DATA @@ -464,38 +466,38 @@ _purecall _putch _putenv _putw -;_putwch +_putwch=stub _putws _pwctype DATA _read -;_resetstkoflw +_resetstkoflw=stub _rmdir _rmtmp _rotl _rotr -;_safe_fdiv -;_safe_fdivr -;_safe_fprem -;_safe_fprem1 +_safe_fdiv=stub +_safe_fdivr=stub +_safe_fprem=stub +_safe_fprem1=stub _scalb -;_scprintf -;_scwprintf +_scprintf=stub +_scwprintf=stub _searchenv _seh_longjmp_unwind=_seh_longjmp_unwind@4 -;_set_error_mode -;_set_SSE2_enable -;_set_sbh_threshold +_set_error_mode=stub +_set_SSE2_enable=stub +_set_sbh_threshold=stub _seterrormode _setjmp _setjmp3 -;_setmaxstdio +_setmaxstdio=stub _setmbcp _setmode _setsystime _sleep _snprintf -;_snscanf -;_snwscanf +_snscanf=stub +_snwscanf=stub _snwprintf _sopen _spawnl @@ -508,7 +510,7 @@ _spawnvp _spawnvpe _splitpath _stat -;_stat64 +_stat64=stub _stati64 _statusfp _strcmpi @@ -525,8 +527,8 @@ _strnset _strrev _strset _strtime -;_strtoi64 -;_strtoui64 +_strtoi64=stub +_strtoui64=stub _strupr _swab _sys_errlist DATA @@ -534,7 +536,7 @@ _sys_nerr DATA _tell _telli64 _tempnam -;_time64 +_time64=stub _timezone DATA _tolower _toupper @@ -546,14 +548,13 @@ _ultoa _ultow _umask _ungetch -;_ungetwch _unlink _unloaddll _unlock _utime -;_utime64 -;_vscprintf -;_vscwprintf +_utime64=stub +_vscprintf=stub +_vscwprintf=stub _vsnprintf _vsnwprintf _waccess @@ -563,7 +564,7 @@ _wchmod _wcmdln _wcreat _wcsdup -;_wcserror +_wcserror=stub _wcsicmp _wcsicoll _wcslwr @@ -573,26 +574,26 @@ _wcsnicoll _wcsnset _wcsrev _wcsset -;_wcstoi64 -;_wcstoui64 -;_wctime64 +_wcstoi64=stub +_wcstoui64=stub +_wctime64=stub _wcsupr _wctime -;_wenviron -;_wexecl -;_wexecle -;_wexeclp -;_wexeclpe -;_wexecv -;_wexecve -;_wexecvp -;_wexecvpe +_wenviron=stub +_wexecl +_wexecle +_wexeclp +_wexeclpe +_wexecv +_wexecve +_wexecvp +_wexecvpe _wfdopen _wfindfirst -;_wfindfirst64 +_wfindfirst64=stub _wfindfirsti64 _wfindnext -;_wfindnext64 +_wfindnext64=stub _wfindnexti64 _wfopen _wfreopen @@ -609,7 +610,7 @@ _wmkdir _wmktemp _wopen _wperror -;_wpgmptr DATA +_wpgmptr=stub DATA _wpopen _wputenv _wremove @@ -617,32 +618,32 @@ _wrename _write _wrmdir _wsearchenv -;_wsetlocale +_wsetlocale=stub _wsopen -;_wspawnl -;_wspawnle -;_wspawnlp -;_wspawnlpe -;_wspawnv -;_wspawnve -;_wspawnvp -;_wspawnvpe +_wspawnl +_wspawnle +_wspawnlp +_wspawnlpe +_wspawnv +_wspawnve +_wspawnvp +_wspawnvpe _wsplitpath _wstat -;_wstat64 +_wstat64=stub _wstati64 _wstrdate _wstrtime -;_wsystem +_wsystem=stub _wtempnam _wtmpnam -;_wtof +_wtof=stub _wtoi _wtoi64 _wtol _wunlink _wutime -;_wutime64 +_wutime64=stub _y0 _y1 _yn diff --git a/reactos/lib/ntdll/rtl/critical.c b/reactos/lib/ntdll/rtl/critical.c index 6da74fc197f..50f01d46b33 100644 --- a/reactos/lib/ntdll/rtl/critical.c +++ b/reactos/lib/ntdll/rtl/critical.c @@ -148,6 +148,13 @@ RtlEnterCriticalSection( CriticalSection->RecursionCount++; return STATUS_SUCCESS; } + else if (CriticalSection->OwningThread == (HANDLE)0) + { + /* No one else owns it either! */ + DPRINT1("Critical section not initialized (guess)!\n"); + /* FIXME: raise exception */ + return STATUS_INVALID_PARAMETER; + } /* We don't own it, so we must wait for it */ RtlpWaitForCriticalSection(CriticalSection); @@ -293,7 +300,16 @@ NTSTATUS STDCALL RtlLeaveCriticalSection( PRTL_CRITICAL_SECTION CriticalSection) -{ +{ + HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread; + + if (Thread != CriticalSection->OwningThread) + { + DPRINT1("Releasing critical section not owned!\n"); + /* FIXME: raise exception */ + return STATUS_INVALID_PARAMETER; + } + /* Decrease the Recursion Count */ if (--CriticalSection->RecursionCount) { diff --git a/reactos/lib/ntdll/stdio/scanf.h b/reactos/lib/ntdll/stdio/scanf.h new file mode 100644 index 00000000000..a8dcde70740 --- /dev/null +++ b/reactos/lib/ntdll/stdio/scanf.h @@ -0,0 +1,537 @@ +/* + * general implementation of scanf used by scanf, sscanf, fscanf, + * _cscanf, wscanf, swscanf and fwscanf + * + * Copyright 1996,1998 Marcus Meissner + * Copyright 1996 Jukka Iivonen + * Copyright 1997,2000, 2003 Uwe Bonnes + * Copyright 2000 Jon Griffiths + * Copyright 2002 Daniel Gudbjartsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef WIDE_SCANF +#define _CHAR_ wchar_t +#define _EOF_ WEOF +#define _EOF_RET WEOF +#define _ISSPACE_(c) iswspace(c) +#define _ISDIGIT_(c) iswdigit(c) +#define _WIDE2SUPPORTED_(c) c /* No conversion needed (wide to wide) */ +#define _CHAR2SUPPORTED_(c) c /* FIXME: convert char to wide char */ +#define _CHAR2DIGIT_(c, base) wchar2digit((c), (base)) +#define _BITMAPSIZE_ 256*256 +#else /* WIDE_SCANF */ +#define _CHAR_ char +#define _EOF_ EOF +#define _EOF_RET EOF +#define _ISSPACE_(c) isspace(c) +#define _ISDIGIT_(c) isdigit(c) +#define _WIDE2SUPPORTED_(c) c /* FIXME: convert wide char to char */ +#define _CHAR2SUPPORTED_(c) c /* No conversion needed (char to char) */ +#define _CHAR2DIGIT_(c, base) char2digit((c), (base)) +#define _BITMAPSIZE_ 256 +#endif /* WIDE_SCANF */ + +#ifdef CONSOLE +#define _GETC_(file) (consumed++, _getch()) +#define _UNGETC_(nch, file) do { _ungetch(nch); consumed--; } while(0) +#define _FUNCTION_ int vcscanf(const char *format, va_list ap) +#else +#ifdef STRING +#undef _EOF_ +#define _EOF_ 0 +#define _GETC_(file) (consumed++, *file++) +#define _UNGETC_(nch, file) do { file--; consumed--; } while(0) +#ifdef WIDE_SCANF +#define _FUNCTION_ int vswscanf(const wchar_t *file, const wchar_t *format, va_list ap) +#else /* WIDE_SCANF */ +#define _FUNCTION_ int vsscanf(const char *file, const char *format, va_list ap) +#endif /* WIDE_SCANF */ +#else /* STRING */ +#ifdef WIDE_SCANF +#define _GETC_(file) (consumed++, fgetwc(file)) +#define _UNGETC_(nch, file) do { ungetwc(nch, file); consumed--; } while(0) +#define _FUNCTION_ int vfwscanf(FILE* file, const wchar_t *format, va_list ap) +#else /* WIDE_SCANF */ +#define _GETC_(file) (consumed++, fgetc(file)) +#define _UNGETC_(nch, file) do { ungetc(nch, file); consumed--; } while(0) +#define _FUNCTION_ int vfscanf(FILE* file, const char *format, va_list ap) +#endif /* WIDE_SCANF */ +#endif /* STRING */ +#endif /* CONSOLE */ + +/********************************************************************* + * Implemented based on + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_format_specification_fields_.2d_.scanf_and_wscanf_functions.asp + * Extended by C. Scott Ananian to handle + * more types of format spec. + */ +_FUNCTION_ { + int rd = 0, consumed = 0; + int nch; + if (!*format) return 0; +#ifndef WIDE_SCANF +#ifdef CONSOLE + TRACE("(%s): \n", debugstr_a(format)); +#else /* CONSOLE */ +#ifdef STRING + TRACE("%s (%s)\n", file, debugstr_a(format)); +#else /* STRING */ + TRACE("%p (%s)\n", file, debugstr_a(format)); +#endif /* STRING */ +#endif /* CONSOLE */ +#endif /* WIDE_SCANF */ + nch = _GETC_(file); + if (nch == _EOF_) return _EOF_RET; + + while (*format) { + /* a whitespace character in the format string causes scanf to read, + * but not store, all consecutive white-space characters in the input + * up to the next non-white-space character. One white space character + * in the input matches any number (including zero) and combination of + * white-space characters in the input. */ + if (_ISSPACE_(*format)) { + /* skip whitespace */ + while ((nch!=_EOF_) && _ISSPACE_(nch)) + nch = _GETC_(file); + } + /* a format specification causes scanf to read and convert characters + * in the input into values of a specified type. The value is assigned + * to an argument in the argument list. Format specifications have + * the form %[*][width][{h | l | I64 | L}]type */ + else if (*format == '%') { + int st = 0; int suppress = 0; int width = 0; + int base, number_signed; + int h_prefix = 0; + int l_prefix = 0; + int L_prefix = 0; + int w_prefix = 0; + int prefix_finished = 0; + int I64_prefix = 0; + format++; + /* look for leading asterisk, which means 'suppress assignment of + * this field'. */ + if (*format=='*') { + format++; + suppress=1; + } + /* look for width specification */ + while (_ISDIGIT_(*format)) { + width*=10; + width+=*format++ - '0'; + } + if (width==0) width=-1; /* no width spec seen */ + /* read prefix (if any) */ + while (!prefix_finished) { + switch(*format) { + case 'h': h_prefix = 1; break; + case 'l': l_prefix = 1; break; + case 'w': w_prefix = 1; break; + case 'L': L_prefix = 1; break; + case 'I': + if (*(format + 1) == '6' && + *(format + 2) == '4') { + I64_prefix = 1; + format += 2; + } + break; + default: + prefix_finished = 1; + } + if (!prefix_finished) format++; + } + /* read type */ + switch(*format) { + case 'x': + case 'X': /* hexadecimal integer. */ + base = 16; number_signed = 0; + goto number; + case 'o': /* octal integer */ + base = 8; number_signed = 0; + goto number; + case 'u': /* unsigned decimal integer */ + base = 10; number_signed = 0; + goto number; + case 'd': /* signed decimal integer */ + base = 10; number_signed = 1; + goto number; + case 'i': /* generic integer */ + base = 10; number_signed = 1; + number: { + /* read an integer */ + ULONGLONG cur = 0; + int negative = 0; + int seendigit=0; + /* skip initial whitespace */ + while ((nch!=_EOF_) && _ISSPACE_(nch)) + nch = _GETC_(file); + /* get sign */ + if (number_signed && (nch == '-' || + nch == '+')) { + negative = (nch=='-'); + nch = _GETC_(file); + if (width>0) width--; + } + /* look for leading indication of base */ + if (width!=0 && nch == '0') { + nch = _GETC_(file); + if (width>0) width--; + seendigit=1; + if (width!=0 && (nch=='x' || nch=='X')) { + if (base==0) + base=16; + if (base==16) { + nch = _GETC_(file); + if (width>0) width--; + seendigit=0; + } + } else if (base==0) + base = 8; + } + /* throw away leading zeros */ + while (width!=0 && nch=='0') { + nch = _GETC_(file); + if (width>0) width--; + seendigit=1; + } + if (width!=0 && _CHAR2DIGIT_(nch, base)!=-1) { + cur = _CHAR2DIGIT_(nch, base); + nch = _GETC_(file); + if (width>0) width--; + seendigit=1; + } + /* read until no more digits */ + while (width!=0 && (nch!=_EOF_) && _CHAR2DIGIT_(nch, base)!=-1) { + cur = cur*base + _CHAR2DIGIT_(nch, base); + nch = _GETC_(file); + if (width>0) width--; + seendigit=1; + } + /* okay, done! */ + if (!seendigit) break; /* not a valid number */ + st = 1; + if (!suppress) { +#define _SET_NUMBER_(type) *va_arg(ap, type*) = negative ? -cur : cur + if (number_signed) { + if (I64_prefix) _SET_NUMBER_(LONGLONG); + else if (l_prefix) _SET_NUMBER_(long int); + else if (h_prefix) _SET_NUMBER_(short int); + else _SET_NUMBER_(int); + } else { + if (negative) { + WARN("Dropping sign in reading a negative number into an unsigned value"); + negative = 0; + } + if (I64_prefix) _SET_NUMBER_(ULONGLONG); + else if (l_prefix) _SET_NUMBER_(unsigned long int); + else if (h_prefix) + _SET_NUMBER_(unsigned short int); + else _SET_NUMBER_(unsigned int); + } + } + } + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': { /* read a float */ + long double cur = 0; + int negative = 0; + /* skip initial whitespace */ + while ((nch!=_EOF_) && _ISSPACE_(nch)) + nch = _GETC_(file); + /* get sign. */ + if (nch == '-' || nch == '+') { + negative = (nch=='-'); + if (width>0) width--; + if (width==0) break; + nch = _GETC_(file); + } + /* get first digit. */ + if ('.' != nch) { + if (!_ISDIGIT_(nch)) break; + cur = (nch - '0'); + nch = _GETC_(file); + if (width>0) width--; + /* read until no more digits */ + while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) { + cur = cur*10 + (nch - '0'); + nch = _GETC_(file); + if (width>0) width--; + } + } else { + cur = 0; /* MaxPayneDemo Fix: .8 -> 0.8 */ + } + /* handle decimals */ + if (width!=0 && nch == '.') { + float dec = 1; + nch = _GETC_(file); + if (width>0) width--; + while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) { + dec /= 10; + cur += dec * (nch - '0'); + nch = _GETC_(file); + if (width>0) width--; + } + } + /* handle exponent */ + if (width!=0 && (nch == 'e' || nch == 'E')) { + int exponent = 0, negexp = 0; + float expcnt; + nch = _GETC_(file); + if (width>0) width--; + /* possible sign on the exponent */ + if (width!=0 && (nch=='+' || nch=='-')) { + negexp = (nch=='-'); + nch = _GETC_(file); + if (width>0) width--; + } + /* exponent digits */ + while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) { + exponent *= 10; + exponent += (nch - '0'); + nch = _GETC_(file); + if (width>0) width--; + } + /* update 'cur' with this exponent. */ + expcnt = negexp ? .1 : 10; + while (exponent!=0) { + if (exponent&1) + cur*=expcnt; + exponent/=2; + expcnt=expcnt*expcnt; + } + } + st = 1; + if (!suppress) { + if (L_prefix) _SET_NUMBER_(long double); + else if (l_prefix) _SET_NUMBER_(double); + else _SET_NUMBER_(float); + } + } + break; + /* According to + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_scanf_type_field_characters.asp + * 's' reads a character string in a call to fscanf + * and 'S' a wide character string and vice versa in a + * call to fwscanf. The 'h', 'w' and 'l' prefixes override + * this behaviour. 'h' forces reading char * but 'l' and 'w' + * force reading WCHAR. */ + case 's': + if (w_prefix || l_prefix) goto widecharstring; + else if (h_prefix) goto charstring; +#ifdef WIDE_SCANF + else goto widecharstring; +#else /* WIDE_SCANF */ + else goto charstring; +#endif /* WIDE_SCANF */ + case 'S': + if (w_prefix || l_prefix) goto widecharstring; + else if (h_prefix) goto charstring; +#ifdef WIDE_SCANF + else goto charstring; +#else /* WIDE_SCANF */ + else goto widecharstring; +#endif /* WIDE_SCANF */ + charstring: { /* read a word into a char */ + char*str = suppress ? NULL : va_arg(ap, char*); + char*sptr = str; + /* skip initial whitespace */ + while ((nch!=_EOF_) && _ISSPACE_(nch)) + nch = _GETC_(file); + /* read until whitespace */ + while (width!=0 && (nch!=_EOF_) && !_ISSPACE_(nch)) { + if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch); + st++; + nch = _GETC_(file); + if (width>0) width--; + } + /* terminate */ + if (!suppress) *sptr = 0; + } + break; + widecharstring: { /* read a word into a wchar_t* */ + wchar_t*str = + suppress ? NULL : va_arg(ap, wchar_t*); + wchar_t*sptr = str; + /* skip initial whitespace */ + while ((nch!=_EOF_) && _ISSPACE_(nch)) + nch = _GETC_(file); + /* read until whitespace */ + while (width!=0 && (nch!=_EOF_) && !_ISSPACE_(nch)) { + if (!suppress) *sptr++ = _WIDE2SUPPORTED_(nch); + st++; + nch = _GETC_(file); + if (width>0) width--; + } + /* terminate */ + if (!suppress) *sptr = 0; + } + break; + /* 'c' and 'C work analogously to 's' and 'S' as described + * above */ + case 'c': + if (w_prefix || l_prefix) goto widecharacter; + else if (h_prefix) goto character; +#ifdef WIDE_SCANF + else goto widecharacter; +#else /* WIDE_SCANF */ + else goto character; +#endif /* WIDE_SCANF */ + case 'C': + if (w_prefix || l_prefix) goto widecharacter; + else if (h_prefix) goto character; +#ifdef WIDE_SCANF + else goto character; +#else /* WIDE_SCANF */ + else goto widecharacter; +#endif /* WIDE_SCANF */ + character: { /* read single character into char */ + if (nch!=_EOF_) { + if (!suppress) { + char*c = va_arg(ap, char*); + *c = _CHAR2SUPPORTED_(nch); + } + st = 1; + nch = _GETC_(file); + } + } + break; + widecharacter: { /* read single character into a wchar_t */ + if (nch!=_EOF_) { + if (!suppress) { + wchar_t*c = va_arg(ap, wchar_t*); + *c = _WIDE2SUPPORTED_(nch); + } + nch = _GETC_(file); + st = 1; + } + } + break; + case 'n': { + if (!suppress) { + int*n = va_arg(ap, int*); + *n = consumed - (nch!=_EOF_); + } + } + break; + case '[': { + _CHAR_ *str = suppress ? NULL : va_arg(ap, _CHAR_*); + _CHAR_ *sptr = str; + RTL_BITMAP bitMask; + ULONG *Mask; + int invert = 0; /* Set if we are NOT to find the chars */ + + /* Init our bitmap */ + Mask = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, _BITMAPSIZE_/8); + RtlInitializeBitMap(&bitMask, Mask, _BITMAPSIZE_); + + /* Read the format */ + format++; + if(*format == '^') { + invert = 1; + format++; + } + if(*format == ']') { + RtlSetBits(&bitMask, ']', 1); + format++; + } + while(*format && (*format != ']')) { + /* According to: + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_scanf_width_specification.asp + * "Note that %[a-z] and %[z-a] are interpreted as equivalent to %[abcde...z]." */ + if((*format == '-') && (*(format + 1) != ']')) { + if ((*(format - 1)) < *(format + 1)) + RtlSetBits(&bitMask, *(format - 1) +1 , *(format + 1) - *(format - 1)); + else + RtlSetBits(&bitMask, *(format + 1) , *(format - 1) - *(format + 1)); + format++; + } else + RtlSetBits(&bitMask, *format, 1); + format++; + } + /* read until char is not suitable */ + while ((width != 0) && (nch != _EOF_)) { + if(!invert) { + if(RtlAreBitsSet(&bitMask, nch, 1)) { + if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch); + } else + break; + } else { + if(RtlAreBitsClear(&bitMask, nch, 1)) { + if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch); + } else + break; + } + st++; + nch = _GETC_(file); + if (width>0) width--; + } + /* terminate */ + if (!suppress) *sptr = 0; + RtlFreeHeap(RtlGetProcessHeap(), 0, Mask); + } + break; + default: + /* From spec: "if a percent sign is followed by a character + * that has no meaning as a format-control character, that + * character and the following characters are treated as + * an ordinary sequence of characters, that is, a sequence + * of characters that must match the input. For example, + * to specify that a percent-sign character is to be input, + * use %%." */ + while ((nch!=_EOF_) && _ISSPACE_(nch)) + nch = _GETC_(file); + if (nch==*format) { + suppress = 1; /* whoops no field to be read */ + st = 1; /* but we got what we expected */ + nch = _GETC_(file); + } + break; + } + if (st && !suppress) rd++; + else if (!st) break; + } + /* a non-white-space character causes scanf to read, but not store, + * a matching non-white-space character. */ + else { + /* check for character match */ + if (nch == *format) { + nch = _GETC_(file); + } else break; + } + format++; + } + if (nch!=_EOF_) { + _UNGETC_(nch, file); + } + TRACE("returning %d\n", rd); + return rd; +} + +#undef _CHAR_ +#undef _EOF_ +#undef _EOF_RET +#undef _ISSPACE_ +#undef _ISDIGIT_ +#undef _CHAR2SUPPORTED_ +#undef _WIDE2SUPPORTED_ +#undef _CHAR2DIGIT_ +#undef _GETC_ +#undef _UNGETC_ +#undef _FUNCTION_ +#undef _BITMAPSIZE_ diff --git a/reactos/lib/ntdll/stdio/sscanf.c b/reactos/lib/ntdll/stdio/sscanf.c index a28d82fa845..88b7b2affa5 100644 --- a/reactos/lib/ntdll/stdio/sscanf.c +++ b/reactos/lib/ntdll/stdio/sscanf.c @@ -1,10 +1,43 @@ /**/ -#include +#include +#include +#include -int sscanf(const char* szReadFrom, const char* szFormat, ...) +#define NDEBUG +#include + + +/* helper function for *scanf. Returns the value of character c in the + * given base, or -1 if the given character is not a digit of the base. + */ +static int char2digit(char c, int base) { + if ((c>='0') && (c<='9') && (c<='0'+base-1)) return (c-'0'); + if (base<=10) return -1; + if ((c>='A') && (c<='Z') && (c<='A'+base-11)) return (c-'A'+10); + if ((c>='a') && (c<='z') && (c<='a'+base-11)) return (c-'a'+10); + return -1; +} + +#define debugstr_a(a) (a) +#define TRACE DPRINT +#define WARN DPRINT1 + +/* vsscanf */ +#undef WIDE_SCANF +#undef CONSOLE +#define STRING 1 +#include "scanf.h" + +int sscanf(const char *str, const char *format, ...) { - return 0; + va_list valist; + int res; + + va_start(valist, format); + res = vsscanf(str, format, valist); + va_end(valist); + return res; } /*EOF */ diff --git a/reactos/lib/ntdll/stdlib/bsearch.c b/reactos/lib/ntdll/stdlib/bsearch.c index 7efbdbd9897..e1e4f11e586 100644 --- a/reactos/lib/ntdll/stdlib/bsearch.c +++ b/reactos/lib/ntdll/stdlib/bsearch.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include /* * @implemented diff --git a/reactos/lib/ntdll/stdlib/lfind.c b/reactos/lib/ntdll/stdlib/lfind.c index 2000fecaffa..2e6e43b0f1e 100644 --- a/reactos/lib/ntdll/stdlib/lfind.c +++ b/reactos/lib/ntdll/stdlib/lfind.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include /*