1/****************************************************************************
2 * Copyright 2019,2020 Thomas E. Dickey                                     *
3 * Copyright 1998-2011,2012 Free Software Foundation, Inc.                  *
4 *                                                                          *
5 * Permission is hereby granted, free of charge, to any person obtaining a  *
6 * copy of this software and associated documentation files (the            *
7 * "Software"), to deal in the Software without restriction, including      *
8 * without limitation the rights to use, copy, modify, merge, publish,      *
9 * distribute, distribute with modifications, sublicense, and/or sell       *
10 * copies of the Software, and to permit persons to whom the Software is    *
11 * furnished to do so, subject to the following conditions:                 *
12 *                                                                          *
13 * The above copyright notice and this permission notice shall be included  *
14 * in all copies or substantial portions of the Software.                   *
15 *                                                                          *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23 *                                                                          *
24 * Except as contained in this notice, the name(s) of the above copyright   *
25 * holders shall not be used in advertising or otherwise to promote the     *
26 * sale, use or other dealings in this Software without prior written       *
27 * authorization.                                                           *
28 ****************************************************************************/
29
30/****************************************************************************
31 *  Author: Juergen Pfeifer                                                 *
32 *     and: Thomas E. Dickey                                                *
33 ****************************************************************************/
34
35/*
36 *	lib_slkset.c
37 *      Set soft label text.
38 */
39#include <curses.priv.h>
40#include <ctype.h>
41
42#if USE_WIDEC_SUPPORT
43#if HAVE_WCTYPE_H
44#include <wctype.h>
45#endif
46#endif
47
48MODULE_ID("$Id: lib_slkset.c,v 1.26 2020/02/02 23:34:34 tom Exp $")
49
50NCURSES_EXPORT(int)
51NCURSES_SP_NAME(slk_set) (NCURSES_SP_DCLx int i, const char *astr, int format)
52{
53    SLK *slk;
54    int offset = 0;
55    int numchrs;
56    int numcols;
57    int limit;
58    const char *str = astr;
59    const char *p;
60
61    T((T_CALLED("slk_set(%p, %d, \"%s\", %d)"), (void *) SP_PARM, i, str, format));
62
63    if (SP_PARM == 0
64	|| (slk = SP_PARM->_slk) == 0
65	|| i < 1
66	|| i > slk->labcnt
67	|| format < 0
68	|| format > 2)
69	returnCode(ERR);
70    if (str == 0)
71	str = "";
72    --i;			/* Adjust numbering of labels */
73
74    limit = MAX_SKEY_LEN(SP_PARM->slk_format);
75    while (isspace(UChar(*str)))
76	str++;			/* skip over leading spaces  */
77    p = str;
78
79#if USE_WIDEC_SUPPORT
80    numcols = 0;
81    while (*p != 0) {
82	mbstate_t state;
83	wchar_t wc;
84	size_t need;
85
86	init_mb(state);
87	need = mbrtowc(0, p, strlen(p), &state);
88	if (need == (size_t) -1)
89	    break;
90	mbrtowc(&wc, p, need, &state);
91	if (!iswprint((wint_t) wc))
92	    break;
93	if (_nc_wacs_width(wc) + numcols > limit)
94	    break;
95	numcols += _nc_wacs_width(wc);
96	p += need;
97    }
98    numchrs = (int) (p - str);
99#else
100    while (isprint(UChar(*p)))
101	p++;			/* The first non-print stops */
102
103    numcols = (int) (p - str);
104    if (numcols > limit)
105	numcols = limit;
106    numchrs = numcols;
107#endif
108
109    FreeIfNeeded(slk->ent[i].ent_text);
110    if ((slk->ent[i].ent_text = strdup(str)) == 0)
111	returnCode(ERR);
112    slk->ent[i].ent_text[numchrs] = '\0';
113
114    if ((slk->ent[i].form_text = (char *) _nc_doalloc(slk->ent[i].form_text,
115						      (size_t) (limit +
116								numchrs + 1))
117	) == 0)
118	returnCode(ERR);
119
120    switch (format) {
121    case 0:			/* left-justified */
122	offset = 0;
123	break;
124    case 1:			/* centered */
125	offset = (limit - numcols) / 2;
126	break;
127    case 2:			/* right-justified */
128	offset = limit - numcols;
129	break;
130    }
131    if (offset <= 0)
132	offset = 0;
133    else
134	memset(slk->ent[i].form_text, ' ', (size_t) offset);
135
136    memcpy(slk->ent[i].form_text + offset,
137	   slk->ent[i].ent_text,
138	   (size_t) numchrs);
139
140    if (offset < limit) {
141	memset(slk->ent[i].form_text + offset + numchrs,
142	       ' ',
143	       (size_t) (limit - (offset + numcols)));
144    }
145
146    slk->ent[i].form_text[numchrs - numcols + limit] = 0;
147    slk->ent[i].dirty = TRUE;
148    returnCode(OK);
149}
150
151#if NCURSES_SP_FUNCS
152NCURSES_EXPORT(int)
153slk_set(int i, const char *astr, int format)
154{
155    return NCURSES_SP_NAME(slk_set) (CURRENT_SCREEN, i, astr, format);
156}
157#endif
158