1 /* Convert wide character to multibyte character. 2 Copyright (C) 2008-2021 Free Software Foundation, Inc. 3 Written by Bruno Haible <bruno@clisp.org>, 2008. 4 5 This file is free software: you can redistribute it and/or modify 6 it under the terms of the GNU Lesser General Public License as 7 published by the Free Software Foundation; either version 2.1 of the 8 License, or (at your option) any later version. 9 10 This file is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License 16 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 17 18 #include <config.h> 19 20 /* Specification. */ 21 #include <wchar.h> 22 23 #include <errno.h> 24 #include <stdlib.h> 25 26 27 size_t 28 wcrtomb (char *s, wchar_t wc, mbstate_t *ps) /* */ 29 #undef wcrtomb 30 { 31 /* This implementation of wcrtomb supports only stateless encodings. 32 ps must be in the initial state. */ 33 if (ps != NULL && !mbsinit (ps)) 34 { 35 errno = EINVAL; 36 return (size_t)(-1); 37 } 38 39 #if !HAVE_WCRTOMB /* IRIX 6.5 */ \ 40 || WCRTOMB_RETVAL_BUG /* Solaris 11.3, MSVC */ \ 41 || WCRTOMB_C_LOCALE_BUG /* Android */ 42 if (s == NULL) 43 /* We know the NUL wide character corresponds to the NUL character. */ 44 return 1; 45 else 46 #endif 47 { 48 #if HAVE_WCRTOMB 49 # if WCRTOMB_C_LOCALE_BUG /* Android */ 50 /* Implement consistently with mbrtowc(): through a 1:1 correspondence, 51 as in ISO-8859-1. */ 52 if (wc >= 0 && wc <= 0xff) 53 { 54 *s = (unsigned char) wc; 55 return 1; 56 } 57 else 58 { 59 errno = EILSEQ; 60 return (size_t)(-1); 61 } 62 # else 63 return wcrtomb (s, wc, ps); 64 # endif 65 #else /* IRIX 6.5 */ 66 /* Fallback for platforms that don't have wcrtomb(). 67 Implement on top of wctomb(). 68 This code is not multithread-safe. */ 69 int ret = wctomb (s, wc); 70 71 if (ret >= 0) 72 return ret; 73 else 74 { 75 errno = EILSEQ; 76 return (size_t)(-1); 77 } 78 #endif 79 } 80 }