ncurses 6.1 - patch 20190810
[ncurses.git] / ncurses / base / lib_insnstr.c
1 /****************************************************************************
2  * Copyright (c) 2004-2016,2018 Free Software Foundation, Inc.              *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28
29 /****************************************************************************
30  *  Author: Thomas E. Dickey                                                *
31  ****************************************************************************/
32
33 /*
34 **      lib_insnstr.c
35 **
36 **      The routine winsnstr().
37 **
38 */
39
40 #include <curses.priv.h>
41 #include <ctype.h>
42
43 MODULE_ID("$Id: lib_insnstr.c,v 1.6 2018/03/10 20:13:59 Gyorgy.Jeney Exp $")
44
45 NCURSES_EXPORT(int)
46 winsnstr(WINDOW *win, const char *s, int n)
47 {
48     int code = ERR;
49     const unsigned char *str = (const unsigned char *) s;
50
51     T((T_CALLED("winsnstr(%p,%s,%d)"), (void *) win, _nc_visbufn(s, n), n));
52
53     if (win != 0 && str != 0) {
54         SCREEN *sp = _nc_screen_of(win);
55 #if USE_WIDEC_SUPPORT
56         /*
57          * If the output contains "wide" (multibyte) characters, we will not
58          * really know the width of a character until we get the last byte
59          * of the character.  Since the preceding byte(s) may use more columns
60          * on the screen than the final character, it is best to route the
61          * call to the wins_nwstr() function.
62          */
63         if (sp->_screen_unicode) {
64             size_t nn = (n > 0) ? (size_t) n : strlen(s);
65             wchar_t *buffer = typeMalloc(wchar_t, nn + 1);
66             if (buffer != 0) {
67                 mbstate_t state;
68                 size_t n3;
69                 init_mb(state);
70                 n3 = mbstowcs(buffer, s, nn);
71                 if (n3 != (size_t) (-1)) {
72                     code = wins_nwstr(win, buffer, (int) n3);
73                 }
74                 free(buffer);
75             }
76         }
77         if (code == ERR)
78 #endif
79         {
80             NCURSES_SIZE_T oy = win->_cury;
81             NCURSES_SIZE_T ox = win->_curx;
82             const unsigned char *cp;
83
84             for (cp = str; (n <= 0 || (cp - str) < n) && *cp; cp++) {
85                 _nc_insert_ch(sp, win, (chtype) UChar(*cp));
86             }
87             win->_curx = ox;
88             win->_cury = oy;
89             _nc_synchook(win);
90             code = OK;
91         }
92     }
93     returnCode(code);
94 }