From: Michihiro NAKAJIMA Date: Mon, 6 Feb 2012 21:41:20 +0000 (+0900) Subject: Simplify a string conversion WCS <==> MBS to stop using mbsnrtowcs and wcsnrtombs. X-Git-Tag: v3.0.4~2^2~112 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47a982508588c3a6cdfb5fb9360bc04ee011898f;p=thirdparty%2Flibarchive.git Simplify a string conversion WCS <==> MBS to stop using mbsnrtowcs and wcsnrtombs. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d16818ba9..1714df019 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -665,7 +665,6 @@ CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R) CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT) CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES) CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC) -CHECK_FUNCTION_EXISTS_GLIBC(mbsnrtowcs HAVE_MBSNRTOWCS) CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE) CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR) CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO) @@ -699,7 +698,6 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB) CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP) CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY) CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN) -CHECK_FUNCTION_EXISTS_GLIBC(wcsnrtombs HAVE_WCSNRTOMBS) CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB) CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S) CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64) diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index 5ccf3681d..4f1463c57 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -664,9 +664,6 @@ typedef uint64_t uintmax_t; /* Define to 1 if you have the `mbrtowc' function. */ #cmakedefine HAVE_MBRTOWC 1 -/* Define to 1 if you have the `mbsnrtowcs' function. */ -#cmakedefine HAVE_MBSNRTOWCS 1 - /* Define to 1 if you have the `memmove' function. */ #cmakedefine HAVE_MEMMOVE 1 @@ -949,9 +946,6 @@ typedef uint64_t uintmax_t; /* Define to 1 if you have the `wcslen' function. */ #cmakedefine HAVE_WCSLEN 1 -/* Define to 1 if you have the `wcsnrtombs' function. */ -#cmakedefine HAVE_WCSNRTOMBS 1 - /* Define to 1 if you have the `wctomb' function. */ #cmakedefine HAVE_WCTOMB 1 diff --git a/configure.ac b/configure.ac index 4108cb54e..c15d43272 100644 --- a/configure.ac +++ b/configure.ac @@ -437,13 +437,13 @@ AC_CHECK_FUNCS([futimens futimes futimesat]) AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r]) AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r]) AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes]) -AC_CHECK_FUNCS([mbrtowc mbsnrtowcs memmove memset]) +AC_CHECK_FUNCS([mbrtowc memmove memset]) AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp]) AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat]) AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs]) AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm]) AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork]) -AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wcsnrtombs wctomb wmemcmp wmemcpy]) +AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy]) AC_CHECK_FUNCS([_ctime64_s _fseeki64]) AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64]) # detects cygwin-1.7, as opposed to older versions diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c index b168e28da..379074333 100644 --- a/libarchive/archive_string.c +++ b/libarchive/archive_string.c @@ -586,41 +586,6 @@ archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest, return (ret); } -#elif defined(HAVE_MBSNRTOWCS) - -/* - * Convert MBS to WCS. - * Note: returns -1 if conversion fails. - */ -int -archive_wstring_append_from_mbs(struct archive_wstring *dest, - const char *p, size_t len) -{ - size_t r; - /* - * No single byte will be more than one wide character, - * so this length estimate will always be big enough. - */ - size_t wcs_length = len; - size_t mbs_length = len; - const char *mbs = p; - wchar_t *wcs; - mbstate_t shift_state; - - memset(&shift_state, 0, sizeof(shift_state)); - if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1)) - return (-1); - wcs = dest->s + dest->length; - r = mbsnrtowcs(wcs, &mbs, mbs_length, wcs_length, &shift_state); - if (r != (size_t)-1) { - dest->length += r; - dest->s[dest->length] = L'\0'; - return (0); - } - dest->s[dest->length] = L'\0'; - return (-1); -} - #else /* @@ -632,6 +597,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, const char *p, size_t len) { size_t r; + int ret_val = 0; /* * No single byte will be more than one wide character, * so this length estimate will always be big enough. @@ -653,15 +619,29 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, * extra MBS when strlen(p) > len and one wide character consis of * multi bytes. */ - while (wcs_length > 0 && *mbs && mbs_length > 0) { + while (*mbs && mbs_length > 0) { + if (wcs_length == 0) { + dest->length = wcs - dest->s; + dest->s[dest->length] = L'\0'; + wcs_length = mbs_length; + if (NULL == archive_wstring_ensure(dest, + dest->length + wcs_length + 1)) + return (-1); + wcs = dest->s + dest->length; + } #if HAVE_MBRTOWC r = mbrtowc(wcs, mbs, wcs_length, &shift_state); #else r = mbtowc(wcs, mbs, wcs_length); #endif if (r == (size_t)-1 || r == (size_t)-2) { - dest->s[dest->length] = L'\0'; - return (-1); + ret_val = -1; + if (errno == EILSEQ) { + ++mbs; + --mbs_length; + continue; + } else + break; } if (r == 0 || r > mbs_length) break; @@ -672,7 +652,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, } dest->length = wcs - dest->s; dest->s[dest->length] = L'\0'; - return (0); + return (ret_val); } #endif @@ -784,73 +764,6 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as, return (defchar_used?-1:ret); } -#elif defined(HAVE_WCSNRTOMBS) - -/* - * Translates a wide character string into current locale character set - * and appends to the archive_string. Note: returns -1 if conversion - * fails. - */ -int -archive_string_append_from_wcs(struct archive_string *as, - const wchar_t *w, size_t len) -{ - mbstate_t shift_state; - size_t r, ndest, nwc; - char *dest; - const wchar_t *wp, *wpp; - int ret_val = 0; - - wp = w; - nwc = len; - ndest = len * 2; - /* Initialize the shift state. */ - memset(&shift_state, 0, sizeof(shift_state)); - while (nwc > 0) { - /* Allocate buffer for MBS. */ - if (archive_string_ensure(as, as->length + ndest + 1) == NULL) - return (-1); - - dest = as->s + as->length; - wpp = wp; - r = wcsnrtombs(dest, &wp, nwc, - as->buffer_length - as->length -1, - &shift_state); - if (r == (size_t)-1) { - if (errno == EILSEQ) { - /* Retry conversion just for safe WCS. */ - size_t xwc = wp - wpp; - wp = wpp; - r = wcsnrtombs(dest, &wp, xwc, - as->buffer_length - as->length -1, - &shift_state); - if (r == (size_t)-1) - /* This would not happen. */ - return (-1); - as->length += r; - nwc -= wp - wpp; - /* Skip an illegal wide char. */ - as->s[as->length++] = '?'; - wp++; - nwc--; - ret_val = -1; - continue; - } else { - ret_val = -1; - break; - } - } - as->length += r; - if (wp == NULL || (wp - wpp) >= nwc) - break; - /* Get a remaining WCS lenth. */ - nwc -= wp - wpp; - } - /* All wide characters are translated to MBS. */ - as->s[as->length] = '\0'; - return (ret_val); -} - #elif defined(HAVE_WCTOMB) || defined(HAVE_WCRTOMB) /* @@ -896,7 +809,7 @@ archive_string_append_from_wcs(struct archive_string *as, /* Re-allocate buffer for MBS. */ if (archive_string_ensure(as, as->length + len * 2 + 1) == NULL) - __archive_errx(1, "Out of memory"); + return (-1); p = as->s + as->length; end = as->s + as->buffer_length - MB_CUR_MAX -1; }