Commit 88e24537 authored by Jon Griffiths's avatar Jon Griffiths Committed by Alexandre Julliard

- Fix _fullpath & splitpath, winapi_check fixes

- Add cprintf,cscanf,_fgetwchar,_fgetwc,_fputwchar,_fputwc, _wtoi & _wtol (fwd),scanf,_timezone_dll
parent ce1398e3
......@@ -16,12 +16,13 @@
*/
#include "crtdll.h"
#include "wincon.h"
#include <stdio.h>
DEFAULT_DEBUG_CHANNEL(crtdll);
static HANDLE __CRTDLL_console_in = INVALID_HANDLE_VALUE;
static HANDLE __CRTDLL_console_out = INVALID_HANDLE_VALUE;
static int __CRTDLL_console_buffer = EOF;
static int __CRTDLL_console_buffer = CRTDLL_EOF;
/* INTERNAL: Initialise console handles */
......@@ -66,7 +67,7 @@ LPSTR __cdecl CRTDLL__cgets(LPSTR str)
/* FIXME: No editing of string supported */
do
{
if (str[1] >= str[0] || (str[1]++, c = CRTDLL__getche()) == EOF || c == '\n')
if (str[1] >= str[0] || (str[1]++, c = CRTDLL__getche()) == CRTDLL_EOF || c == '\n')
{
*buf = '\0';
return str + 2;
......@@ -77,6 +78,24 @@ LPSTR __cdecl CRTDLL__cgets(LPSTR str)
/*********************************************************************
* _cprintf (CRTDLL.064)
*
* Write a formatted string to CONOUT$.
*/
INT __cdecl CRTDLL__cprintf( LPCSTR format, ... )
{
va_list valist;
char buffer[2048];
va_start( valist, format );
if (snprintf( buffer, sizeof(buffer), format, valist ) == -1)
ERR("Format too large for internal buffer!\n");
va_end(valist);
return CRTDLL__cputs( buffer );
}
/*********************************************************************
* _cputs (CRTDLL.065)
*
* Write a string to CONOUT$.
......@@ -87,7 +106,133 @@ INT __cdecl CRTDLL__cputs(LPCSTR str)
if (WriteConsoleA(__CRTDLL_console_out, str, strlen(str), &count, NULL)
&& count == 1)
return 0;
return EOF;
return CRTDLL_EOF;
}
/*********************************************************************
* _cscanf (CRTDLL.067)
*
* Read formatted input from CONIN$.
*/
INT __cdecl CRTDLL__cscanf( LPCSTR format, ... )
{
/* NOTE: If you extend this function, extend CRTDLL_fscanf in file.c too */
INT rd = 0;
int nch;
va_list ap;
if (!*format) return 0;
WARN("\"%s\": semi-stub\n", format);
nch = CRTDLL__getch();
va_start(ap, format);
while (*format) {
if (*format == ' ') {
/* skip whitespace */
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL__getch();
}
else if (*format == '%') {
int st = 0;
format++;
switch(*format) {
case 'd': { /* read an integer */
int*val = va_arg(ap, int*);
int cur = 0;
/* skip initial whitespace */
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL__getch();
/* get sign and first digit */
if (nch == '-') {
nch = CRTDLL__getch();
if (isdigit(nch))
cur = -(nch - '0');
else break;
} else {
if (isdigit(nch))
cur = nch - '0';
else break;
}
nch = CRTDLL__getch();
/* read until no more digits */
while ((nch!=CRTDLL_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = CRTDLL__getch();
}
st = 1;
*val = cur;
}
break;
case 'f': { /* read a float */
float*val = va_arg(ap, float*);
float cur = 0;
/* skip initial whitespace */
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL__getch();
/* get sign and first digit */
if (nch == '-') {
nch = CRTDLL__getch();
if (isdigit(nch))
cur = -(nch - '0');
else break;
} else {
if (isdigit(nch))
cur = nch - '0';
else break;
}
/* read until no more digits */
while ((nch!=CRTDLL_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = CRTDLL__getch();
}
if (nch == '.') {
/* handle decimals */
float dec = 1;
nch = CRTDLL__getch();
while ((nch!=CRTDLL_EOF) && isdigit(nch)) {
dec /= 10;
cur += dec * (nch - '0');
nch = CRTDLL__getch();
}
}
st = 1;
*val = cur;
}
break;
case 's': { /* read a word */
char*str = va_arg(ap, char*);
char*sptr = str;
/* skip initial whitespace */
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL__getch();
/* read until whitespace */
while ((nch!=CRTDLL_EOF) && !isspace(nch)) {
*sptr++ = nch; st++;
nch = CRTDLL__getch();
}
/* terminate */
*sptr = 0;
TRACE("read word: %s\n", str);
}
break;
default: FIXME("unhandled: %%%c\n", *format);
}
if (st) rd++;
else break;
}
else {
/* check for character match */
if (nch == *format)
nch = CRTDLL__getch();
else break;
}
format++;
}
va_end(ap);
if (nch != CRTDLL_EOF)
CRTDLL__ungetch(nch);
TRACE("returning %d\n", rd);
return rd;
}
......@@ -98,10 +243,10 @@ INT __cdecl CRTDLL__cputs(LPCSTR str)
*/
INT __cdecl CRTDLL__getch(VOID)
{
if (__CRTDLL_console_buffer != EOF)
if (__CRTDLL_console_buffer != CRTDLL_EOF)
{
INT retVal = __CRTDLL_console_buffer;
__CRTDLL_console_buffer = EOF;
__CRTDLL_console_buffer = CRTDLL_EOF;
return retVal;
}
else
......@@ -130,7 +275,7 @@ INT __cdecl CRTDLL__getch(VOID)
} while(1);
if (mode) SetConsoleMode(__CRTDLL_console_in, mode);
}
return EOF;
return CRTDLL_EOF;
}
......@@ -142,9 +287,9 @@ INT __cdecl CRTDLL__getch(VOID)
INT __cdecl CRTDLL__getche(VOID)
{
INT res = CRTDLL__getch();
if (res != EOF && CRTDLL__putch(res) != EOF)
if (res != CRTDLL_EOF && CRTDLL__putch(res) != CRTDLL_EOF)
return res;
return EOF;
return CRTDLL_EOF;
}
......@@ -155,7 +300,7 @@ INT __cdecl CRTDLL__getche(VOID)
*/
INT __cdecl CRTDLL__kbhit(VOID)
{
if (__CRTDLL_console_buffer != EOF)
if (__CRTDLL_console_buffer != CRTDLL_EOF)
return 1;
else
{
......@@ -201,7 +346,7 @@ INT __cdecl CRTDLL__putch(INT c)
if (WriteConsoleA(__CRTDLL_console_out, &c, 1, &count, NULL) &&
count == 1)
return c;
return EOF;
return CRTDLL_EOF;
}
......@@ -212,8 +357,8 @@ INT __cdecl CRTDLL__putch(INT c)
*/
INT __cdecl CRTDLL__ungetch(INT c)
{
if (c == EOF || __CRTDLL_console_buffer != EOF)
return EOF;
if (c == CRTDLL_EOF || __CRTDLL_console_buffer != CRTDLL_EOF)
return CRTDLL_EOF;
return __CRTDLL_console_buffer = c;
}
......
......@@ -157,7 +157,8 @@ typedef struct _crtfile
#define SEEK_CUR 1
#define SEEK_END 2
#define EOF -1
#define CRTDLL_EOF -1
#define CRTDLL_WEOF (WCHAR)(0xFFFF)
extern CRTDLL_FILE __CRTDLL_iob[3];
......@@ -281,14 +282,16 @@ LPSTR __cdecl CRTDLL__mktemp( LPSTR pattern );
CRTDLL_FILE* __cdecl CRTDLL_fopen( LPCSTR path, LPCSTR mode );
CRTDLL_FILE* __cdecl CRTDLL_freopen( LPCSTR path,LPCSTR mode,CRTDLL_FILE* f );
CRTDLL_FILE* __cdecl CRTDLL_tmpfile( void );
WCHAR __cdecl CRTDLL__fgetwchar( VOID );
INT __cdecl CRTDLL__fgetchar( VOID );
DWORD __cdecl CRTDLL_fread( LPVOID ptr,INT size,INT nmemb,CRTDLL_FILE* file );
INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* stream, LPSTR format, ... );
INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* stream, LPCSTR format, ... );
INT __cdecl CRTDLL__filbuf( CRTDLL_FILE* file );
LONG __cdecl CRTDLL__filelength( INT fd );
INT __cdecl CRTDLL__fileno( CRTDLL_FILE* file );
INT __cdecl CRTDLL__flsbuf( INT c, CRTDLL_FILE* file );
INT __cdecl CRTDLL__fputchar( INT c );
WCHAR __cdecl CRTDLL__fputwchar( WCHAR wc );
INT __cdecl CRTDLL__flushall( VOID );
INT __cdecl CRTDLL__fcloseall( VOID );
LONG __cdecl CRTDLL__lseek( INT fd, LONG offset, INT whence );
......@@ -315,6 +318,8 @@ INT __cdecl CRTDLL_putc( INT c, CRTDLL_FILE* file );
INT __cdecl CRTDLL_fgetc( CRTDLL_FILE* file );
INT __cdecl CRTDLL_getchar( VOID );
INT __cdecl CRTDLL_getc( CRTDLL_FILE* file );
WCHAR __cdecl CRTDLL_fgetwc( CRTDLL_FILE* file );
WCHAR __cdecl CRTDLL_fputwc( WCHAR wc, CRTDLL_FILE* file );
CHAR* __cdecl CRTDLL_fgets( LPSTR s, INT size, CRTDLL_FILE* file );
LPSTR __cdecl CRTDLL_gets( LPSTR buf );
INT __cdecl CRTDLL_fclose( CRTDLL_FILE* file );
......@@ -324,6 +329,7 @@ LONG __cdecl CRTDLL__tell(INT fd);
INT __cdecl CRTDLL__umask(INT umask);
INT __cdecl CRTDLL__utime( LPCSTR path, struct _utimbuf *t );
INT __cdecl CRTDLL__unlink( LPCSTR pathname );
INT __cdecl CRTDLL_scanf( LPCSTR format, ... );
INT __cdecl CRTDLL_rename( LPCSTR oldpath,LPCSTR newpath );
int __cdecl CRTDLL__stat( LPCSTR filename, struct _stat * buf );
INT __cdecl CRTDLL__open( LPCSTR path,INT flags );
......@@ -359,8 +365,8 @@ VOID __cdecl CRTDLL_longjmp( jmp_buf env, int val );
LPSTR __cdecl CRTDLL_setlocale( INT category,LPCSTR locale );
INT __cdecl CRTDLL__isctype( INT c, UINT type );
LPSTR __cdecl CRTDLL__fullpath( LPSTR buf, LPCSTR name, INT size );
VOID __cdecl CRTDLL__splitpath( LPCSTR path, LPSTR drive, LPSTR directory,
LPSTR filename, LPSTR extension );
VOID __cdecl CRTDLL__splitpath(LPCSTR inpath, LPSTR drv, LPSTR dir,
LPSTR fname, LPSTR ext );
INT __cdecl CRTDLL__matherr( struct _exception *e );
VOID __cdecl CRTDLL__makepath( LPSTR path, LPCSTR drive,
LPCSTR directory, LPCSTR filename,
......@@ -388,6 +394,7 @@ INT __cdecl CRTDLL_ispunct( INT c);
INT __cdecl CRTDLL_isspace( INT c);
INT __cdecl CRTDLL_isupper( INT c);
INT __cdecl CRTDLL_isxdigit( INT c );
INT __cdecl CRTDLL_isleadbyte( UCHAR c );
double __cdecl CRTDLL_ldexp( double x, LONG y );
LPSTR __cdecl CRTDLL__mbsrchr( LPSTR s,CHAR x );
VOID __cdecl CRTDLL___dllonexit ( VOID );
......@@ -444,7 +451,7 @@ HANDLE __cdecl CRTDLL__spawnve( INT flags, LPCSTR name, LPCSTR *argv, LPCSTR *en
HANDLE __cdecl CRTDLL__spawnvp( INT flags, LPCSTR name, LPCSTR *argv);
HANDLE __cdecl CRTDLL__spawnvpe( INT flags, LPCSTR name, LPCSTR *argv, LPCSTR *envv);
INT __cdecl CRTDLL_system( LPCSTR cmd );
INT __cdecl CRTDLL__cwait( PINT status, INT pid, INT action );
INT __cdecl CRTDLL__cwait( LPINT status, INT pid, INT action );
/* str.c */
LPSTR __cdecl CRTDLL__strdec( LPSTR str1, LPSTR str2 );
......@@ -494,7 +501,9 @@ INT __cdecl CRTDLL_iswxdigit( WCHAR wc );
/* console.c */
LPSTR __cdecl CRTDLL__cgets( LPSTR str );
INT __cdecl CRTDLL__cfprintf( LPCSTR format, ... );
INT __cdecl CRTDLL__cputs( LPCSTR str );
INT __cdecl CRTDLL__cscanf( LPCSTR format, ... );
INT __cdecl CRTDLL__getch( VOID );
INT __cdecl CRTDLL__getche( VOID );
INT __cdecl CRTDLL__kbhit( VOID );
......
......@@ -70,11 +70,11 @@ debug_channels (crtdll)
@ cdecl _control87(long long) CRTDLL__control87
@ cdecl _controlfp(long long) CRTDLL__controlfp
@ cdecl _copysign(double double) CRTDLL__copysign
@ stub _cprintf
@ varargs _cprintf(str) CRTDLL__cprintf
@ stub _cpumode_dll
@ cdecl _cputs(str) CRTDLL__cputs
@ cdecl _creat(str long) CRTDLL__creat
@ stub _cscanf
@ varargs _cscanf(str) CRTDLL__cscanf
@ extern _ctype CRTDLL_ctype
@ cdecl _cwait(ptr long long) CRTDLL__cwait
@ stub _daylight_dll
......@@ -100,7 +100,7 @@ debug_channels (crtdll)
@ cdecl _fcvt(double long ptr ptr) fcvt
@ cdecl _fdopen(long ptr) CRTDLL__fdopen
@ cdecl _fgetchar() CRTDLL__fgetchar
@ stub _fgetwchar
@ cdecl _fgetwchar() CRTDLL__fgetwchar
@ cdecl _filbuf(ptr) CRTDLL__filbuf
@ stub _fileinfo_dll
@ cdecl _filelength(long) CRTDLL__filelength
......@@ -116,7 +116,7 @@ debug_channels (crtdll)
@ stub _fpieee_flt
@ cdecl _fpreset() CRTDLL__fpreset
@ cdecl _fputchar(long) CRTDLL__fputchar
@ stub _fputwchar
@ cdecl _fputwchar(long) CRTDLL__fputwchar
@ cdecl _fsopen(str str long) CRTDLL__fsopen
@ cdecl _fstat(long ptr) CRTDLL__fstat
@ cdecl _ftime(ptr) CRTDLL__ftime
......@@ -313,7 +313,7 @@ debug_channels (crtdll)
@ extern _sys_nerr_dll CRTDLL__sys_nerr
@ cdecl _tell(long) CRTDLL__tell
@ cdecl _tempnam(str ptr) CRTDLL__tempnam
@ stub _timezone_dll
@ extern _timezone_dll CRTDLL_timezone_dll
@ cdecl _tolower(long) CRTDLL__toupper
@ cdecl _toupper(long) CRTDLL__tolower
@ stub _tzname
......@@ -340,8 +340,8 @@ debug_channels (crtdll)
@ extern _winminor_dll CRTDLL_winminor_dll
@ extern _winver_dll CRTDLL_winver_dll
@ cdecl _write(long ptr long) CRTDLL__write
@ stub _wtoi
@ stub _wtol
@ forward _wtoi NTDLL._wtoi
@ forward _wtol NTDLL._wtol
@ cdecl _y0(double) CRTDLL__y0
@ cdecl _y1(double) CRTDLL__y1
@ cdecl _yn(long double) CRTDLL__yn
......@@ -376,14 +376,14 @@ debug_channels (crtdll)
@ cdecl fgetc(ptr) CRTDLL_fgetc
@ cdecl fgetpos(ptr ptr) CRTDLL_fgetpos
@ cdecl fgets(ptr long ptr) CRTDLL_fgets
@ stub fgetwc
@ cdecl fgetwc(ptr) CRTDLL_fgetwc
@ cdecl floor(double) floor
@ cdecl fmod(double double) fmod
@ cdecl fopen(str str) CRTDLL_fopen
@ varargs fprintf(ptr str) CRTDLL_fprintf
@ cdecl fputc(long ptr) CRTDLL_fputc
@ cdecl fputs(str ptr) CRTDLL_fputs
@ stub fputwc
@ cdecl fputwc(long ptr) CRTDLL_fputwc
@ cdecl fread(ptr long long ptr) CRTDLL_fread
@ cdecl free(ptr) CRTDLL_free
@ cdecl freopen(str str ptr) CRTDLL_freopen
......@@ -458,7 +458,7 @@ debug_channels (crtdll)
@ cdecl remove(str) CRTDLL_remove
@ cdecl rename(str str) CRTDLL_rename
@ cdecl rewind(ptr) CRTDLL_rewind
@ stub scanf
@ varargs scanf(str) CRTDLL_scanf
@ cdecl setbuf(ptr ptr) CRTDLL_setbuf
@ cdecl setlocale(long ptr) CRTDLL_setlocale
@ stub setvbuf
......
......@@ -67,6 +67,7 @@ UINT CRTDLL_osminor_dll; /* CRTDLL.242 */
UINT CRTDLL_osmode_dll; /* CRTDLL.243 */
UINT CRTDLL_osver_dll; /* CRTDLL.244 */
UINT CRTDLL_osversion_dll; /* CRTDLL.245 */
LONG CRTDLL_timezone_dll = 1; /* CRTDLL.245 */
UINT CRTDLL_winmajor_dll; /* CRTDLL.329 */
UINT CRTDLL_winminor_dll; /* CRTDLL.330 */
UINT CRTDLL_winver_dll; /* CRTDLL.331 */
......@@ -687,78 +688,262 @@ INT __cdecl CRTDLL__isctype(INT c, UINT type)
}
/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
static void fln_fix(char *path)
{
int dir_flag = 0, root_flag = 0;
char *r, *p, *q, *s;
/* Skip drive */
if (NULL == (r = strrchr(path, ':')))
r = path;
else
++r;
/* Ignore leading slashes */
while ('\\' == *r)
if ('\\' == r[1])
strcpy(r, &r[1]);
else
{
root_flag = 1;
++r;
}
p = r; /* Change "\\" to "\" */
while (NULL != (p = strchr(p, '\\')))
if ('\\' == p[1])
strcpy(p, &p[1]);
else
++p;
while ('.' == *r) /* Scrunch leading ".\" */
{
if ('.' == r[1])
{
/* Ignore leading ".." */
for (p = (r += 2); *p && (*p != '\\'); ++p)
;
}
else
{
for (p = r + 1 ;*p && (*p != '\\'); ++p)
;
}
strcpy(r, p + ((*p) ? 1 : 0));
}
while ('\\' == path[strlen(path)-1]) /* Strip last '\\' */
{
dir_flag = 1;
path[strlen(path)-1] = '\0';
}
s = r;
/* Look for "\." in path */
while (NULL != (p = strstr(s, "\\.")))
{
if ('.' == p[2])
{
/* Execute this section if ".." found */
q = p - 1;
while (q > r) /* Backup one level */
{
if (*q == '\\')
break;
--q;
}
if (q > r)
{
strcpy(q, p + 3);
s = q;
}
else if ('.' != *q)
{
strcpy(q + ((*q == '\\') ? 1 : 0),
p + 3 + ((*(p + 3)) ? 1 : 0));
s = q;
}
else s = ++p;
}
else
{
/* Execute this section if "." found */
q = p + 2;
for ( ;*q && (*q != '\\'); ++q)
;
strcpy (p, q);
}
}
if (root_flag) /* Embedded ".." could have bubbled up to root */
{
for (p = r; *p && ('.' == *p || '\\' == *p); ++p)
;
if (r != p)
strcpy(r, p);
}
if (dir_flag)
strcat(path, "\\");
}
/*********************************************************************
* _fullpath (CRTDLL.114)
* _fullpath
*
* Convert a partial path into a complete, normalised path.
*/
LPSTR __cdecl CRTDLL__fullpath(LPSTR buf, LPCSTR name, INT size)
LPSTR __cdecl CRTDLL__fullpath(LPSTR absPath, LPCSTR relPath, INT size)
{
if (!buf)
char drive[5],dir[MAX_PATH],file[MAX_PATH],ext[MAX_PATH];
char res[MAX_PATH];
size_t len;
res[0] = '\0';
if (!relPath || !*relPath)
return CRTDLL__getcwd(absPath, size);
if (size < 4)
{
CRTDLL_errno = ERANGE;
return NULL;
}
TRACE(":resolving relative path '%s'\n",relPath);
CRTDLL__splitpath(relPath, drive, dir, file, ext);
/* Get Directory and drive into 'res' */
if (!dir[0] || (dir[0] != '/' && dir[0] != '\\'))
{
size = 256;
if(!(buf = CRTDLL_malloc(size))) return NULL;
/* Relative or no directory given */
CRTDLL__getdcwd(drive[0] ? toupper(drive[0]) - 'A' + 1 : 0, res, MAX_PATH);
strcat(res,"\\");
if (dir[0])
strcat(res,dir);
if (drive[0])
res[0] = drive[0]; /* If given a drive, preserve the letter case */
}
if (!GetFullPathNameA( name, size, buf, NULL )) return NULL;
TRACE("CRTDLL_fullpath got %s\n",buf);
return buf;
else
{
strcpy(res,drive);
strcat(res,dir);
}
strcat(res,"\\");
strcat(res, file);
strcat(res, ext);
fln_fix(res);
len = strlen(res);
if (len >= MAX_PATH || len >= size)
return NULL; /* FIXME: errno? */
if (!absPath)
return CRTDLL__strdup(res);
strcpy(absPath,res);
return absPath;
}
/*********************************************************************
* _splitpath (CRTDLL.279)
*
* Split a path string into components.
*
* PARAMETERS
* inpath [in] Path to split
* drive [out] "x:" or ""
* directory [out] "\dir", "\dir\", "/dir", "/dir/", "./" etc
* filename [out] filename, without dot or slashes
* extension [out] ".ext" or ""
*/
VOID __cdecl CRTDLL__splitpath(LPCSTR path, LPSTR drive, LPSTR directory, LPSTR filename, LPSTR extension )
VOID __cdecl CRTDLL__splitpath(LPCSTR inpath, LPSTR drv, LPSTR dir,
LPSTR fname, LPSTR ext )
{
/* drive includes :
directory includes leading and trailing (forward and backward slashes)
filename without dot and slashes
extension with leading dot
*/
char * drivechar,*dirchar,*namechar;
/* Modified PD code from 'snippets' collection. */
char ch, *ptr, *p;
char pathbuff[MAX_PATH],*path=pathbuff;
TRACE("CRTDLL__splitpath got %s\n",path);
TRACE(":splitting path '%s'\n",path);
strcpy(pathbuff, inpath);
drivechar = strchr(path,':');
dirchar = strrchr(path,'/');
namechar = strrchr(path,'\\');
dirchar = max(dirchar,namechar);
if (dirchar)
namechar = strrchr(dirchar,'.');
else
namechar = strrchr(path,'.');
/* convert slashes to backslashes for searching */
for (ptr = (char*)path; *ptr; ++ptr)
if ('/' == *ptr)
*ptr = '\\';
if (drive)
/* look for drive spec */
if ('\0' != (ptr = strchr(path, ':')))
{
*drive = 0x00;
if (drivechar)
++ptr;
if (drv)
{
strncat(drive,path,drivechar-path+1);
path = drivechar+1;
strncpy(drv, path, ptr - path);
drv[ptr - path] = '\0';
}
path = ptr;
}
if (directory)
else if (drv)
*drv = '\0';
/* find rightmost backslash or leftmost colon */
if (NULL == (ptr = strrchr(path, '\\')))
ptr = (strchr(path, ':'));
if (!ptr)
{
ptr = (char *)path; /* no path */
if (dir)
*dir = '\0';
}
else
{
*directory = 0x00;
if (dirchar)
++ptr; /* skip the delimiter */
if (dir)
{
strncat(directory,path,dirchar-path+1);
path = dirchar+1;
ch = *ptr;
*ptr = '\0';
strcpy(dir, path);
*ptr = ch;
}
}
if (filename)
{
*filename = 0x00;
if (namechar)
if (NULL == (p = strrchr(ptr, '.')))
{
strncat(filename,path,namechar-path);
if (extension)
if (fname)
strcpy(fname, ptr);
if (ext)
*ext = '\0';
}
else
{
*extension = 0x00;
strcat(extension,namechar);
*p = '\0';
if (fname)
strcpy(fname, ptr);
*p = '.';
if (ext)
strcpy(ext, p);
}
/* Fix pathological case - Win returns ':' as part of the
* directory when no drive letter is given.
*/
if (drv && drv[0] == ':')
{
*drv = '\0';
if (dir)
{
pathbuff[0] = ':';
pathbuff[1] = '\0';
strcat(pathbuff,dir);
strcpy(dir,pathbuff);
}
}
TRACE("CRTDLL__splitpath found %s %s %s %s\n",drive,directory,filename,extension);
}
......@@ -770,7 +955,8 @@ VOID __cdecl CRTDLL__splitpath(LPCSTR path, LPSTR drive, LPSTR directory, LPSTR
INT __cdecl CRTDLL__matherr(struct _exception *e)
{
/* FIXME: Supposedly this can be user overridden, but
* currently it will never be called anyway.
* currently it will never be called anyway. User will
* need to use .spec ignore directive to override.
*/
FIXME(":Unhandled math error!\n");
return e == NULL ? 0 : 0;
......@@ -780,7 +966,6 @@ INT __cdecl CRTDLL__matherr(struct _exception *e)
/*********************************************************************
* _makepath (CRTDLL.182)
*/
VOID __cdecl CRTDLL__makepath(LPSTR path, LPCSTR drive,
LPCSTR directory, LPCSTR filename,
LPCSTR extension )
......@@ -1016,7 +1201,7 @@ INT __cdecl CRTDLL_isgraph(INT c)
/*********************************************************************
* isleadbyte (CRTDLL.447)
*/
INT __cdecl CRTDLL_isleadbyte(unsigned char c)
INT __cdecl CRTDLL_isleadbyte(UCHAR c)
{
return CRTDLL__isctype( c, CRTDLL_LEADBYTE );
}
......
......@@ -205,11 +205,13 @@ INT __cdecl CRTDLL__findnext(DWORD hand, find_t * ft)
CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT size)
{
char dir[_MAX_PATH];
int dir_len = GetCurrentDirectoryA(_MAX_PATH,dir);
int dir_len = GetCurrentDirectoryA(MAX_PATH,dir);
if (dir_len < 1)
return NULL; /* FIXME: Real return value untested */
TRACE(":returning '%s'\n", dir);
if (!buf)
{
if (size < 0)
......@@ -232,10 +234,12 @@ CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT size)
* Get the current directory on a drive. A: =1, B: =2, etc.
* Passing drive 0 means the current drive.
*/
CHAR* __cdecl CRTDLL__getdcwd(INT drive,LPSTR buf, INT size)
CHAR* __cdecl CRTDLL__getdcwd(INT drive, LPSTR buf, INT size)
{
static CHAR* dummy;
TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
if (!drive || drive == CRTDLL__getdrive())
return CRTDLL__getcwd(buf,size); /* current */
else
......@@ -258,6 +262,7 @@ CHAR* __cdecl CRTDLL__getdcwd(INT drive,LPSTR buf, INT size)
return NULL; /* buf too small */
}
TRACE(":returning '%s'\n", dir);
if (!buf)
return CRTDLL__strdup(dir); /* allocate */
......
......@@ -395,7 +395,20 @@ CRTDLL_FILE* __cdecl CRTDLL__fdopen(INT fd, LPCSTR mode)
/*********************************************************************
* _fgetwchar (CRTDLL.062)
*
* Read a wide character from stdin.
*/
WCHAR __cdecl CRTDLL__fgetwchar( VOID )
{
return CRTDLL_fgetwc(CRTDLL_stdin);
}
/*********************************************************************
* _fgetchar (CRTDLL.092)
*
* Read a character from stdin.
*/
INT __cdecl CRTDLL__fgetchar( VOID )
{
......@@ -506,6 +519,17 @@ INT __cdecl CRTDLL__fputchar(INT c)
/*********************************************************************
* _fputwchar (CRTDLL.109)
*
* Put a wide character to stdout.
*/
WCHAR __cdecl CRTDLL__fputwchar( WCHAR wc )
{
return CRTDLL_fputwc(wc, CRTDLL_stdout);
}
/*********************************************************************
* _fsopen (CRTDLL.110)
*
* Open a FILE* with sharing.
......@@ -640,7 +664,7 @@ INT __cdecl CRTDLL__getw( CRTDLL_FILE* file )
{
INT i;
if (CRTDLL__read(file->_file, &i, sizeof(INT)) != 1)
return EOF;
return CRTDLL_EOF;
return i;
}
......@@ -853,7 +877,7 @@ INT __cdecl CRTDLL__open_osfhandle(HANDLE hand, INT flags)
*/
INT __cdecl CRTDLL__putw(INT val, CRTDLL_FILE* file)
{
return CRTDLL__write(file->_file, &val, sizeof(val)) == 1? val : EOF;
return CRTDLL__write(file->_file, &val, sizeof(val)) == 1? val : CRTDLL_EOF;
}
......@@ -1174,7 +1198,7 @@ INT __cdecl CRTDLL_fgetc( CRTDLL_FILE* file )
{
char c;
if (CRTDLL__read(file->_file,&c,1) != 1)
return EOF;
return CRTDLL_EOF;
return c;
}
......@@ -1204,14 +1228,14 @@ CHAR* __cdecl CRTDLL_fgets(LPSTR s, INT size, CRTDLL_FILE* file)
* windows95's ftp.exe.
* JG - Is this true now we use ReadFile() on stdin too?
*/
for(cc = CRTDLL_fgetc(file); cc != EOF && cc != '\n';
for(cc = CRTDLL_fgetc(file); cc != CRTDLL_EOF && cc != '\n';
cc = CRTDLL_fgetc(file))
if (cc != '\r')
{
if (--size <= 0) break;
*s++ = (char)cc;
}
if ((cc == EOF) && (s == buf_start)) /* If nothing read, return 0*/
if ((cc == CRTDLL_EOF) && (s == buf_start)) /* If nothing read, return 0*/
{
TRACE(":nothing read\n");
return 0;
......@@ -1226,6 +1250,33 @@ CHAR* __cdecl CRTDLL_fgets(LPSTR s, INT size, CRTDLL_FILE* file)
/*********************************************************************
* fgetwc (CRTDLL.366)
*
* Read a wide character from a FILE*.
*/
WCHAR __cdecl CRTDLL_fgetwc( CRTDLL_FILE* file )
{
WCHAR wc;
if (CRTDLL__read(file->_file, &wc, sizeof(wc)) != sizeof(wc))
return CRTDLL_WEOF;
return wc;
}
/*********************************************************************
* fputwc (CRTDLL.373)
*
* Write a wide character to a FILE*.
*/
WCHAR __cdecl CRTDLL_fputwc( WCHAR wc, CRTDLL_FILE* file)
{
if (CRTDLL__write(file->_file, &wc, sizeof(wc)) != sizeof(wc))
return CRTDLL_WEOF;
return wc;
}
/*********************************************************************
* fputs (CRTDLL.375)
*/
INT __cdecl CRTDLL_fputs( LPCSTR s, CRTDLL_FILE* file )
......@@ -1318,7 +1369,7 @@ CRTDLL_FILE* __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
*/
INT __cdecl CRTDLL_fputc( INT c, CRTDLL_FILE* file )
{
return CRTDLL__write(file->_file, &c, 1) == 1? c : EOF;
return CRTDLL__write(file->_file, &c, 1) == 1? c : CRTDLL_EOF;
}
......@@ -1393,8 +1444,9 @@ INT __cdecl CRTDLL_fsetpos( CRTDLL_FILE* file, CRTDLL_fpos_t *pos)
/*********************************************************************
* fscanf (CRTDLL.381)
*/
INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPCSTR format, ... )
{
/* NOTE: If you extend this function, extend CRTDLL__cscanf in console.c too */
INT rd = 0;
int nch;
va_list ap;
......@@ -1405,7 +1457,7 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
while (*format) {
if (*format == ' ') {
/* skip whitespace */
while ((nch!=EOF) && isspace(nch))
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL_fgetc(file);
}
else if (*format == '%') {
......@@ -1416,7 +1468,7 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
int*val = va_arg(ap, int*);
int cur = 0;
/* skip initial whitespace */
while ((nch!=EOF) && isspace(nch))
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL_fgetc(file);
/* get sign and first digit */
if (nch == '-') {
......@@ -1431,7 +1483,7 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
}
nch = CRTDLL_fgetc(file);
/* read until no more digits */
while ((nch!=EOF) && isdigit(nch)) {
while ((nch!=CRTDLL_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = CRTDLL_fgetc(file);
}
......@@ -1443,7 +1495,7 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
float*val = va_arg(ap, float*);
float cur = 0;
/* skip initial whitespace */
while ((nch!=EOF) && isspace(nch))
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL_fgetc(file);
/* get sign and first digit */
if (nch == '-') {
......@@ -1457,7 +1509,7 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
else break;
}
/* read until no more digits */
while ((nch!=EOF) && isdigit(nch)) {
while ((nch!=CRTDLL_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = CRTDLL_fgetc(file);
}
......@@ -1465,7 +1517,7 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
/* handle decimals */
float dec = 1;
nch = CRTDLL_fgetc(file);
while ((nch!=EOF) && isdigit(nch)) {
while ((nch!=CRTDLL_EOF) && isdigit(nch)) {
dec /= 10;
cur += dec * (nch - '0');
nch = CRTDLL_fgetc(file);
......@@ -1479,10 +1531,10 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
char*str = va_arg(ap, char*);
char*sptr = str;
/* skip initial whitespace */
while ((nch!=EOF) && isspace(nch))
while ((nch!=CRTDLL_EOF) && isspace(nch))
nch = CRTDLL_fgetc(file);
/* read until whitespace */
while ((nch!=EOF) && !isspace(nch)) {
while ((nch!=CRTDLL_EOF) && !isspace(nch)) {
*sptr++ = nch; st++;
nch = CRTDLL_fgetc(file);
}
......@@ -1505,7 +1557,7 @@ INT __cdecl CRTDLL_fscanf( CRTDLL_FILE* file, LPSTR format, ... )
format++;
}
va_end(ap);
if (nch!=EOF) {
if (nch!=CRTDLL_EOF) {
WARN("need ungetch\n");
}
TRACE("returning %d\n", rd);
......@@ -1573,7 +1625,7 @@ LPSTR __cdecl CRTDLL_gets(LPSTR buf)
* windows95's ftp.exe.
* JG 19/9/00: Is this still true, now we are using ReadFile?
*/
for(cc = CRTDLL_fgetc(CRTDLL_stdin); cc != EOF && cc != '\n';
for(cc = CRTDLL_fgetc(CRTDLL_stdin); cc != CRTDLL_EOF && cc != '\n';
cc = CRTDLL_fgetc(CRTDLL_stdin))
if(cc != '\r') *buf++ = (char)cc;
......@@ -1612,6 +1664,20 @@ INT __cdecl CRTDLL_puts(LPCSTR s)
/*********************************************************************
* remove (CRTDLL.445)
*/
INT __cdecl CRTDLL_remove(LPCSTR path)
{
TRACE(":path (%s)\n",path);
if (DeleteFileA(path))
return 0;
TRACE(":failed-last error (%ld)\n",GetLastError());
__CRTDLL__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* rewind (CRTDLL.447)
*
* Set the file pointer to the start of a file and clear any error
......@@ -1626,16 +1692,17 @@ VOID __cdecl CRTDLL_rewind(CRTDLL_FILE* file)
/*********************************************************************
* remove (CRTDLL.448)
* scanf (CRTDLL.448)
*/
INT __cdecl CRTDLL_remove(LPCSTR path)
INT __cdecl CRTDLL_scanf( LPCSTR format, ... )
{
TRACE(":path (%s)\n",path);
if (DeleteFileA(path))
return 0;
TRACE(":failed-last error (%ld)\n",GetLastError());
__CRTDLL__set_errno(GetLastError());
return -1;
va_list valist;
INT res;
va_start( valist, format );
res = CRTDLL_fscanf(CRTDLL_stdin, format, valist);
va_end(va_list);
return res;
}
......
......@@ -36,12 +36,15 @@
* a table for a supported Wine locale, mail it to me and
* I will add the needed support (jon_p_griffiths@yahoo.com).
*/
#include "crtdll.h"
#include <winnt.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "winnt.h"
DEFAULT_DEBUG_CHANNEL(crtdll);
#define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */
......
......@@ -147,7 +147,7 @@ static LPSTR __CRTDLL__argvtos(LPCSTR *arg, CHAR delim)
*
* Wait for a spawned process to finish.
*/
INT __cdecl CRTDLL__cwait(PINT status, INT pid, INT action)
INT __cdecl CRTDLL__cwait(LPINT status, INT pid, INT action)
{
HANDLE hPid = (HANDLE)pid;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment