* mingwex/mbrtowc.c: New file.
* mingwex/wcrtomb.c: New file. * mingwex/btowc.c: New file. * mingwex/wctob.c: New file. * mingwex/mb_wc_common.h: New file. * mingwex/Makefile.in (DISTFILES): Add new files. (Q8_OBJS): Add new objects. * include/wchar.h: Adjust comment about mbrtowc() and related funcions. Add __restrict__ to pointer params in prototypes. (wmemset. wmemchr, wmemcpy, wmemmove, wcstoll, wcstoull): Remove arg names from protototypes.
This commit is contained in:
		
							parent
							
								
									4fc953d6a1
								
							
						
					
					
						commit
						6fbeb6a3f0
					
				|  | @ -1,8 +1,21 @@ | |||
| 2005-04-23  Danny Smith  <dannysmith@users.sourceforge.net> | ||||
| 
 | ||||
| 	* mingwex/mbrtowc.c: New file. | ||||
| 	* mingwex/wcrtomb.c: New file. | ||||
| 	* mingwex/btowc.c: New file. | ||||
| 	* mingwex/wctob.c: New file. | ||||
| 	* mingwex/mb_wc_common.h: New file. | ||||
| 	* mingwex/Makefile.in (DISTFILES): Add new files. | ||||
| 	(Q8_OBJS): Add new objects. | ||||
| 	* include/wchar.h: Adjust comment about mbrtowc() and related | ||||
| 	funcions. Add __restrict__ to pointer params in prototypes. | ||||
| 	(wmemset. wmemchr, wmemcpy, wmemmove, wcstoll, wcstoull): Remove | ||||
| 	arg names from protototypes. | ||||
| 	 | ||||
| 2005-04-23  Wu Yongwei  <adah@sh163.net> | ||||
| 
 | ||||
| 	mingwex/dirent.c: Formatting changes. | ||||
| 
 | ||||
| 	mingwex/dirent.c (_topendir): Make the end-of-path slash check | ||||
| 	* mingwex/dirent.c: Formatting changes. | ||||
| 	* mingwex/dirent.c (_topendir): Make the end-of-path slash check | ||||
| 	MBCS-safe. | ||||
| 
 | ||||
| 2005-03-31  Danny Smith  <dannysmith@users.sourceforge.net> | ||||
|  |  | |||
|  | @ -254,9 +254,11 @@ _CRTIMP wchar_t* __cdecl wcsupr (wchar_t*); | |||
| #define _WSTRING_DEFINED | ||||
| #endif  /* _WSTRING_DEFINED */ | ||||
| 
 | ||||
| /* These are resolved by -lmsvcp60 */ | ||||
| /* If you don't have msvcp60.dll in your windows system directory, you can
 | ||||
|    easily obtain it with a search from your favorite search engine. */ | ||||
| /* These are resolved by -lmingwex. Alternatively, they can be resolved by
 | ||||
|    adding -lmsvcp60 to your command line, which will give you the VC++ | ||||
|    versions of these functions. If you want the latter and don't have | ||||
|    msvcp60.dll in your windows system directory, you can easily obtain | ||||
|    it with a search from your favorite search engine.  */ | ||||
| #ifndef __STRICT_ANSI__ | ||||
| typedef wchar_t _Wint_t; | ||||
| #endif | ||||
|  | @ -264,29 +266,35 @@ typedef wchar_t _Wint_t; | |||
| typedef int mbstate_t; | ||||
| 
 | ||||
| wint_t __cdecl btowc(int); | ||||
| size_t __cdecl mbrlen(const char *, size_t, mbstate_t *); | ||||
| size_t __cdecl mbrtowc(wchar_t *, const char *, size_t, mbstate_t *); | ||||
| size_t __cdecl mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *); | ||||
| 
 | ||||
| size_t __cdecl wcrtomb(char *, wchar_t, mbstate_t *); | ||||
| size_t __cdecl wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *); | ||||
| size_t __cdecl mbrlen(const char * __restrict__, size_t, | ||||
| 		      mbstate_t * __restrict__); | ||||
| size_t __cdecl mbrtowc(wchar_t * __restrict__, const char * __restrict__, | ||||
| 		       size_t, mbstate_t * __restrict__); | ||||
| size_t __cdecl mbsrtowcs(wchar_t * __restrict__, const char ** __restrict__, | ||||
| 			 size_t, mbstate_t * __restrict__); | ||||
| size_t __cdecl wcrtomb(char * __restrict__, wchar_t, | ||||
| 		       mbstate_t * __restrict__); | ||||
| size_t __cdecl wcsrtombs(char * __restrict__, const wchar_t ** __restrict__, | ||||
| 			 size_t, mbstate_t * __restrict__); | ||||
| int __cdecl wctob(wint_t); | ||||
| 
 | ||||
