xref: /freebsd/contrib/ncurses/ncurses/widechar/lib_unget_wch.c (revision 21817992b3314c908ab50f0bb88d2ee750b9c4ac)
139f2269fSPeter Wemm /****************************************************************************
2*21817992SBaptiste Daroussin  * Copyright 2020,2023 Thomas E. Dickey                                     *
3e1865124SBaptiste Daroussin  * Copyright 2002-2011,2016 Free Software Foundation, Inc.                  *
439f2269fSPeter Wemm  *                                                                          *
539f2269fSPeter Wemm  * Permission is hereby granted, free of charge, to any person obtaining a  *
639f2269fSPeter Wemm  * copy of this software and associated documentation files (the            *
739f2269fSPeter Wemm  * "Software"), to deal in the Software without restriction, including      *
839f2269fSPeter Wemm  * without limitation the rights to use, copy, modify, merge, publish,      *
939f2269fSPeter Wemm  * distribute, distribute with modifications, sublicense, and/or sell       *
1039f2269fSPeter Wemm  * copies of the Software, and to permit persons to whom the Software is    *
1139f2269fSPeter Wemm  * furnished to do so, subject to the following conditions:                 *
1239f2269fSPeter Wemm  *                                                                          *
1339f2269fSPeter Wemm  * The above copyright notice and this permission notice shall be included  *
1439f2269fSPeter Wemm  * in all copies or substantial portions of the Software.                   *
1539f2269fSPeter Wemm  *                                                                          *
1639f2269fSPeter Wemm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1739f2269fSPeter Wemm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1839f2269fSPeter Wemm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1939f2269fSPeter Wemm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
2039f2269fSPeter Wemm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2139f2269fSPeter Wemm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2239f2269fSPeter Wemm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2339f2269fSPeter Wemm  *                                                                          *
2439f2269fSPeter Wemm  * Except as contained in this notice, the name(s) of the above copyright   *
2539f2269fSPeter Wemm  * holders shall not be used in advertising or otherwise to promote the     *
2639f2269fSPeter Wemm  * sale, use or other dealings in this Software without prior written       *
2739f2269fSPeter Wemm  * authorization.                                                           *
2839f2269fSPeter Wemm  ****************************************************************************/
2939f2269fSPeter Wemm 
3039f2269fSPeter Wemm /****************************************************************************
3139f2269fSPeter Wemm  *  Author: Thomas E. Dickey 2002                                           *
3239f2269fSPeter Wemm  ****************************************************************************/
3339f2269fSPeter Wemm 
3439f2269fSPeter Wemm /*
3539f2269fSPeter Wemm **	lib_unget_wch.c
3639f2269fSPeter Wemm **
3739f2269fSPeter Wemm **	The routine unget_wch().
3839f2269fSPeter Wemm **
3939f2269fSPeter Wemm */
4039f2269fSPeter Wemm 
4139f2269fSPeter Wemm #include <curses.priv.h>
4239f2269fSPeter Wemm 
43*21817992SBaptiste Daroussin MODULE_ID("$Id: lib_unget_wch.c,v 1.18 2023/06/03 12:50:52 tom Exp $")
444a1a9510SRong-En Fan 
454a1a9510SRong-En Fan /*
465ca44d1cSRong-En Fan  * Wrapper for wcrtomb() which obtains the length needed for the given
475ca44d1cSRong-En Fan  * wide-character 'source'.
484a1a9510SRong-En Fan  */
NCURSES_EXPORT(size_t)494a1a9510SRong-En Fan NCURSES_EXPORT(size_t)
504a1a9510SRong-En Fan _nc_wcrtomb(char *target, wchar_t source, mbstate_t * state)
514a1a9510SRong-En Fan {
525ca44d1cSRong-En Fan     int result;
535ca44d1cSRong-En Fan 
544a1a9510SRong-En Fan     if (target == 0) {
554a1a9510SRong-En Fan 	wchar_t temp[2];
564a1a9510SRong-En Fan 	const wchar_t *tempp = temp;
574a1a9510SRong-En Fan 	temp[0] = source;
584a1a9510SRong-En Fan 	temp[1] = 0;
5973f0a83dSXin LI 	result = (int) wcsrtombs(NULL, &tempp, (size_t) 0, state);
605ca44d1cSRong-En Fan     } else {
6106bfebdeSXin LI 	result = (int) wcrtomb(target, source, state);
624a1a9510SRong-En Fan     }
63*21817992SBaptiste Daroussin     if (!isEILSEQ(result) && ((result == 0) || (result > MB_LEN_MAX)))
645ca44d1cSRong-En Fan 	result = 1;
6506bfebdeSXin LI     return (size_t) result;
664a1a9510SRong-En Fan }
6739f2269fSPeter Wemm 
6839f2269fSPeter Wemm NCURSES_EXPORT(int)
NCURSES_SP_NAME(unget_wch)6906bfebdeSXin LI NCURSES_SP_NAME(unget_wch) (NCURSES_SP_DCLx const wchar_t wch)
7039f2269fSPeter Wemm {
7139f2269fSPeter Wemm     int result = OK;
7239f2269fSPeter Wemm     mbstate_t state;
7339f2269fSPeter Wemm     size_t length;
7439f2269fSPeter Wemm 
7506bfebdeSXin LI     T((T_CALLED("unget_wch(%p, %#lx)"), (void *) SP_PARM, (unsigned long) wch));
7639f2269fSPeter Wemm 
774a1a9510SRong-En Fan     init_mb(state);
784a1a9510SRong-En Fan     length = _nc_wcrtomb(0, wch, &state);
7939f2269fSPeter Wemm 
8039f2269fSPeter Wemm     if (length != (size_t) (-1)
8139f2269fSPeter Wemm 	&& length != 0) {
824a1a9510SRong-En Fan 	char *string;
8339f2269fSPeter Wemm 
844a1a9510SRong-En Fan 	if ((string = (char *) malloc(length)) != 0) {
85aae38d10SBaptiste Daroussin 	    int n;
86aae38d10SBaptiste Daroussin 
874a1a9510SRong-En Fan 	    init_mb(state);
8806bfebdeSXin LI 	    /* ignore the result, since we already validated the character */
8906bfebdeSXin LI 	    IGNORE_RC((int) wcrtomb(string, wch, &state));
9039f2269fSPeter Wemm 
9139f2269fSPeter Wemm 	    for (n = (int) (length - 1); n >= 0; --n) {
9206bfebdeSXin LI 		if (NCURSES_SP_NAME(ungetch) (NCURSES_SP_ARGx
9306bfebdeSXin LI 					      UChar(string[n])) !=OK) {
9439f2269fSPeter Wemm 		    result = ERR;
9539f2269fSPeter Wemm 		    break;
9639f2269fSPeter Wemm 		}
9739f2269fSPeter Wemm 	    }
9839f2269fSPeter Wemm 	    free(string);
9939f2269fSPeter Wemm 	} else {
10039f2269fSPeter Wemm 	    result = ERR;
10139f2269fSPeter Wemm 	}
1024a1a9510SRong-En Fan     } else {
1034a1a9510SRong-En Fan 	result = ERR;
1044a1a9510SRong-En Fan     }
10539f2269fSPeter Wemm 
10639f2269fSPeter Wemm     returnCode(result);
10739f2269fSPeter Wemm }
10806bfebdeSXin LI 
10906bfebdeSXin LI #if NCURSES_SP_FUNCS
11006bfebdeSXin LI NCURSES_EXPORT(int)
unget_wch(const wchar_t wch)11106bfebdeSXin LI unget_wch(const wchar_t wch)
11206bfebdeSXin LI {
11306bfebdeSXin LI     return NCURSES_SP_NAME(unget_wch) (CURRENT_SCREEN, wch);
11406bfebdeSXin LI }
11506bfebdeSXin LI #endif
116