From eed177f19168b57810ddecec8203387752071ca2 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 4 Jul 2001 16:39:37 +0000 Subject: [PATCH] Added conio functions svn path=/trunk/; revision=2034 --- reactos/include/msvcrt/conio.h | 67 ++ reactos/include/msvcrt/internal/console.h | 11 + reactos/include/msvcrt/internal/stdio.h | 12 + reactos/lib/msvcrt/Makefile | 38 +- reactos/lib/msvcrt/conio/cgets.c | 64 ++ reactos/lib/msvcrt/conio/cprintf.c | 17 + reactos/lib/msvcrt/conio/cputs.c | 23 + reactos/lib/msvcrt/conio/cscanf.c | 18 + reactos/lib/msvcrt/conio/getch.c | 40 + reactos/lib/msvcrt/conio/getche.c | 31 + reactos/lib/msvcrt/conio/kbhit.c | 31 + reactos/lib/msvcrt/conio/putch.c | 21 + reactos/lib/msvcrt/conio/ungetch.c | 29 + reactos/lib/msvcrt/msvcrt.def | 106 +- reactos/lib/msvcrt/stdio/fscanf.c | 59 + reactos/lib/msvcrt/stdio/scanf.c | 58 + reactos/lib/msvcrt/stdio/sscanf.c | 65 ++ reactos/lib/msvcrt/stdio/ungetc.c | 71 ++ reactos/lib/msvcrt/stdio/vfscanf.c | 1200 +++++++++++++++++++++ reactos/lib/msvcrt/stdio/vscanf.c | 33 + reactos/lib/msvcrt/stdio/vsscanf.c | 49 + 21 files changed, 1989 insertions(+), 54 deletions(-) create mode 100644 reactos/include/msvcrt/conio.h create mode 100644 reactos/include/msvcrt/internal/console.h create mode 100644 reactos/include/msvcrt/internal/stdio.h create mode 100644 reactos/lib/msvcrt/conio/cgets.c create mode 100644 reactos/lib/msvcrt/conio/cprintf.c create mode 100644 reactos/lib/msvcrt/conio/cputs.c create mode 100644 reactos/lib/msvcrt/conio/cscanf.c create mode 100644 reactos/lib/msvcrt/conio/getch.c create mode 100644 reactos/lib/msvcrt/conio/getche.c create mode 100644 reactos/lib/msvcrt/conio/kbhit.c create mode 100644 reactos/lib/msvcrt/conio/putch.c create mode 100644 reactos/lib/msvcrt/conio/ungetch.c create mode 100644 reactos/lib/msvcrt/stdio/fscanf.c create mode 100644 reactos/lib/msvcrt/stdio/scanf.c create mode 100644 reactos/lib/msvcrt/stdio/sscanf.c create mode 100644 reactos/lib/msvcrt/stdio/ungetc.c create mode 100644 reactos/lib/msvcrt/stdio/vfscanf.c create mode 100644 reactos/lib/msvcrt/stdio/vscanf.c create mode 100644 reactos/lib/msvcrt/stdio/vsscanf.c diff --git a/reactos/include/msvcrt/conio.h b/reactos/include/msvcrt/conio.h new file mode 100644 index 00000000000..ed6dd14cbf0 --- /dev/null +++ b/reactos/include/msvcrt/conio.h @@ -0,0 +1,67 @@ +/* + * conio.h + * + * Low level console I/O functions. Pretty please try to use the ANSI + * standard ones if you are writing new code. + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Colin Peters + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * $Revision: 1.1 $ + * $Author: ekohl $ + * $Date: 2001/07/04 16:31:14 $ + * + */ + +#ifndef __STRICT_ANSI__ + +#ifndef _CONIO_H_ +#define _CONIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +char* _cgets (char* szBuffer); +int _cprintf (const char* szFormat, ...); +int _cputs (const char* szString); +int _cscanf (char* szFormat, ...); + +int _getch (void); +int _getche (void); +int _kbhit (void); +int _putch (int cPut); +int _ungetch (int cUnget); + + +#ifndef _NO_OLDNAMES + +#define getch _getch +#define getche _getche +#define kbhit _kbhit +#define putch(cPut) _putch(cPut) +#define ungetch(cUnget) _ungetch(cUnget) + +#endif /* Not _NO_OLDNAMES */ + + +#ifdef __cplusplus +} +#endif + +#endif /* Not _CONIO_H_ */ + +#endif /* Not __STRICT_ANSI__ */ diff --git a/reactos/include/msvcrt/internal/console.h b/reactos/include/msvcrt/internal/console.h new file mode 100644 index 00000000000..0fc6c13a046 --- /dev/null +++ b/reactos/include/msvcrt/internal/console.h @@ -0,0 +1,11 @@ +/* console.h */ + +#ifndef __MSVCRT_INTERNAL_CONSOLE_H +#define __MSVCRT_INTERNAL_CONSOLE_H + +extern int char_avail; +extern int ungot_char; + +#endif /* __MSVCRT_INTERNAL_CONSOLE_H */ + +/* EOF */ \ No newline at end of file diff --git a/reactos/include/msvcrt/internal/stdio.h b/reactos/include/msvcrt/internal/stdio.h new file mode 100644 index 00000000000..e4025529a49 --- /dev/null +++ b/reactos/include/msvcrt/internal/stdio.h @@ -0,0 +1,12 @@ +/* stdio.h */ + +#ifndef __MSVCRT_INTERNAL_STDIO_H +#define __MSVCRT_INTERNAL_STDIO_H + +int __vfscanf (FILE *s, const char *format, va_list argptr); +int __vscanf (const char *format, va_list arg); +int __vsscanf (const char *s,const char *format,va_list arg); + +#endif /* __MSVCRT_INTERNAL_STDIO_H */ + +/* EOF */ \ No newline at end of file diff --git a/reactos/lib/msvcrt/Makefile b/reactos/lib/msvcrt/Makefile index aedcdc2c85e..11e701fc474 100644 --- a/reactos/lib/msvcrt/Makefile +++ b/reactos/lib/msvcrt/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.12 2001/07/02 21:51:18 ekohl Exp $ +# $Id: Makefile,v 1.13 2001/07/04 16:39:36 ekohl Exp $ # # ReactOS Operating System # @@ -12,6 +12,17 @@ CFLAGS = -I../../include -D__MSVCRT__ all: $(TARGET_DLL) +OBJECTS_CONIO = \ + conio/cgets.o \ + conio/cprintf.o \ + conio/cputs.o \ + conio/cscanf.o \ + conio/getch.o \ + conio/getche.o \ + conio/kbhit.o \ + conio/putch.o \ + conio/ungetch.o + OBJECTS_CTYPE = \ ctype/isalnum.o \ ctype/isalpha.o \ @@ -65,16 +76,30 @@ OBJECTS_FLOAT = \ OBJECTS_IO = \ io/access.o \ + io/chmod.o \ + io/chsize.o \ io/close.o \ io/commit.o \ + io/create.o \ + io/dup.o \ + io/dup2.o \ + io/eof.o \ + io/filelen.o \ + io/find.o \ io/fmode.o \ io/isatty.o \ + io/locking.o \ io/lseek.o \ io/mktemp.o \ io/open.o \ + io/pipe.o \ io/read.o \ io/setmode.o \ + io/sopen.o \ + io/tell.o \ + io/umask.o \ io/unlink.o \ + io/utime.o \ io/write.o OBJECTS_MATH = \ @@ -115,6 +140,7 @@ OBJECTS_STDIO = \ stdio/fputc.o \ stdio/fputs.o \ stdio/fread.o \ + stdio/fscanf.o \ stdio/fwalk.o \ stdio/fwrite.o \ stdio/getc.o \ @@ -123,14 +149,20 @@ OBJECTS_STDIO = \ stdio/putchar.o \ stdio/puts.o \ stdio/remove.o \ + stdio/scanf.o \ stdio/setvbuf.o \ stdio/sprintf.o \ + stdio/sscanf.o \ stdio/stdhnd.o \ stdio/tempnam.o \ + stdio/ungetc.o \ stdio/vfprintf.o \ + stdio/vfscanf.o \ stdio/vfwprint.o \ stdio/vprintf.o \ + stdio/vscanf.o \ stdio/vsprintf.o \ + stdio/vsscanf.o #incomplete OBJECTS_STDLIB = \ @@ -206,6 +238,7 @@ OBJECTS_STRING = \ OBJECTS_SYS_STAT = \ sys_stat/fstat.o \ + sys_stat/futime.o \ sys_stat/stat.o OBJECTS_TIME = \ @@ -239,6 +272,7 @@ OBJECTS_WSTRING = \ wstring/wcsxfrm.o OBJECTS = \ + $(OBJECTS_CONIO) \ $(OBJECTS_CTYPE) \ $(OBJECTS_DIRECT) \ $(OBJECTS_EXCEPT) \ @@ -258,6 +292,7 @@ OBJECTS = \ ifeq ($(DOSCLI), yes) CLEAN_FILES = \ + conio\*.o \ ctype\*.o \ direct\*.o \ float\*.o \ @@ -280,6 +315,7 @@ CLEAN_FILES = \ base.tmp else CLEAN_FILES = \ + conio/*.o \ ctype/*.o \ direct/*.o \ float/*.o \ diff --git a/reactos/lib/msvcrt/conio/cgets.c b/reactos/lib/msvcrt/conio/cgets.c new file mode 100644 index 00000000000..71645d07365 --- /dev/null +++ b/reactos/lib/msvcrt/conio/cgets.c @@ -0,0 +1,64 @@ +#include +#include + + +char *_cgets(char *string) +{ + unsigned len = 0; + unsigned int maxlen_wanted; + char *sp; + int c; + /* + * Be smart and check for NULL pointer. + * Don't know wether TURBOC does this. + */ + if (!string) + return(NULL); + maxlen_wanted = (unsigned int)((unsigned char)string[0]); + sp = &(string[2]); + /* + * Should the string be shorter maxlen_wanted including or excluding + * the trailing '\0' ? We don't take any risk. + */ + while(len < maxlen_wanted-1) + { + c=_getch(); + /* + * shold we check for backspace here? + * TURBOC does (just checked) but doesn't in cscanf (thats harder + * or even impossible). We do the same. + */ + if (c == '\b') + { + if (len > 0) + { + _cputs("\b \b"); /* go back, clear char on screen with space + and go back again */ + len--; + sp[len] = '\0'; /* clear the character in the string */ + } + } + else if (c == '\r') + { + sp[len] = '\0'; + break; + } + else if (c == 0) + { + /* special character ends input */ + sp[len] = '\0'; + _ungetch(c); /* keep the char for later processing */ + break; + } + else + { + sp[len] = _putch(c); + len++; + } + } + sp[maxlen_wanted-1] = '\0'; + string[1] = (char)((unsigned char)len); + return(sp); +} + + diff --git a/reactos/lib/msvcrt/conio/cprintf.c b/reactos/lib/msvcrt/conio/cprintf.c new file mode 100644 index 00000000000..da3ca0c8d6b --- /dev/null +++ b/reactos/lib/msvcrt/conio/cprintf.c @@ -0,0 +1,17 @@ +#include +#include + +int +_cprintf(const char *fmt, ...) +{ + int cnt; + char buf[ 2048 ]; /* this is buggy, because buffer might be too small. */ + va_list ap; + + va_start(ap, fmt); + cnt = vsprintf(buf, fmt, ap); + va_end(ap); + + _cputs(buf); + return cnt; +} diff --git a/reactos/lib/msvcrt/conio/cputs.c b/reactos/lib/msvcrt/conio/cputs.c new file mode 100644 index 00000000000..396c71eee61 --- /dev/null +++ b/reactos/lib/msvcrt/conio/cputs.c @@ -0,0 +1,23 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/crtdll/conio/cputs.c + * PURPOSE: Writes a character to stdout + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include +#include +#include +#include + +int _cputs(const char *_str) +{ + int len = strlen(_str); + DWORD written = 0; + if (!WriteFile(filehnd(stdout->_file),_str,len,&written,NULL)) + return -1; + return 0; +} diff --git a/reactos/lib/msvcrt/conio/cscanf.c b/reactos/lib/msvcrt/conio/cscanf.c new file mode 100644 index 00000000000..58e01d99e2a --- /dev/null +++ b/reactos/lib/msvcrt/conio/cscanf.c @@ -0,0 +1,18 @@ +#include +#include +#include + +int _cscanf(char *fmt, ...) +{ + int cnt; + va_list ap; + + //fixme cscanf should scan the console's keyboard + va_start(ap, fmt); + cnt = __vscanf(fmt, ap); + va_end(ap); + + return cnt; +} + + diff --git a/reactos/lib/msvcrt/conio/getch.c b/reactos/lib/msvcrt/conio/getch.c new file mode 100644 index 00000000000..15d2eb6e8db --- /dev/null +++ b/reactos/lib/msvcrt/conio/getch.c @@ -0,0 +1,40 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/crtdll/conio/getch.c + * PURPOSE: Writes a character to stdout + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include +#include +#include +#include + + +int _getch(void) +{ + DWORD NumberOfCharsRead = 0; + char c; + + if (char_avail) + { + c = ungot_char; + char_avail = 0; + } + else + { + ReadConsoleA(_get_osfhandle(stdin->_file), + &c, + 1, + &NumberOfCharsRead, + NULL); + } + if (c == 10) + c = 13; + putchar(c); + + return c; +} diff --git a/reactos/lib/msvcrt/conio/getche.c b/reactos/lib/msvcrt/conio/getche.c new file mode 100644 index 00000000000..f994649e73d --- /dev/null +++ b/reactos/lib/msvcrt/conio/getche.c @@ -0,0 +1,31 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * PROJECT: ReactOS system libraries + * FILE: lib/crtdll/conio/getche.c + * PURPOSE: Reads a character from stdin + * PROGRAMER: DJ Delorie + Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ + +#include +#include + + +int getche(void) +{ + if (char_avail) + /* + * We don't know, wether the ungot char was already echoed + * we assume yes (for example in cscanf, probably the only + * place where ungetch is ever called. + * There is no way to check for this really, because + * ungetch could have been called with a character that + * hasn't been got by a conio function. + * We don't echo again. + */ + return(getch()); + return (_putch(getch())); +} diff --git a/reactos/lib/msvcrt/conio/kbhit.c b/reactos/lib/msvcrt/conio/kbhit.c new file mode 100644 index 00000000000..876099fa746 --- /dev/null +++ b/reactos/lib/msvcrt/conio/kbhit.c @@ -0,0 +1,31 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/crtdll/conio/kbhit.c + * PURPOSE: Checks for keyboard hits + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ + +#include +#include +#include + + +// FIXME PeekCosoleInput returns more than keyboard hits + +int _kbhit(void) +{ + INPUT_RECORD InputRecord; + DWORD NumberRead=0; + if (char_avail) + return(1); + else + { + //FIXME PeekConsoleInput might do DeviceIo + //PeekConsoleInput((HANDLE)stdin->_file,&InputRecord,1,&NumberRead); + return NumberRead; + } + return 0; +} diff --git a/reactos/lib/msvcrt/conio/putch.c b/reactos/lib/msvcrt/conio/putch.c new file mode 100644 index 00000000000..5f370136593 --- /dev/null +++ b/reactos/lib/msvcrt/conio/putch.c @@ -0,0 +1,21 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/crtdll/conio/putch.c + * PURPOSE: Writes a character to stdout + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include + +int _putch(int c) +{ + DWORD NumberOfCharsWritten; + + if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),&c,1,&NumberOfCharsWritten,NULL)) + return -1; + + return NumberOfCharsWritten; +} diff --git a/reactos/lib/msvcrt/conio/ungetch.c b/reactos/lib/msvcrt/conio/ungetch.c new file mode 100644 index 00000000000..8b974bb85fc --- /dev/null +++ b/reactos/lib/msvcrt/conio/ungetch.c @@ -0,0 +1,29 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * PROJECT: ReactOS system libraries + * FILE: lib/crtdll/conio/ungetch.c + * PURPOSE: Ungets a character from stdin + * PROGRAMER: DJ Delorie + Boudewijn Dekker [ Adapted from djgpp libc ] + * UPDATE HISTORY: + * 28/12/98: Created + */ + +#include +#include + +#define EOF -1 + +int char_avail = 0; +int ungot_char = 0; + + +int _ungetch(int c) +{ + if (char_avail) + return(EOF); + ungot_char = c; + char_avail = 1; + return(c); +} diff --git a/reactos/lib/msvcrt/msvcrt.def b/reactos/lib/msvcrt/msvcrt.def index 175b485e561..6e5f3ce6758 100644 --- a/reactos/lib/msvcrt/msvcrt.def +++ b/reactos/lib/msvcrt/msvcrt.def @@ -1,4 +1,4 @@ -; $Id: msvcrt.def,v 1.8 2001/07/03 13:21:22 ekohl Exp $ +; $Id: msvcrt.def,v 1.9 2001/07/04 16:39:37 ekohl Exp $ ; ; ReactOS MSVCRT Compatibility Library ; @@ -181,13 +181,13 @@ _c_exit ; _cabs ; _callnewh _cexit -; _cgets +_cgets _chdir _chdrive _chgsign ; _chkesp -; _chmod -; _chsize +_chmod +_chsize _clearfp _close _commit @@ -195,21 +195,21 @@ _commode DATA _control87 _controlfp _copysign -; _cprintf -; _cputs -; _creat -; _cscanf +_cprintf +_cputs +_creat +_cscanf _ctype DATA ; _cwait ; _daylight ; _dstbias -; _dup -; _dup2 +_dup +_dup2 ; _ecvt _endthread _endthreadex _environ_dll DATA -; _eof +_eof _errno _except_handler2 _except_handler3 @@ -230,14 +230,14 @@ _fcloseall ; _fgetwchar _filbuf ; _fileinfo -; _filelength -; _filelengthi64 +_filelength +_filelengthi64 _fileno -; _findclose -; _findfirst -; _findfirsti64 -; _findnext -; _findnexti64 +_findclose +_findfirst +_findfirsti64 +_findnext +_findnexti64 _finite _flsbuf _flushall @@ -249,16 +249,16 @@ _fpreset ; _fputwchar ; _fsopen _fstat -; _fstati64 +_fstati64 ; _ftime ; _ftol _fullpath -; _futime +_futime ; _gcvt _get_osfhandle ; _get_sbh_threshold -; _getch -; _getche +_getch +_getche _getcwd _getdcwd _getdiskfree @@ -323,19 +323,19 @@ _itow ; _j0 ; _j1 ; _jn -; _kbhit +_kbhit ; _lfind _loaddll _local_unwind2 ; _lock -; _locking +_locking _logb ; _longjmpex _lrotl _lrotr ; _lsearch _lseek -; _lseeki64 +_lseeki64 _ltoa _ltow _makepath @@ -410,10 +410,10 @@ _osver DATA ; _pclose _pctype DATA _pgmptr DATA -; _pipe +_pipe ; _popen _purecall -; _putch +_putch _putenv ; _putw _putws @@ -442,7 +442,7 @@ _setmode _sleep _snprintf _snwprintf -; _sopen +_sopen ; _spawnl ; _spawnle ; _spawnlp @@ -453,7 +453,7 @@ _snwprintf ; _spawnvpe _splitpath _stat -; _stati64 +_stati64 _statusfp _strcmpi ; _strdate @@ -473,8 +473,8 @@ _strupr _swab _sys_errlist DATA _sys_nerr DATA -; _tell -; _telli64 +_tell +_telli64 _tempnam ; _timezone _tolower @@ -485,20 +485,20 @@ _ui64toa _ui64tow _ultoa _ultow -; _umask -; _ungetch +_umask +_ungetch _unlink _unloaddll ; _unlock -; _utime +_utime _vsnprintf _vsnwprintf _waccess ; _wasctime _wchdir -; _wchmod +_wchmod ; _wcmdln -; _wcreat +_wcreat _wcsdup _wcsicmp _wcsicoll @@ -521,10 +521,10 @@ _wcsupr ; _wexecvp ; _wexecvpe ; _wfdopen -; _wfindfirst -; _wfindfirsti64 -; _wfindnext -; _wfindnexti64 +_wfindfirst +_wfindfirsti64 +_wfindnext +_wfindnexti64 ; _wfopen ; _wfreopen ; _wfsopen @@ -549,7 +549,7 @@ _write _wrmdir _wsearchenv ; _wsetlocale -; _wsopen +_wsopen ; _wspawnl ; _wspawnle ; _wspawnlp @@ -559,8 +559,8 @@ _wsearchenv ; _wspawnvp ; _wspawnvpe _wsplitpath -; _wstat -; _wstati64 +_wstat +_wstati64 ; _wstrdate ; _wstrtime ; _wsystem @@ -569,8 +569,8 @@ _wsplitpath _wtoi _wtoi64 _wtol -; _wunlink -; _wutime +_wunlink +_wutime ; _y0 ; _y1 ; _yn @@ -619,13 +619,13 @@ fread free ; freopen ; frexp -; fscanf +fscanf ; fseek ; fsetpos ; ftell fwprintf fwrite -; fwscanf +fwscanf getc ; getchar getenv @@ -693,7 +693,7 @@ realloc remove ; rename ; rewind -; scanf +scanf ; setbuf ; setlocale setvbuf @@ -703,7 +703,7 @@ signal sprintf ; sqrt ; srand -; sscanf +sscanf strcat strchr strcmp @@ -726,7 +726,7 @@ strtol strtoul strxfrm swprintf -; swscanf +swscanf ; system ; tan ; tanh @@ -737,8 +737,8 @@ tolower toupper towlower towupper -; ungetc -; ungetwc +ungetc +ungetwc vfprintf vfwprintf vprintf @@ -768,6 +768,6 @@ wcstoul wcsxfrm ; wctomb wprintf -; wscanf +wscanf ; EOF diff --git a/reactos/lib/msvcrt/stdio/fscanf.c b/reactos/lib/msvcrt/stdio/fscanf.c new file mode 100644 index 00000000000..0187334b893 --- /dev/null +++ b/reactos/lib/msvcrt/stdio/fscanf.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + + +#include +#include +#include +#include +#include + + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int fscanf(FILE *stream,const char *format, ...) +{ + va_list arg; + int done; + + va_start(arg, format); + done = __vfscanf(stream, format, arg); + va_end(arg); + + return done; +} + +int +fwscanf(FILE *stream, const wchar_t *fmt, ...) +{ + va_list arg; + int done; + char *cf; + int i,len = wcslen(fmt); + + cf = malloc(len+1); + for(i=0;i +#include +#include +#include +#include + + +/* Read formatted input from stdin according to the format string FORMAT. */ +/* VARARGS1 */ +int scanf(const char *format, ...) +{ + va_list arg; + int done; + + va_start(arg, format); + done = __vscanf(format, arg); + va_end(arg); + + return done; +} + +int +wscanf(const wchar_t *fmt, ...) +{ + va_list arg; + int done; + char *f; + int i, len = wcslen(fmt); + + f = malloc(len+1); + for(i=0;i +#include +#include +#include +#include + + +/* Read formatted input from S, according to the format string FORMAT. */ +/* VARARGS2 */ +int sscanf (const char *s,const char *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vsscanf (s, format, arg); + va_end (arg); + + return done; +} + +int swscanf(const wchar_t *str, const wchar_t *fmt, ...) +{ + va_list arg; + int done; + char *f , *s; + int i,len = wcslen(fmt); + + f = malloc(len+1); + for(i=0;i +#include +#include +#include + +int ungetc(int c, FILE *f) +{ + if (!__validfp (f) || !OPEN4READING(f)) + { + __set_errno (EINVAL); + return EOF; + } + + if (c == EOF) + return EOF; + + if (f->_ptr == NULL || f->_base == NULL) + return EOF; + + if (f->_ptr == f->_base) + { + if (f->_cnt == 0) + f->_ptr++; + else + return EOF; + } + + f->_cnt++; + f->_ptr--; + if (*f->_ptr != c) + { + f->_flag |= _IOUNGETC; + *f->_ptr = c; + } + return c; +} + + +wint_t +ungetwc(wchar_t c, FILE *f) +{ + if (!__validfp (f) || !OPEN4READING(f)) + { + __set_errno(EINVAL); + return EOF; + } + + if (c == (wchar_t)EOF) + return EOF; + + if (f->_ptr == NULL || f->_base == NULL) + return EOF; + + if (f->_ptr == f->_base) + { + if (f->_cnt == 0) + f->_ptr+=sizeof(wchar_t); + else + return EOF; + } + + f->_cnt+=sizeof(wchar_t); + f->_ptr-=sizeof(wchar_t); + + f->_flag |= _IOUNGETC; + *((wchar_t *)(f->_ptr)) = c; + + return c; +} diff --git a/reactos/lib/msvcrt/stdio/vfscanf.c b/reactos/lib/msvcrt/stdio/vfscanf.c new file mode 100644 index 00000000000..a802416483d --- /dev/null +++ b/reactos/lib/msvcrt/stdio/vfscanf.c @@ -0,0 +1,1200 @@ +/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The internal entry points for `strtoX' take an extra flag argument + saying whether or not to parse locale-dependent number grouping. */ + +double __strtod_internal (const char *__nptr,char **__endptr, int __group); +float __strtof_internal (const char *__nptr, char **__endptr,int __group); +long double __strtold_internal (const char *__nptr,char **__endptr, int __group); +long int __strtol_internal (const char *__nptr, char **__endptr, int __base, int __group); +unsigned long int __strtoul_internal (const char *__nptr, char **__endptr, int __base, int __group); + + + +#ifdef __GNUC__ +#define HAVE_LONGLONG +#define LONGLONG long long +#else +#define LONGLONG long +#endif + +/* Those are flags in the conversion format. */ +# define LONG 0x001 /* l: long or double */ +# define LONGDBL 0x002 /* L: long long or long double */ +# define SHORT 0x004 /* h: short */ +# define SUPPRESS 0x008 /* *: suppress assignment */ +# define POINTER 0x010 /* weird %p pointer (`fake hex') */ +# define NOSKIP 0x020 /* do not skip blanks */ +# define WIDTH 0x040 /* width was given */ +# define GROUP 0x080 /* ': group numbers */ +# define MALLOC 0x100 /* a: malloc strings */ + +# define TYPEMOD (LONG|LONGDBL|SHORT) + + +# define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s)) +# define inchar() ((c = getc (s)), (void) (c != EOF && ++read_in), c) +# define encode_error() do { \ + funlockfile (s); \ + __set_errno (EILSEQ); \ + return done; \ + } while (0) +# define conv_error() do { \ + funlockfile (s); \ + return done; \ + } while (0) +# define input_error() do { \ + funlockfile (s); \ + return done ? 0 : EOF; \ + } while (0) +# define memory_error() do { \ + funlockfile (s); \ + __set_errno (ENOMEM); \ + return EOF; \ + } while (0) +# define ARGCHECK(s, format) \ + do \ + { \ + /* Check file argument for consistence. */ \ + if (!__validfp (s) || !s->__mode.__read) \ + { \ + __set_errno (EBADF); \ + return EOF; \ + } \ + else if (format == NULL) \ + { \ + __set_errno (EINVAL); \ + return EOF; \ + } \ + } while (0) + +# define flockfile(S) /* nothing */ +# define funlockfile(S) /* nothing */ + + char *wp = NULL; /* Workspace. */ + size_t wpmax = 0; /* Maximal size of workspace. */ + size_t wpsize = 0; /* Currently used bytes in workspace. */ + + +void ADDW(int Ch) \ +{ + if (wpsize == wpmax) + { + char *old = wp; + wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax; + wp = (char *) malloc (wpmax); + if (old != NULL) + { + memcpy (wp, old, wpsize); + free(old); + } + } + wp[wpsize++] = (Ch); +} + + +int __vfscanf (FILE *s, const char *format, va_list argptr) +{ + va_list arg; + register const char *f = format; + register unsigned char fc; /* Current character of the format. */ + register size_t done = 0; /* Assignments done. */ + register size_t read_in = 0; /* Chars read in. */ + register int c = 0; /* Last char read. */ + register int width; /* Maximum field width. */ + register int flags; /* Modifiers for current format element. */ + + /* Status for reading F-P nums. */ + char got_dot, got_e, negative; + /* If a [...] is a [^...]. */ + char not_in; + /* Base for integral numbers. */ + int base; + /* Signedness for integral numbers. */ + int number_signed; + /* Decimal point character. */ + wchar_t decimal = '.'; + /* The thousands character of the current locale. */ + wchar_t thousands = ','; + /* Integral holding variables. */ + union + { + long long int q; + unsigned long long int uq; + long int l; + unsigned long int ul; + } num; + /* Character-buffer pointer. */ + char *str = NULL; + wchar_t *wstr = NULL; + char **strptr = NULL; + size_t strsize = 0; + /* We must not react on white spaces immediately because they can + possibly be matched even if in the input stream no character is + available anymore. */ + int skip_space = 0; + /* Workspace. */ + char *tw; /* Temporary pointer. */ + +#ifdef __va_copy + __va_copy (arg, argptr); +#else + arg = (va_list) argptr; +#endif + + + + /* Run through the format string. */ + while (*f != '\0') + { + unsigned int argpos; + /* Extract the next argument, which is of type TYPE. + For a %N$... spec, this is the Nth argument from the beginning; + otherwise it is the next argument after the state now in ARG. */ +#define ARG(type) va_arg(argptr,type) + + if (!isascii (*f)) + { + /* Non-ASCII, may be a multibyte. */ + // int len = mblen (f, strlen (f)); + int len =1; + if (len > 0) + { + do + { + c = inchar (); + if (c == EOF) + input_error (); + else if (c != *f++) + { + ungetc (c, s); + conv_error (); + } + } + while (--len > 0); + continue; + } + } + + fc = *f++; + if (fc != '%') + { + /* Remember to skip spaces. */ + if (isspace (fc)) + { + skip_space = 1; + continue; + } + + /* Read a character. */ + c = inchar (); + + /* Characters other than format specs must just match. */ + if (c == EOF) + input_error (); + + /* We saw white space char as the last character in the format + string. Now it's time to skip all leading white space. */ + if (skip_space) + { + while (isspace (c)) + if (inchar () == EOF && errno == EINTR) + conv_error (); + skip_space = 0; + } + + if (c != fc) + { + ungetc (c, s); + conv_error (); + } + + continue; + } + + /* This is the start of the conversion string. */ + flags = 0; + + /* Initialize state of modifiers. */ + argpos = 0; + + /* Prepare temporary buffer. */ + wpsize = 0; + + /* Check for a positional parameter specification. */ + if (isdigit (*f)) + { + argpos = *f++ - '0'; + while (isdigit (*f)) + argpos = argpos * 10 + (*f++ - '0'); + if (*f == '$') + ++f; + else + { + /* Oops; that was actually the field width. */ + width = argpos; + flags |= WIDTH; + argpos = 0; + goto got_width; + } + } + + /* Check for the assignment-suppressing and the number grouping flag. */ + while (*f == '*' || *f == '\'') + switch (*f++) + { + case '*': + flags |= SUPPRESS; + break; + case '\'': + flags |= GROUP; + break; + } + + /* We have seen width. */ + if (isdigit (*f)) + flags |= WIDTH; + + /* Find the maximum field width. */ + width = 0; + while (isdigit (*f)) + { + width *= 10; + width += *f++ - '0'; + } + got_width: + if (width == 0) + width = -1; + + /* Check for type modifiers. */ + while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a' || *f == 'q') + switch (*f++) + { + case 'h': + /* int's are short int's. */ + if (flags & TYPEMOD) + /* Signal illegal format element. */ + conv_error (); + flags |= SHORT; + break; + case 'l': + if (flags & (SHORT|LONGDBL)) + conv_error (); + else if (flags & LONG) + { + /* A double `l' is equivalent to an `L'. */ + flags &= ~LONG; + flags |= LONGDBL; + } + else + /* int's are long int's. */ + flags |= LONG; + break; + case 'q': + case 'L': + /* double's are long double's, and int's are long long int's. */ + if (flags & TYPEMOD) + /* Signal illegal format element. */ + conv_error (); + flags |= LONGDBL; + break; + case 'a': + if (flags & TYPEMOD) + /* Signal illegal format element. */ + conv_error (); + /* String conversions (%s, %[) take a `char **' + arg and fill it in with a malloc'd pointer. */ + flags |= MALLOC; + break; + } + + /* End of the format string? */ + if (*f == '\0') + conv_error (); + + /* We must take care for EINTR errors. */ + if (c == EOF && errno == EINTR) + input_error (); + + /* Find the conversion specifier. */ + fc = *f++; + if (skip_space || (fc != '[' && fc != 'c' && fc != 'C' && fc != 'n')) + { + /* Eat whitespace. */ + do + if (inchar () == EOF && errno == EINTR) + input_error (); + while (isspace (c)); + ungetc (c, s); + skip_space = 0; + } + + switch (fc) + { + case '%': /* Must match a literal '%'. */ + c = inchar (); + if (c != fc) + { + ungetc (c, s); + conv_error (); + } + break; + + case 'n': /* Answer number of assignments done. */ + /* Corrigendum 1 to ISO C 1990 describes the allowed flags + with the 'n' conversion specifier. */ + if (!(flags & SUPPRESS)) + { + /* Don't count the read-ahead. */ + if (flags & LONGDBL) + *ARG (long int *) = read_in; + else if (flags & LONG) + *ARG (long int *) = read_in; + else if (flags & SHORT) + *ARG (short int *) = read_in; + else + *ARG (int *) = read_in; + +#ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1 + /* We have a severe problem here. The ISO C standard + contradicts itself in explaining the effect of the %n + format in `scanf'. While in ISO C:1990 and the ISO C + Amendement 1:1995 the result is described as + + Execution of a %n directive does not effect the + assignment count returned at the completion of + execution of the f(w)scanf function. + + in ISO C Corrigendum 1:1994 the following was added: + + Subclause 7.9.6.2 + Add the following fourth example: + In: + #include + int d1, d2, n1, n2, i; + i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2); + the value 123 is assigned to d1 and the value3 to n1. + Because %n can never get an input failure the value + of 3 is also assigned to n2. The value of d2 is not + affected. The value 3 is assigned to i. + + We go for now with the historically correct code fro ISO C, + i.e., we don't count the %n assignments. When it ever + should proof to be wrong just remove the #ifdef above. */ + ++done; +#endif + } + break; + + case 'c': /* Match characters. */ + if ((flags & LONG) == 0) + { + if (!(flags & SUPPRESS)) + { + str = ARG (char *); + if (str == NULL) + conv_error (); + } + + c = inchar (); + if (c == EOF) + input_error (); + + if (width == -1) + width = 1; + + if (!(flags & SUPPRESS)) + { + do + *str++ = c; + while (--width > 0 && inchar () != EOF); + } + else + while (--width > 0 && inchar () != EOF); + + if (width > 0) + /* I.e., EOF was read. */ + --read_in; + + if (!(flags & SUPPRESS)) + ++done; + + break; + } + /* FALLTHROUGH */ + case 'C': + /* Get UTF-8 encoded wide character. Here we assume (as in + other parts of the libc) that we only have to handle + UTF-8. */ + { + wint_t val; + size_t cnt = 0; + int first = 1; + + if (!(flags & SUPPRESS)) + { + wstr = ARG (wchar_t *); + if (str == NULL) + conv_error (); + } + + do + { +#define NEXT_WIDE_CHAR(First) \ + c = inchar (); \ + if (c == EOF) { \ + /* EOF is only an error for the first character. */ \ + if (First) { \ + input_error (); \ + } \ + else \ + { \ + --read_in; \ + break; \ + } \ + } \ + val = c; \ + if (val >= 0x80) \ + { \ + if ((c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \ + encode_error (); \ + if ((c & 0xe0) == 0xc0) \ + { \ + /* We expect two bytes. */ \ + cnt = 1; \ + val &= 0x1f; \ + } \ + else if ((c & 0xf0) == 0xe0) \ + { \ + /* We expect three bytes. */ \ + cnt = 2; \ + val &= 0x0f; \ + } \ + else if ((c & 0xf8) == 0xf0) \ + { \ + /* We expect four bytes. */ \ + cnt = 3; \ + val &= 0x07; \ + } \ + else if ((c & 0xfc) == 0xf8) \ + { \ + /* We expect five bytes. */ \ + cnt = 4; \ + val &= 0x03; \ + } \ + else \ + { \ + /* We expect six bytes. */ \ + cnt = 5; \ + val &= 0x01; \ + } \ + \ + do \ + { \ + c = inchar (); \ + if (c == EOF \ + || (c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \ + encode_error (); \ + val <<= 6; \ + val |= c & 0x3f; \ + } \ + while (--cnt > 0); \ + } \ + \ + if (!(flags & SUPPRESS)) \ + *wstr++ = val; \ + first = 0 + + NEXT_WIDE_CHAR (first); + } + while (--width > 0); + + if (width > 0) + /* I.e., EOF was read. */ + --read_in; + + if (!(flags & SUPPRESS)) + ++done; + } + break; + + case 's': /* Read a string. */ + if (flags & LONG) + /* We have to process a wide character string. */ + goto wide_char_string; + +#define STRING_ARG(Str, Type) \ + if (!(flags & SUPPRESS)) \ + { \ + if (flags & MALLOC) \ + { \ + /* The string is to be stored in a malloc'd buffer. */ \ + strptr = ARG (char **); \ + if (strptr == NULL) \ + conv_error (); \ + /* Allocate an initial buffer. */ \ + strsize = 100; \ + *strptr = malloc (strsize * sizeof (Type)); \ + Str = (Type *) *strptr; \ + } \ + else \ + Str = ARG (Type *); \ + if (Str == NULL) \ + conv_error (); \ + } + STRING_ARG (str, char); + + c = inchar (); + if (c == EOF) + input_error (); + + do + { + if (isspace (c)) + { + ungetc (c, s); + break; + } +#define STRING_ADD_CHAR(Str, c, Type) \ + if (!(flags & SUPPRESS)) \ + { \ + *Str++ = c; \ + if ((flags & MALLOC) && (char *) Str == *strptr + strsize) \ + { \ + /* Enlarge the buffer. */ \ + Str = realloc (*strptr, strsize * 2 * sizeof (Type)); \ + if (Str == NULL) \ + { \ + /* Can't allocate that much. Last-ditch effort. */\ + Str = realloc (*strptr, \ + (strsize + 1) * sizeof (Type)); \ + if (Str == NULL) \ + { \ + /* We lose. Oh well. \ + Terminate the string and stop converting, \ + so at least we don't skip any input. */ \ + ((Type *) (*strptr))[strsize] = '\0'; \ + ++done; \ + conv_error (); \ + } \ + else \ + { \ + *strptr = (char *) Str; \ + Str = ((Type *) *strptr) + strsize; \ + ++strsize; \ + } \ + } \ + else \ + { \ + *strptr = (char *) Str; \ + Str = ((Type *) *strptr) + strsize; \ + strsize *= 2; \ + } \ + } \ + } + STRING_ADD_CHAR (str, c, char); + } while ((width <= 0 || --width > 0) && inchar () != EOF); + + if (!(flags & SUPPRESS)) + { + *str = '\0'; + ++done; + } + break; + + case 'S': + /* Wide character string. */ + wide_char_string: + { + wint_t val; + int first = 1; + STRING_ARG (wstr, wchar_t); + + do + { + size_t cnt = 0; + NEXT_WIDE_CHAR (first); + + if (iswspace (val)) + { + /* XXX We would have to push back the whole wide char + with possibly many bytes. But since scanf does + not make a difference for white space characters + we can simply push back a simple which is + guaranteed to be in the [:space:] class. */ + ungetc (' ', s); + break; + } + + STRING_ADD_CHAR (wstr, val, wchar_t); + first = 0; + } + while (width <= 0 || --width > 0); + + if (!(flags & SUPPRESS)) + { + *wstr = L'\0'; + ++done; + } + } + break; + + case 'x': /* Hexadecimal integer. */ + case 'X': /* Ditto. */ + 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 number. */ + base = 0; + number_signed = 1; + + number: + c = inchar (); + if (c == EOF) + input_error (); + + /* Check for a sign. */ + if (c == '-' || c == '+') + { + ADDW (c); + if (width > 0) + --width; + c = inchar (); + } + + /* Look for a leading indication of base. */ + if (width != 0 && c == '0') + { + if (width > 0) + --width; + + ADDW (c); + c = inchar (); + + if (width != 0 && tolower (c) == 'x') + { + if (base == 0) + base = 16; + if (base == 16) + { + if (width > 0) + --width; + c = inchar (); + } + } + else if (base == 0) + base = 8; + } + + if (base == 0) + base = 10; + + /* Read the number into workspace. */ + while (c != EOF && width != 0) + { + if (base == 16 ? !isxdigit (c) : + ((!isdigit (c) || c - '0' >= base) && + !((flags & GROUP) && base == 10 && c == thousands))) + break; + ADDW (c); + if (width > 0) + --width; + + c = inchar (); + } + + /* The just read character is not part of the number anymore. */ + ungetc (c, s); + + if (wpsize == 0 || + (wpsize == 1 && (wp[0] == '+' || wp[0] == '-'))) + /* There was no number. */ + conv_error (); + + /* Convert the number. */ + ADDW ('\0'); + if (flags & LONGDBL) + { +// if (number_signed) +// num.q = __strtoq_internal (wp, &tw, base, flags & GROUP); +// else +// num.uq = __strtouq_internal (wp, &tw, base, flags & GROUP); + } + else + { + if (number_signed) + num.l = __strtol_internal (wp, &tw, base, flags & GROUP); + else + num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP); + } + if (wp == tw) + conv_error (); + + if (!(flags & SUPPRESS)) + { + if (! number_signed) + { + if (flags & LONGDBL) { + *ARG (unsigned LONGLONG int *) = num.uq; + } + else if (flags & LONG) + *ARG (unsigned long int *) = num.ul; + else if (flags & SHORT) + *ARG (unsigned short int *) = (unsigned short int) num.ul; + else + *ARG (unsigned int *) = (unsigned int) num.ul; + } + else + { + if (flags & LONGDBL) { + *ARG (LONGLONG int *) = num.q; + } + else if (flags & LONG) + *ARG (long int *) = num.l; + else if (flags & SHORT) + *ARG (short int *) = (short int) num.l; + else + *ARG (int *) = (int) num.l; + } + ++done; + } + break; + + case 'e': /* Floating-point numbers. */ + case 'E': + case 'f': + case 'g': + case 'G': + c = inchar (); + if (c == EOF) + input_error (); + + /* Check for a sign. */ + if (c == '-' || c == '+') + { + negative = c == '-'; + if (inchar () == EOF) + /* EOF is only an input error before we read any chars. */ + conv_error (); + if (width > 0) + --width; + } + else + negative = 0; + + got_dot = got_e = 0; + do + { + if (isdigit (c)) + ADDW (c); + else if (got_e && wp[wpsize - 1] == 'e' + && (c == '-' || c == '+')) + ADDW (c); + else if (wpsize > 0 && !got_e && tolower (c) == 'e') + { + ADDW ('e'); + got_e = got_dot = 1; + } + else if (c == decimal && !got_dot) + { + ADDW (c); + got_dot = 1; + } + else if ((flags & GROUP) && c == thousands && !got_dot) + ADDW (c); + else + { + /* The last read character is not part of the number + anymore. */ + ungetc (c, s); + break; + } + if (width > 0) + --width; + } + while (width != 0 && inchar () != EOF); + + if (wpsize == 0) + conv_error (); + + /* Convert the number. */ + ADDW ('\0'); + if (flags & LONGDBL) + { + long double d = __strtold_internal (wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) + *ARG (long double *) = negative ? -d : d; + } + else if (flags & LONG) + { + double d = __strtod_internal (wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) + *ARG (double *) = negative ? -d : d; + } + else + { + float d = __strtof_internal (wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) + *ARG (float *) = negative ? -d : d; + } + + if (tw == wp) + conv_error (); + + if (!(flags & SUPPRESS)) + ++done; + break; + + case '[': /* Character class. */ + if (flags & LONG) + { + STRING_ARG (wstr, wchar_t); + c = '\0'; /* This is to keep gcc quiet. */ + } + else + { + STRING_ARG (str, char); + + c = inchar (); + if (c == EOF) + input_error (); + } + + if (*f == '^') + { + ++f; + not_in = 1; + } + else + not_in = 0; + + /* Fill WP with byte flags indexed by character. + We will use this flag map for matching input characters. */ + if (wpmax < UCHAR_MAX) + { + wpmax = UCHAR_MAX; + wp = (char *) alloca (wpmax); + } + memset (wp, 0, UCHAR_MAX); + + fc = *f; + if (fc == ']' || fc == '-') + { + /* If ] or - appears before any char in the set, it is not + the terminator or separator, but the first char in the + set. */ + wp[fc] = 1; + ++f; + } + + while ((fc = *f++) != '\0' && fc != ']') + { + if (fc == '-' && *f != '\0' && *f != ']' && + (unsigned char) f[-2] <= (unsigned char) *f) + { + /* Add all characters from the one before the '-' + up to (but not including) the next format char. */ + for (fc = f[-2]; fc < *f; ++fc) + wp[fc] = 1; + } + else + /* Add the character to the flag map. */ + wp[fc] = 1; + } + if (fc == '\0') + { + if (!(flags & LONG)) + ungetc (c, s); + conv_error(); + } + + if (flags & LONG) + { + wint_t val; + int first = 1; + + do + { + size_t cnt = 0; + NEXT_WIDE_CHAR (first); + if (val > 255 || wp[val] == not_in) + { + /* XXX We have a problem here. We read a wide + character and this possibly took several + bytes. But we can only push back one single + character. To be sure we don't create wrong + input we push it back only in case it is + representable within one byte. */ + if (val < 0x80) + ungetc (val, s); + break; + } + STRING_ADD_CHAR (wstr, val, wchar_t); + if (width > 0) + --width; + first = 0; + } + while (width != 0); + + if (first) + conv_error (); + + if (!(flags & SUPPRESS)) + { + *wstr = L'\0'; + ++done; + } + } + else + { + num.ul = read_in - 1; /* -1 because we already read one char. */ + do + { + if (wp[c] == not_in) + { + ungetc (c, s); + break; + } + STRING_ADD_CHAR (str, c, char); + if (width > 0) + --width; + } + while (width != 0 && inchar () != EOF); + + if (read_in == num.ul) + conv_error (); + + if (!(flags & SUPPRESS)) + { + *str = '\0'; + ++done; + } + } + break; + + case 'p': /* Generic pointer. */ + base = 16; + /* A PTR must be the same size as a `long int'. */ + flags &= ~(SHORT|LONGDBL); + flags |= LONG; + number_signed = 0; + goto number; + } + } + + /* The last thing we saw int the format string was a white space. + Consume the last white spaces. */ + if (skip_space) + { + do + c = inchar (); + while (isspace (c)); + ungetc (c, s); + } + + + return done; +} + + + +int +xfscanf(FILE *f, const char *fmt, ...) +{ + int r; + va_list a=0; + va_start(a, fmt); + r = __vfscanf(f, fmt, a); + va_end(a); + return r; +} + + +double __strtod_internal (const char *__nptr,char **__endptr, int __group) +{ + return strtod(__nptr,__endptr); +} +float __strtof_internal (const char *__nptr, char **__endptr,int __group) +{ + return (float)strtod(__nptr,__endptr); +} +static double powten[] = +{ + 1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L, + 1e512L, 1e512L*1e512L, 1e2048L, 1e4096L +}; + +long double __strtold_internal (const char *s,char **sret, int __group) +{ + + long double r; /* result */ + int e, ne; /* exponent */ + int sign; /* +- 1.0 */ + int esign; + int flags=0; + int l2powm1; + + r = 0.0L; + sign = 1; + e = ne = 0; + esign = 1; + + while(*s && isspace(*s)) + s++; + + if (*s == '+') + s++; + else if (*s == '-') + { + sign = -1; + s++; + } + + while ((*s >= '0') && (*s <= '9')) + { + flags |= 1; + r *= 10.0L; + r += *s - '0'; + s++; + } + + if (*s == '.') + { + s++; + while ((*s >= '0') && (*s <= '9')) + { + flags |= 2; + r *= 10.0L; + r += *s - '0'; + s++; + ne++; + } + } + if (flags == 0) + { + if (sret) + *sret = (char *)s; + return 0.0L; + } + + if ((*s == 'e') || (*s == 'E')) + { + s++; + if (*s == '+') + s++; + else if (*s == '-') + { + s++; + esign = -1; + } + while ((*s >= '0') && (*s <= '9')) + { + e *= 10; + e += *s - '0'; + s++; + } + } + if (esign < 0) + { + esign = -esign; + e = -e; + } + e = e - ne; + if (e < -4096) + { + /* possibly subnormal number, 10^e would overflow */ + r *= 1.0e-2048L; + e += 2048; + } + if (e < 0) + { + e = -e; + esign = -esign; + } + if (e >= 8192) + e = 8191; + if (e) + { + double d = 1.0L; + l2powm1 = 0; + while (e) + { + if (e & 1) + d *= powten[l2powm1]; + e >>= 1; + l2powm1++; + } + if (esign > 0) + r *= d; + else + r /= d; + } + if (sret) + *sret = (char *)s; + return r * sign; + + return 0; +} +long int __strtol_internal (const char *__nptr, char **__endptr, int __base, int __group) +{ + return strtol(__nptr,__endptr, __base); +} +unsigned long int __strtoul_internal (const char *__nptr, char **__endptr, int __base, int __group) +{ + return strtoul(__nptr,__endptr, __base); +} + + + + + + + + + diff --git a/reactos/lib/msvcrt/stdio/vscanf.c b/reactos/lib/msvcrt/stdio/vscanf.c new file mode 100644 index 00000000000..81e508f89a3 --- /dev/null +++ b/reactos/lib/msvcrt/stdio/vscanf.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include + + +#undef vscanf + + +/* Read formatted input from stdin according to the format + string in FORMAT, using the argument list in ARG. */ +int __vscanf (const char *format, va_list arg) +{ + return __vfscanf(stdin, format, arg); +} diff --git a/reactos/lib/msvcrt/stdio/vsscanf.c b/reactos/lib/msvcrt/stdio/vsscanf.c new file mode 100644 index 00000000000..26f7908fe9a --- /dev/null +++ b/reactos/lib/msvcrt/stdio/vsscanf.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1991, 1992, 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include +#include + +#undef vsscanf + +/* Read formatted input from S according to the format + string FORMAT, using the argument list in ARG. */ +int __vsscanf(const char *s,const char *format,va_list arg) +{ + FILE f; + + if (s == NULL) + { + __set_errno(EINVAL); + return -1; + } + + memset((void *) &f, 0, sizeof (f)); + + f._flag = _IOREAD; + f._ptr = (char *)s; + f._base = (char *)s; + f._bufsiz = strlen(s); + f._cnt = f._bufsiz; + + return __vfscanf(&f, format, arg); +}