| #ifndef __NO_ISOCEXT /* these need static lib libmingwex.a */ | ||||
| __CRT_INLINE int __cdecl fwide(FILE* __UNUSED_PARAM(stream), int __UNUSED_PARAM(mode)) | ||||
| __CRT_INLINE int __cdecl fwide(FILE* __UNUSED_PARAM(stream), | ||||
| 			       int __UNUSED_PARAM(mode)) | ||||
|   {return -1;} /* limited to byte orientation */  | ||||
| __CRT_INLINE int __cdecl mbsinit(const mbstate_t* __UNUSED_PARAM(ps)) | ||||
|   {return 1;} | ||||
| wchar_t* __cdecl wmemset(wchar_t* s, wchar_t c, size_t n); | ||||
| wchar_t* __cdecl wmemchr(const wchar_t* s, wchar_t c, size_t n); | ||||
| int wmemcmp(const wchar_t* s1, const wchar_t * s2, size_t n); | ||||
| wchar_t* __cdecl wmemcpy(wchar_t* __restrict__ s1, const wchar_t* __restrict__ s2, | ||||
| 		 size_t n); | ||||
| wchar_t* __cdecl wmemmove(wchar_t* s1, const wchar_t* s2, size_t n); | ||||
| long long __cdecl wcstoll(const wchar_t* __restrict__ nptr, | ||||
| 		  wchar_t** __restrict__ endptr, int base); | ||||
| unsigned long long __cdecl wcstoull(const wchar_t* __restrict__ nptr, | ||||
| 			    wchar_t ** __restrict__ endptr, int base); | ||||
| wchar_t* __cdecl wmemset(wchar_t *, wchar_t, size_t); | ||||
| wchar_t* __cdecl wmemchr(const wchar_t*, wchar_t, size_t); | ||||
| int wmemcmp(const wchar_t*, const wchar_t *, size_t); | ||||
| wchar_t* __cdecl wmemcpy(wchar_t* __restrict__, | ||||
| 		         const wchar_t* __restrict__, | ||||
| 			 size_t); | ||||
| wchar_t* __cdecl wmemmove(wchar_t* s1, const wchar_t *, size_t); | ||||
| long long __cdecl wcstoll(const wchar_t * __restrict__, | ||||
| 			  wchar_t** __restrict__, int); | ||||
| unsigned long long __cdecl wcstoull(const wchar_t * __restrict__, | ||||
| 			    wchar_t ** __restrict__, int); | ||||
| #endif /* __NO_ISOCEXT */ | ||||
| 
 | ||||
| #ifndef	__STRICT_ANSI__ | ||||
|  |  | |||
|  | @ -34,7 +34,8 @@ DISTFILES = Makefile.in configure configure.in \ | |||
| 	mingw-fseek.c sitest.c strtof.c strtoimax.c strtold.c strtoumax.c \
 | ||||
| 	testwmem.c tst-aligned-malloc.c ulltoa.c ulltow.c wcstof.c \
 | ||||
| 	wcstoimax.c wcstold.c wcstoumax.c wctrans.c wctype.c \
 | ||||
| 	wdirent.c wmemchr.c wmemcmp.c wmemcpy.c wmemmove.c wmemset.c wtoll.c	 | ||||
| 	wdirent.c wmemchr.c wmemcmp.c wmemcpy.c wmemmove.c wmemset.c wtoll.c \
 | ||||
| 	wcrtomb.c wctob.c mbrtowc.c btowc.c mb_wc_common.h | ||||
| MATH_DISTFILES = \
 | ||||
| 	acosf.c acosl.c asinf.c asinl.c atan2f.c atan2l.c \
 | ||||
| 	atanf.c atanl.c cbrt.c cbrtf.c cbrtl.c ceilf.S ceill.S \
 | ||||
|  | @ -114,7 +115,7 @@ Q8_OBJS = \ | |||
| 	fwide.o imaxabs.o imaxdiv.o mbsinit.o \
 | ||||
| 	strtoimax.o strtoumax.o wcstoimax.o wcstoumax.o \
 | ||||
| 	wmemchr.o wmemcmp.o wmemcpy.o wmemmove.o wmemset.o \
 | ||||
