Commit d229b98c authored by Alexandre Julliard's avatar Alexandre Julliard

Reimplemented multi-byte and wide-chars functions to not depend on

lstr* functions; added a few missing ones; fixed a couple of bugs.
parent bb1984e6
......@@ -8,7 +8,9 @@ MODULE = crtdll
SPEC_SRCS = crtdll.spec
C_SRCS = \
crtdll_main.c
crtdll_main.c \
mbstring.c \
wcstring.c
all: $(MODULE).o
......
......@@ -35,8 +35,8 @@ init CRTDLL_Init
30 stub __iscsymf
31 stub __mb_cur_max_dll
32 stub __pxcptinfoptrs
33 stub __threadhandle
34 stub __threadid
33 cdecl __threadhandle() GetCurrentThread
34 cdecl __threadid() GetCurrentThreadId
35 stub __toascii
36 cdecl _abnormal_termination() CRTDLL__abnormal_termination
37 cdecl _access(str long) CRTDLL__access
......@@ -199,16 +199,16 @@ init CRTDLL_Init
194 stub _mbctoupper
195 stub _mbctype
196 stub _mbsbtype
197 cdecl _mbscat(str str) CRTDLL__mbscat
197 cdecl _mbscat(str str) strcat
198 stub _mbschr
199 stub _mbscmp
200 cdecl _mbscpy(ptr str) CRTDLL__mbscpy
200 cdecl _mbscpy(ptr str) strcpy
201 stub _mbscspn
202 stub _mbsdec
203 stub _mbsdup
203 cdecl _mbsdup(str) CRTDLL__strdup
204 cdecl _mbsicmp(str str) CRTDLL__mbsicmp
205 cdecl _mbsinc(str) CRTDLL__mbsinc
206 stub _mbslen
206 cdecl _mbslen(str) CRTDLL__mbslen
207 stub _mbslwr
208 stub _mbsnbcat
209 stub _mbsnbcmp
......@@ -327,9 +327,9 @@ init CRTDLL_Init
322 cdecl _wcsicoll(wstr wstr) CRTDLL__wcsicoll
323 cdecl _wcslwr(wstr) CRTDLL__wcslwr
324 cdecl _wcsnicmp(wstr wstr long) CRTDLL__wcsnicmp
325 stub _wcsnset
325 cdecl _wcsnset(wstr long long) CRTDLL__wcsnset
326 cdecl _wcsrev(wstr) CRTDLL__wcsrev
327 stub _wcsset
327 cdecl _wcsset(wstr long) CRTDLL__wcsset
328 cdecl _wcsupr(wstr) CRTDLL__wcsupr
329 extern _winmajor_dll CRTDLL_winmajor_dll
330 extern _winminor_dll CRTDLL_winminor_dll
......@@ -430,7 +430,7 @@ init CRTDLL_Init
425 cdecl log10(double) log10
426 cdecl longjmp(ptr long) CRTDLL_longjmp
427 cdecl malloc(ptr) CRTDLL_malloc
428 cdecl mblen(str long) CRTDLL_mblen
428 cdecl mblen(str long) mblen
429 cdecl mbstowcs(ptr str long) CRTDLL_mbstowcs
430 cdecl mbtowc(ptr ptr long) CRTDLL_mbtowc
431 cdecl memchr(ptr long long) memchr
......@@ -516,7 +516,7 @@ init CRTDLL_Init
511 cdecl wcsncat(wstr wstr long) CRTDLL_wcsncat
512 cdecl wcsncmp(wstr wstr long) CRTDLL_wcsncmp
513 cdecl wcsncpy(ptr wstr long) CRTDLL_wcsncpy
514 stub wcspbrk
514 cdecl wcspbrk(wstr wstr) CRTDLL_wcspbrk
515 cdecl wcsrchr(wstr long) CRTDLL_wcsrchr
516 cdecl wcsspn(wstr wstr) CRTDLL_wcsspn
517 cdecl wcsstr(wstr wstr) CRTDLL_wcsstr
......@@ -526,6 +526,6 @@ init CRTDLL_Init
521 cdecl wcstombs(ptr ptr long) CRTDLL_wcstombs
522 stub wcstoul
523 stub wcsxfrm
524 stub wctomb
524 cdecl wctomb(ptr long) CRTDLL_wctomb
525 stub wprintf
526 stub wscanf
/*
* CRTDLL multi-byte string functions
*
* Copyright 1999 Alexandre Julliard
*/
#include "config.h"
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_WCTYPE_H
#include <wctype.h>
#endif
#include "windef.h"
#include "crtdll.h"
/*********************************************************************
* CRTDLL__mbsinc (CRTDLL.205)
*/
LPSTR __cdecl CRTDLL__mbsinc( LPCSTR str )
{
int len = mblen( str, MB_LEN_MAX );
if (len < 1) len = 1;
return (LPSTR)(str + len);
}
/*********************************************************************
* CRTDLL__mbslen (CRTDLL.206)
*/
INT __cdecl CRTDLL__mbslen( LPCSTR str )
{
INT len, total = 0;
while ((len = mblen( str, MB_LEN_MAX )) > 0)
{
str += len;
total++;
}
return total;
}
/*********************************************************************
* CRTDLL_mbstowcs (CRTDLL.429)
*/
INT __cdecl CRTDLL_mbstowcs( LPWSTR dst, LPCSTR src, INT n )
{
wchar_t *buffer, *p;
int ret;
if (!(buffer = CRTDLL_malloc( n * sizeof(wchar_t) ))) return -1;
ret = mbstowcs( buffer, src, n );
if (ret < n) n = ret + 1; /* nb of chars to copy (including terminating null) */
p = buffer;
while (n-- > 0) *dst++ = (WCHAR)*p++;
CRTDLL_free( buffer );
return ret;
}
/*********************************************************************
* CRTDLL_mbtowc (CRTDLL.430)
*/
INT __cdecl CRTDLL_mbtowc( WCHAR *dst, LPCSTR str, INT n )
{
wchar_t res;
int ret = mbtowc( &res, str, n );
if (dst) *dst = (WCHAR)res;
return ret;
}
/*
* CRTDLL wide-char functions
*
* Copyright 1999 Alexandre Julliard
*
* TODO:
* These functions are really necessary only if sizeof(WCHAR) != sizeof(wchar_t),
* otherwise we could use the libc functions directly.
*/
#include "config.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_WCTYPE_H
#include <wctype.h>
#endif
#include "windef.h"
#include "crtdll.h"
/*********************************************************************
* CRTDLL__wcsdup (CRTDLL.320)
*/
LPWSTR __cdecl CRTDLL__wcsdup( LPCWSTR str )
{
LPWSTR ret = NULL;
if (str)
{
int size = (CRTDLL_wcslen(str) + 1) * sizeof(WCHAR);
ret = CRTDLL_malloc( size );
if (ret) memcpy( ret, str, size );
}
return ret;
}
/*********************************************************************
* CRTDLL__wcsicmp (CRTDLL.321)
*/
INT __cdecl CRTDLL__wcsicmp( LPCWSTR str1, LPCWSTR str2 )
{
while (*str1 && (CRTDLL_towupper(*str1) == CRTDLL_towupper(*str2)))
{
str1++;
str2++;
}
return CRTDLL_towupper(*str1) - CRTDLL_towupper(*str2);
}
/*********************************************************************
* CRTDLL__wcsicoll (CRTDLL.322)
*/
INT __cdecl CRTDLL__wcsicoll( LPCWSTR str1, LPCWSTR str2 )
{
/* FIXME: handle collates */
return CRTDLL__wcsicmp( str1, str2 );
}
/*********************************************************************
* CRTDLL__wcslwr (CRTDLL.323)
*/
LPWSTR __cdecl CRTDLL__wcslwr( LPWSTR str )
{
LPWSTR ret = str;
for ( ; *str; str++) *str = CRTDLL_towlower(*str);
return ret;
}
/*********************************************************************
* CRTDLL__wcsnicmp (CRTDLL.324)
*/
INT __cdecl CRTDLL__wcsnicmp( LPCWSTR str1, LPCWSTR str2, INT n )
{
if (!n) return 0;
while ((--n > 0) && *str1 && (CRTDLL_towupper(*str1) == CRTDLL_towupper(*str2)))
{
str1++;
str2++;
}
return CRTDLL_towupper(*str1) - CRTDLL_towupper(*str2);
}
/*********************************************************************
* CRTDLL__wcsnset (CRTDLL.325)
*/
LPWSTR __cdecl CRTDLL__wcsnset( LPWSTR str, WCHAR c, INT n )
{
LPWSTR ret = str;
while ((n-- > 0) && *str) *str++ = c;
return ret;
}
/*********************************************************************
* CRTDLL__wcsrev (CRTDLL.326)
*/
LPWSTR __cdecl CRTDLL__wcsrev( LPWSTR str )
{
LPWSTR ret = str;
LPWSTR end = str + CRTDLL_wcslen(str) - 1;
while (end > str)
{
WCHAR t = *end;
*end-- = *str;
*str++ = t;
}
return ret;
}
/*********************************************************************
* CRTDLL__wcsset (CRTDLL.327)
*/
LPWSTR __cdecl CRTDLL__wcsset( LPWSTR str, WCHAR c )
{
LPWSTR ret = str;
while (*str) *str++ = c;
return ret;
}
/*********************************************************************
* CRTDLL__wcsupr (CRTDLL.328)
*/
LPWSTR __cdecl CRTDLL__wcsupr( LPWSTR str )
{
LPWSTR ret = str;
for ( ; *str; str++) *str = CRTDLL_towupper(*str);
return ret;
}
/*********************************************************************
* CRTDLL_towlower (CRTDLL.493)
*/
WCHAR __cdecl CRTDLL_towlower( WCHAR ch )
{
#ifdef HAVE_WCTYPE_H
ch = (WCHAR)towlower( (wchar_t)ch );
#else
if (!HIBYTE(ch)) ch = (WCHAR)tolower( LOBYTE(ch) ); /* FIXME */
#endif
return ch;
}
/*********************************************************************
* CRTDLL_towupper (CRTDLL.494)
*/
WCHAR __cdecl CRTDLL_towupper( WCHAR ch )
{
#ifdef HAVE_WCTYPE_H
ch = (WCHAR)towupper( (wchar_t)ch );
#else
if (!HIBYTE(ch)) ch = (WCHAR)toupper( LOBYTE(ch) ); /* FIXME */
#endif
return ch;
}
/***********************************************************************
* CRTDLL_wcscat (CRTDLL.503)
*/
LPWSTR __cdecl CRTDLL_wcscat( LPWSTR dst, LPCWSTR src )
{
LPWSTR p = dst;
while (*p) p++;
while ((*p++ = *src++));
return dst;
}
/*********************************************************************
* CRTDLL_wcschr (CRTDLL.504)
*/
LPWSTR __cdecl CRTDLL_wcschr( LPCWSTR str, WCHAR ch )
{
while (*str)
{
if (*str == ch) return (LPWSTR)str;
str++;
}
return NULL;
}
/*********************************************************************
* CRTDLL_wcscmp (CRTDLL.505)
*/
INT __cdecl CRTDLL_wcscmp( LPCWSTR str1, LPCWSTR str2 )
{
while (*str1 && (*str1 == *str2)) { str1++; str2++; }
return (INT)(*str1 - *str2);
}
/*********************************************************************
* CRTDLL_wcscoll (CRTDLL.506)
*/
DWORD __cdecl CRTDLL_wcscoll( LPCWSTR str1, LPCWSTR str2 )
{
/* FIXME: handle collates */
return CRTDLL_wcscmp( str1, str2 );
}
/***********************************************************************
* CRTDLL_wcscpy (CRTDLL.507)
*/
LPWSTR __cdecl CRTDLL_wcscpy( LPWSTR dst, LPCWSTR src )
{
LPWSTR p = dst;
while ((*p++ = *src++));
return dst;
}
/*********************************************************************
* CRTDLL_wcscspn (CRTDLL.508)
*/
INT __cdecl CRTDLL_wcscspn( LPCWSTR str, LPCWSTR reject )
{
LPCWSTR start = str;
while (*str)
{
LPCWSTR p = reject;
while (*p && (*p != *str)) p++;
if (*p) break;
str++;
}
return str - start;
}
/***********************************************************************
* CRTDLL_wcslen (CRTDLL.510)
*/
INT __cdecl CRTDLL_wcslen( LPCWSTR str )
{
LPCWSTR s = str;
while (*s) s++;
return s - str;
}
/*********************************************************************
* CRTDLL_wcsncat (CRTDLL.511)
*/
LPWSTR __cdecl CRTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT n )
{
LPWSTR ret = s1;
while (*s1) s1++;
while (n-- > 0) if (!(*s1++ = *s2++)) return ret;
*s1 = 0;
return ret;
}
/*********************************************************************
* CRTDLL_wcsncmp (CRTDLL.512)
*/
INT __cdecl CRTDLL_wcsncmp( LPCWSTR str1, LPCWSTR str2, INT n )
{
if (!n) return 0;
while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
return (INT)(*str1 - *str2);
}
/*********************************************************************
* CRTDLL_wcsncpy (CRTDLL.513)
*/
LPWSTR __cdecl CRTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT n )
{
LPWSTR ret = s1;
while (n-- > 0) if (!(*s1++ = *s2++)) break;
while (n-- > 0) *s1++ = 0;
return ret;
}
/*********************************************************************
* CRTDLL_wcspbrk (CRTDLL.514)
*/
LPWSTR __cdecl CRTDLL_wcspbrk( LPCWSTR str, LPCWSTR accept )
{
LPCWSTR p;
while (*str)
{
for (p = accept; *p; p++) if (*p == *str) return (LPWSTR)str;
str++;
}
return NULL;
}
/*********************************************************************
* CRTDLL_wcsrchr (CRTDLL.515)
*/
LPWSTR __cdecl CRTDLL_wcsrchr( LPWSTR str, WCHAR ch )
{
LPWSTR last = NULL;
while (*str)
{
if (*str == ch) last = str;
str++;
}
return last;
}
/*********************************************************************
* CRTDLL_wcsspn (CRTDLL.516)
*/
INT __cdecl CRTDLL_wcsspn( LPCWSTR str, LPCWSTR accept )
{
LPCWSTR start = str;
while (*str)
{
LPCWSTR p = accept;
while (*p && (*p != *str)) p++;
if (!*p) break;
str++;
}
return str - start;
}
/*********************************************************************
* CRTDLL_wcsstr (CRTDLL.517)
*/
LPWSTR __cdecl CRTDLL_wcsstr( LPCWSTR str, LPCWSTR sub )
{
while (*str)
{
LPCWSTR p1 = str, p2 = sub;
while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
if (!*p2) return (LPWSTR)str;
str++;
}
return NULL;
}
/*********************************************************************
* CRTDLL_wcstok (CRTDLL.519)
*/
LPWSTR __cdecl CRTDLL_wcstok( LPWSTR str, LPCWSTR delim )
{
static LPWSTR next = NULL;
LPWSTR ret;
if (!str)
if (!(str = next)) return NULL;
while (*str && CRTDLL_wcschr( delim, *str )) str++;
if (!*str) return NULL;
ret = str++;
while (*str && !CRTDLL_wcschr( delim, *str )) str++;
if (*str) *str++ = 0;
next = str;
return ret;
}
/*********************************************************************
* CRTDLL_wcstombs (CRTDLL.521)
*/
INT __cdecl CRTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT n )
{
wchar_t *buffer, *p;
int ret;
int size = (CRTDLL_wcslen(src) + 1) * sizeof(wchar_t);
if (!(buffer = CRTDLL_malloc( size ))) return -1;
p = buffer;
while ((*p++ = (wchar_t)*src++));
ret = wcstombs( dst, buffer, n );
CRTDLL_free( buffer );
return ret;
}
/*********************************************************************
* CRTDLL_wctomb (CRTDLL.524)
*/
INT __cdecl CRTDLL_wctomb( LPSTR dst, WCHAR ch )
{
return wctomb( dst, (wchar_t)ch );
}
......@@ -907,7 +907,7 @@ type win32
899 cdecl isxdigit(long) isxdigit
900 stub labs
901 stub log
902 stub mbstowcs
902 cdecl mbstowcs(ptr str long) CRTDLL_mbstowcs
903 cdecl memchr(ptr long long) memchr
904 cdecl memcmp(ptr ptr long) memcmp
905 cdecl memcpy(ptr ptr long) memcpy
......@@ -943,12 +943,12 @@ type win32
935 cdecl wcschr(wstr long) CRTDLL_wcschr
936 cdecl wcscmp(wstr wstr) CRTDLL_wcscmp
937 cdecl wcscpy(ptr wstr) CRTDLL_wcscpy
938 stub wcscspn
938 cdecl wcscspn(wstr wstr) CRTDLL_wcscspn
939 cdecl wcslen(wstr) CRTDLL_wcslen
940 stub wcsncat
940 cdecl wcsncat(wstr wstr long) CRTDLL_wcsncat
941 cdecl wcsncmp(wstr wstr long) CRTDLL_wcsncmp
942 cdecl wcsncpy(ptr wstr long) CRTDLL_wcsncpy
943 stub wcspbrk
943 cdecl wcspbrk(wstr wstr) CRTDLL_wcspbrk
944 cdecl wcsrchr(wstr long) CRTDLL_wcsrchr
945 cdecl wcsspn(wstr wstr) CRTDLL_wcsspn
946 cdecl wcsstr(wstr wstr) CRTDLL_wcsstr
......
......@@ -27,4 +27,75 @@
/* function prototypes used in crtdll.c */
extern int LastErrorToErrno(DWORD);
void * __cdecl CRTDLL_malloc( DWORD size );
void __cdecl CRTDLL_free( void *ptr );
LPSTR __cdecl CRTDLL__mbsinc( LPCSTR str );
INT __cdecl CRTDLL__mbslen( LPCSTR str );
LPWSTR __cdecl CRTDLL__wcsdup( LPCWSTR str );
INT __cdecl CRTDLL__wcsicmp( LPCWSTR str1, LPCWSTR str2 );
INT __cdecl CRTDLL__wcsicoll( LPCWSTR str1, LPCWSTR str2 );
LPWSTR __cdecl CRTDLL__wcslwr( LPWSTR str );
INT __cdecl CRTDLL__wcsnicmp( LPCWSTR str1, LPCWSTR str2, INT n );
LPWSTR __cdecl CRTDLL__wcsnset( LPWSTR str, WCHAR c, INT n );
LPWSTR __cdecl CRTDLL__wcsrev( LPWSTR str );
LPWSTR __cdecl CRTDLL__wcsset( LPWSTR str, WCHAR c );
LPWSTR __cdecl CRTDLL__wcsupr( LPWSTR str );
INT __cdecl CRTDLL_mbstowcs( LPWSTR dst, LPCSTR src, INT n );
INT __cdecl CRTDLL_mbtowc( WCHAR *dst, LPCSTR str, INT n );
WCHAR __cdecl CRTDLL_towlower( WCHAR ch );
WCHAR __cdecl CRTDLL_towupper( WCHAR ch );
LPWSTR __cdecl CRTDLL_wcscat( LPWSTR dst, LPCWSTR src );
LPWSTR __cdecl CRTDLL_wcschr( LPCWSTR str, WCHAR ch );
INT __cdecl CRTDLL_wcscmp( LPCWSTR str1, LPCWSTR str2 );
DWORD __cdecl CRTDLL_wcscoll( LPCWSTR str1, LPCWSTR str2 );
LPWSTR __cdecl CRTDLL_wcscpy( LPWSTR dst, LPCWSTR src );
INT __cdecl CRTDLL_wcscspn( LPCWSTR str, LPCWSTR reject );
INT __cdecl CRTDLL_wcslen( LPCWSTR str );
LPWSTR __cdecl CRTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT n );
INT __cdecl CRTDLL_wcsncmp( LPCWSTR str1, LPCWSTR str2, INT n );
LPWSTR __cdecl CRTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT n );
LPWSTR __cdecl CRTDLL_wcspbrk( LPCWSTR str, LPCWSTR accept );
LPWSTR __cdecl CRTDLL_wcsrchr( LPWSTR str, WCHAR ch );
INT __cdecl CRTDLL_wcsspn( LPCWSTR str, LPCWSTR accept );
LPWSTR __cdecl CRTDLL_wcsstr( LPCWSTR str, LPCWSTR sub );
LPWSTR __cdecl CRTDLL_wcstok( LPWSTR str, LPCWSTR delim );
INT __cdecl CRTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT n );
INT __cdecl CRTDLL_wctomb( LPSTR dst, WCHAR ch );
#ifdef notyet
#define _mbsinc CRTDLL__mbsinc
#define _mbslen CRTDLL__mbslen
#define _wcsdup CRTDLL__wcsdup
#define _wcsicmp CRTDLL__wcsicmp
#define _wcsicoll CRTDLL__wcsicoll
#define _wcslwr CRTDLL__wcslwr
#define _wcsnicmp CRTDLL__wcsnicmp
#define _wcsnset CRTDLL__wcsnset
#define _wcsrev CRTDLL__wcsrev
#define _wcsset CRTDLL__wcsset
#define _wcsupr CRTDLL__wcsupr
#define mbstowcs CRTDLL_mbstowcs
#define mbtowc CRTDLL_mbtowc
#define towlower CRTDLL_towlower
#define towupper CRTDLL_towupper
#define wcscat CRTDLL_wcscat
#define wcschr CRTDLL_wcschr
#define wcscmp CRTDLL_wcscmp
#define wcscoll CRTDLL_wcscoll
#define wcscpy CRTDLL_wcscpy
#define wcscspn CRTDLL_wcscspn
#define wcslen CRTDLL_wcslen
#define wcsncat CRTDLL_wcsncat
#define wcsncmp CRTDLL_wcsncmp
#define wcsncpy CRTDLL_wcsncpy
#define wcspbrk CRTDLL_wcspbrk
#define wcsrchr CRTDLL_wcsrchr
#define wcsspn CRTDLL_wcsspn
#define wcsstr CRTDLL_wcsstr
#define wcstok CRTDLL_wcstok
#define wcstombs CRTDLL_wcstombs
#define wctomb CRTDLL_wctomb
#endif
#endif /* __WINE_CRTDLL_H */
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