| 	wctrans.o wctype.o | ||||
| 	wctrans.o wctype.o wcrtomb.o wctob.o mbrtowc.o btowc.o | ||||
| STDLIB_OBJS = \
 | ||||
| 	strtold.o wcstold.o | ||||
| STDLIB_STUB_OBJS = \
 | ||||
|  | @ -232,7 +233,7 @@ wcstold.o: $(srcdir)/wcstold.c $(srcdir)/math/cephes_emath.h | |||
| acosh.o acoshf.o acoshl.o \ | ||||
| asinh.o asinhf.o asinhl.o \ | ||||
| atanh.o atanhf.o atanhl.o: fastmath.h | ||||
| 
 | ||||
| mbrtowc.o wcrtomb.o: mb_wc_common.h   | ||||
| 
 | ||||
| dist: | ||||
| 	mkdir $(distdir)/mingwex | ||||
|  |  | |||
|  | @ -0,0 +1,19 @@ | |||
| #include "mb_wc_common.h" | ||||
| #include <wchar.h> | ||||
| #include <stdio.h> | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #include <windows.h> | ||||
| 
 | ||||
| wint_t btowc (int c) | ||||
| { | ||||
|   if (c == EOF) | ||||
|     return (WEOF); | ||||
|   else | ||||
|     { | ||||
|       unsigned char ch = c; | ||||
|       wchar_t wc = WEOF; | ||||
|       MultiByteToWideChar (get_cp_from_locale(), MB_ERR_INVALID_CHARS, | ||||
| 			   (char*)&ch, 1, &wc, 1); | ||||
|       return wc; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,18 @@ | |||
| #include <locale.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| static inline | ||||
| unsigned int get_cp_from_locale (void) | ||||
| { | ||||
|   char* cp_string; | ||||
|   /*
 | ||||
|     locale :: "lang[_country[.code_page]]"  | ||||
|                | ".code_page" | ||||
| 
 | ||||
|   */ | ||||
| 
 | ||||
|   if ((cp_string = strchr(setlocale(LC_CTYPE, NULL), '.'))) | ||||
|     return  ((unsigned) atoi (cp_string + 1)); | ||||
|   return 0; | ||||
| } | ||||
|  | @ -0,0 +1,164 @@ | |||
| #include "mb_wc_common.h" | ||||
| #include <wchar.h> | ||||
| #include <stdlib.h> | ||||
| #include <errno.h> | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #include <windows.h> | ||||
| 
 | ||||
| #define MBTOWC_FLAGS (MB_PRECOMPOSED | MB_ERR_INVALID_CHARS) | ||||
| /* Attribute `nonnull' was valid as of gcc 3.3.  */ | ||||
| #ifndef ATTRIBUTE_NONNULL | ||||
| # if (__GNUC__ > 3 ||( __GNUC__ == 3 &&  __GNUC_MINOR__ >= 3)) | ||||
| #  define ATTRIBUTE_NONNULL(m...) __attribute__ ((__nonnull__ (m))) | ||||
| # else | ||||
| #  define ATTRIBUTE_NONNULL(m...) | ||||
| # endif /* GNUC >= 3.3 */ | ||||
| #endif /* ATTRIBUTE_NONNULL */ | ||||
| 
 | ||||
| static int ATTRIBUTE_NONNULL(1, 4) | ||||
| __mbrtowc_cp (wchar_t * __restrict__ pwc, const char * __restrict__ s, | ||||
| 	      size_t n, mbstate_t* __restrict__ ps, | ||||
| 	      const unsigned int cp, const unsigned int mb_max)  | ||||
| { | ||||
|   union { | ||||
|     mbstate_t val; | ||||
|     char mbcs[4]; | ||||
|   }  shift_state; | ||||
| 
 | ||||
| 
 | ||||
|   /* Do the prelim checks */ | ||||
|   if (s == NULL) | ||||
|     return 0; | ||||
| 
 | ||||
|   if (n == 0) | ||||
|     /* The standard doesn't mention this case explicitly. Tell
 | ||||
|        caller that the conversion from a non-null s is incomplete. */ | ||||
|     return -2; | ||||
| 
 | ||||
|   /* Save the current shift state, in case we need it in DBCS case.  */ | ||||
|   shift_state.val = *ps; | ||||
|   *ps = 0; | ||||
| 
 | ||||
|   if (!*s) | ||||
|     { | ||||
|       *pwc = 0; | ||||
|       return 0; | ||||
|     } | ||||
|   | ||||
|   if (mb_max > 1) | ||||
|     { | ||||
|       if (shift_state.mbcs[0] != 0) | ||||
| 	{ | ||||
| 	  /* Complete the mb char with the trailing byte.  */ | ||||
|           shift_state.mbcs[1] = *s;  /* the second byte */ | ||||
|           if (MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, | ||||
| 				  shift_state.mbcs, 2, pwc, 1) | ||||
| 		 == 0) | ||||
| 	    { | ||||
| 	      /* An invalid trailing byte */	  | ||||
| 	      errno = EILSEQ; | ||||
| 	      return -1; | ||||
| 	    } | ||||
|           return 2; | ||||
|         } | ||||
|       else if (IsDBCSLeadByteEx (cp, *s)) | ||||
|         { | ||||
|           /* If told to translate one byte, just save the leadbyte
 | ||||
|              in *ps.  */ | ||||
| 	  if (n < 2) | ||||
| 	    { | ||||
| 	      ((char*) ps)[0] = *s;  | ||||
| 	      return -2; | ||||
| 	    } | ||||
|           /* Else translate the first two bytes  */   | ||||
|           else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, | ||||
| 					s, 2, pwc, 1) | ||||
| 		    == 0) | ||||
| 	    { | ||||
| 	      errno = EILSEQ; | ||||
| 	      return -1; | ||||
| 	    } | ||||
|           return 2; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   /* Fall through to single byte char  */  | ||||
|   if (cp == 0) | ||||
|       *pwc = (wchar_t)(unsigned char)*s; | ||||
|   | ||||
|   else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, s, 1, pwc, 1) | ||||
| 	    == 0) | ||||
|     { | ||||
|       errno = EILSEQ; | ||||
|       return  -1; | ||||
|     } | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| size_t | ||||
| mbrtowc (wchar_t * __restrict__ pwc, const char * __restrict__ s, | ||||
| 	 size_t n, mbstate_t* __restrict__ ps) | ||||
| { | ||||
|   static mbstate_t internal_mbstate = 0; | ||||
|   wchar_t  byte_bucket = 0; | ||||
|   wchar_t* dst = pwc ? pwc : &byte_bucket; | ||||
| 
 | ||||
|   return (size_t) __mbrtowc_cp (dst, s, n, ps ? ps : &internal_mbstate, | ||||
| 				get_cp_from_locale(), MB_CUR_MAX); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| size_t | ||||
| mbsrtowcs (wchar_t* __restrict__ dst,  const char ** __restrict__ src, | ||||
| 	   size_t len, mbstate_t* __restrict__ ps) | ||||
| { | ||||
|   int ret =0 ; | ||||
|   size_t n = 0; | ||||
|   static mbstate_t internal_mbstate = 0; | ||||
|   mbstate_t* internal_ps = ps ? ps : &internal_mbstate; | ||||
|   const unsigned int cp = get_cp_from_locale();; | ||||
|   const unsigned int mb_max = MB_CUR_MAX; | ||||
| 
 | ||||
|   if ( src == NULL || *src == NULL )	/* undefined behavior */ | ||||
|     return 0; | ||||
| 
 | ||||
|   if (dst != NULL) | ||||
|     { | ||||
|       while (n < len | ||||
| 	     && (ret = __mbrtowc_cp(dst, *src, len - n, | ||||
| 				    internal_ps, cp, mb_max)) | ||||
| 		  > 0) | ||||
| 	{ | ||||
| 	  ++dst; | ||||
|    	  *src += ret; | ||||
|           n += ret; | ||||
|         } | ||||
| 
 | ||||
|       if (n < len && ret == 0) | ||||
|         *src = (char *)NULL; | ||||
|     } | ||||
|    | ||||
|   else | ||||
|     { | ||||
|       wchar_t byte_bucket = 0; | ||||
|       while (n < len | ||||
| 	     && (ret = __mbrtowc_cp (&byte_bucket, *src, mb_max, | ||||
| 				     internal_ps, cp, mb_max)) | ||||
| 		  > 0) | ||||
| 	{ | ||||
|           *src += ret; | ||||
|           n += ret; | ||||
|         } | ||||
|     } | ||||
|   return n; | ||||
| } | ||||
| 
 | ||||
| size_t | ||||
| mbrlen (const char * __restrict__ s, size_t n, | ||||
| 	mbstate_t * __restrict__ ps) | ||||
| { | ||||
|   static mbstate_t s_mbstate = 0; | ||||
|   wchar_t byte_bucket = 0; | ||||
|   return __mbrtowc_cp (&byte_bucket, s, n, (ps) ? ps : &s_mbstate, | ||||
| 		       get_cp_from_locale(), MB_CUR_MAX); | ||||
| } | ||||
|  | @ -0,0 +1,94 @@ | |||
| #include "mb_wc_common.h" | ||||
| #include <wchar.h> | ||||
| #include <stdlib.h> | ||||
| #include <errno.h> | ||||
| #include <limits.h> | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #include <windows.h> | ||||
| 
 | ||||
| 
 | ||||
| static int __MINGW_ATTRIB_NONNULL(1) | ||||
|  __wcrtomb_cp (char *dst, wchar_t wc, const unsigned int cp, | ||||
| 	       const unsigned int mb_max) | ||||
| {        | ||||
|  if (wc > 255) | ||||
|     { | ||||
|       errno = EILSEQ; | ||||
|       return -1; | ||||
|     } | ||||
| 
 | ||||
|   if (cp == 0) | ||||
|     { | ||||
|       *dst = (char) wc; | ||||
|       return 1; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       int invalid_char = 0; | ||||
|     | ||||
|       int size = WideCharToMultiByte(get_cp_from_locale(), | ||||
| 				     0 /* Is this correct flag? */, | ||||
| 				     &wc, 1, dst, mb_max, | ||||
| 				     NULL, &invalid_char); | ||||
|       if (size == 0 || invalid_char)   | ||||
|         { | ||||
|           errno = EILSEQ; | ||||
|           return -1; | ||||
|         } | ||||
|       return size; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| size_t | ||||
| wcrtomb (char *dst, wchar_t wc, mbstate_t * __UNUSED_PARAM (ps)) | ||||
| { | ||||
|   char byte_bucket [MB_LEN_MAX]; | ||||
|   char* tmp_dst = dst ? dst : byte_bucket;       | ||||
|   return (size_t)__wcrtomb_cp (tmp_dst, wc, get_cp_from_locale (), | ||||
| 			       MB_CUR_MAX); | ||||
| } | ||||
| 
 | ||||
| size_t wcsrtombs (char *dst, const wchar_t **src, size_t len, | ||||
| 		  mbstate_t * __UNUSED_PARAM (ps)) | ||||
| { | ||||
|   int ret = 0; | ||||
|   size_t n = 0; | ||||
|   const unsigned int cp = get_cp_from_locale(); | ||||
|   const unsigned int mb_max = MB_CUR_MAX; | ||||
| 
 | ||||
|   if (src == NULL || *src == NULL) /* undefined behavior */ | ||||
|      return 0; | ||||
| 
 | ||||
|   if (dst != NULL) | ||||
|     { | ||||
|       const wchar_t ** saved_src = src; | ||||
|       while (n < len) | ||||
|         { | ||||
|           if ((ret = __wcrtomb_cp (dst, **src, cp, mb_max)) <= 0) | ||||
| 	     return (size_t) -1; | ||||
|   	  n += ret; | ||||
|    	  dst += ret; | ||||
|           if (*(dst - 1) == '\0') | ||||
| 	    { | ||||
| 	      *saved_src = (wchar_t) NULL;; | ||||
| 	      return (n  - 1); | ||||
| 	    } | ||||
| 	  *src++; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       char byte_bucket [MB_LEN_MAX]; | ||||
|       while (n < len) | ||||
|         { | ||||
| 	  if ((ret = __wcrtomb_cp (byte_bucket, **src, cp, mb_max)) | ||||
| 		 <= 0) | ||||
|  	    return (size_t) -1;     | ||||
| 	  n += ret; | ||||
| 	  if (byte_bucket [ret - 1] == '\0') | ||||
| 	    return (n - 1); | ||||
|           *src++; | ||||
|         } | ||||
|     } | ||||
|   return n; | ||||
| } | ||||
|  | @ -0,0 +1,21 @@ | |||
| #include "mb_wc_common.h" | ||||
| #include <wchar.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <errno.h> | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #include <windows.h> | ||||
| 
 | ||||
| /* Return just the first byte after translating to multibyte.  */ | ||||
| int wctob (wint_t wc ) | ||||
| { | ||||
|     wchar_t w = wc; | ||||
|     char c; | ||||
|     int invalid_char = 0; | ||||
|     if (!WideCharToMultiByte (get_cp_from_locale(),  | ||||
| 			      0 /* Is this correct flag? */, | ||||
| 			      &w, 1, &c, 1, NULL, &invalid_char) | ||||
|          || invalid_char) | ||||
|       return EOF; | ||||
|     return (int) c; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue