10e3d5408SPeter Wemm /****************************************************************************
2*21817992SBaptiste Daroussin * Copyright 2018-2022,2023 Thomas E. Dickey *
3e1865124SBaptiste Daroussin * Copyright 1998-2013,2017 Free Software Foundation, Inc. *
40e3d5408SPeter Wemm * *
50e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a *
60e3d5408SPeter Wemm * copy of this software and associated documentation files (the *
70e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including *
80e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, *
90e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell *
100e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is *
110e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: *
120e3d5408SPeter Wemm * *
130e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included *
140e3d5408SPeter Wemm * in all copies or substantial portions of the Software. *
150e3d5408SPeter Wemm * *
160e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
170e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
180e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
190e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
200e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
210e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
220e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
230e3d5408SPeter Wemm * *
240e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright *
250e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the *
260e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written *
270e3d5408SPeter Wemm * authorization. *
280e3d5408SPeter Wemm ****************************************************************************/
290e3d5408SPeter Wemm
300e3d5408SPeter Wemm /****************************************************************************
310e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
320e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> *
334a1a9510SRong-En Fan * and: Thomas E. Dickey 1996-on *
340e3d5408SPeter Wemm ****************************************************************************/
350e3d5408SPeter Wemm
360e3d5408SPeter Wemm /*
370e3d5408SPeter Wemm * alloc_entry.c -- allocation functions for terminfo entries
380e3d5408SPeter Wemm *
390e3d5408SPeter Wemm * _nc_copy_entry()
400e3d5408SPeter Wemm * _nc_init_entry()
410e3d5408SPeter Wemm * _nc_merge_entry()
420e3d5408SPeter Wemm * _nc_save_str()
430e3d5408SPeter Wemm * _nc_wrap_entry()
440e3d5408SPeter Wemm *
450e3d5408SPeter Wemm */
460e3d5408SPeter Wemm
470e3d5408SPeter Wemm #include <curses.priv.h>
480e3d5408SPeter Wemm
490e3d5408SPeter Wemm #include <tic.h>
500e3d5408SPeter Wemm
51*21817992SBaptiste Daroussin MODULE_ID("$Id: alloc_entry.c,v 1.79 2023/09/15 08:16:12 tom Exp $")
520e3d5408SPeter Wemm
530e3d5408SPeter Wemm #define ABSENT_OFFSET -1
540e3d5408SPeter Wemm #define CANCELLED_OFFSET -2
550e3d5408SPeter Wemm
5639f2269fSPeter Wemm static char *stringbuf; /* buffer for string capabilities */
570e3d5408SPeter Wemm static size_t next_free; /* next free character in stringbuf */
580e3d5408SPeter Wemm
597a69bbfbSPeter Wemm NCURSES_EXPORT(void)
_nc_init_entry(ENTRY * const tp)60aae38d10SBaptiste Daroussin _nc_init_entry(ENTRY * const tp)
610e3d5408SPeter Wemm /* initialize a terminal type data block */
620e3d5408SPeter Wemm {
63*21817992SBaptiste Daroussin DEBUG(2, (T_CALLED("_nc_init_entry(tp=%p)"), (void *) tp));
64*21817992SBaptiste Daroussin
65*21817992SBaptiste Daroussin if (tp == NULL) {
664a1a9510SRong-En Fan #if NO_LEAKS
67*21817992SBaptiste Daroussin if (stringbuf != NULL) {
684a1a9510SRong-En Fan FreeAndNull(stringbuf);
6906bfebdeSXin LI }
704a1a9510SRong-En Fan return;
71*21817992SBaptiste Daroussin #else
72*21817992SBaptiste Daroussin _nc_err_abort("_nc_init_entry called without initialization");
734a1a9510SRong-En Fan #endif
74*21817992SBaptiste Daroussin }
750e3d5408SPeter Wemm
76*21817992SBaptiste Daroussin if (stringbuf == NULL)
77*21817992SBaptiste Daroussin TYPE_CALLOC(char, (size_t) MAX_ENTRY_SIZE, stringbuf);
780e3d5408SPeter Wemm
790e3d5408SPeter Wemm next_free = 0;
8073f0a83dSXin LI
81aae38d10SBaptiste Daroussin _nc_init_termtype(&(tp->tterm));
82*21817992SBaptiste Daroussin
83*21817992SBaptiste Daroussin DEBUG(2, (T_RETURN("")));
840e3d5408SPeter Wemm }
850e3d5408SPeter Wemm
867a69bbfbSPeter Wemm NCURSES_EXPORT(ENTRY *)
_nc_copy_entry(ENTRY * oldp)8715589c42SPeter Wemm _nc_copy_entry(ENTRY * oldp)
880e3d5408SPeter Wemm {
89*21817992SBaptiste Daroussin ENTRY *newp;
900e3d5408SPeter Wemm
91*21817992SBaptiste Daroussin DEBUG(2, (T_CALLED("_nc_copy_entry(oldp=%p)"), (void *) oldp));
92*21817992SBaptiste Daroussin
93*21817992SBaptiste Daroussin newp = typeCalloc(ENTRY, 1);
94*21817992SBaptiste Daroussin if (newp != NULL) {
950e3d5408SPeter Wemm *newp = *oldp;
96aae38d10SBaptiste Daroussin _nc_copy_termtype2(&(newp->tterm), &(oldp->tterm));
970e3d5408SPeter Wemm }
98*21817992SBaptiste Daroussin
99*21817992SBaptiste Daroussin DEBUG(2, (T_RETURN("%p"), (void *) newp));
100*21817992SBaptiste Daroussin return (newp);
1010e3d5408SPeter Wemm }
1020e3d5408SPeter Wemm
1034a1a9510SRong-En Fan /* save a copy of string in the string buffer */
1047a69bbfbSPeter Wemm NCURSES_EXPORT(char *)
_nc_save_str(const char * string)105*21817992SBaptiste Daroussin _nc_save_str(const char *string)
1060e3d5408SPeter Wemm {
1074a1a9510SRong-En Fan char *result = 0;
1080e3d5408SPeter Wemm size_t old_next_free = next_free;
109*21817992SBaptiste Daroussin
110*21817992SBaptiste Daroussin if (stringbuf != NULL) {
111aae38d10SBaptiste Daroussin size_t len;
112aae38d10SBaptiste Daroussin
113aae38d10SBaptiste Daroussin if (!VALID_STRING(string))
114*21817992SBaptiste Daroussin string = "";
115aae38d10SBaptiste Daroussin len = strlen(string) + 1;
1160e3d5408SPeter Wemm
1174a1a9510SRong-En Fan if (len == 1 && next_free != 0) {
1184a1a9510SRong-En Fan /*
1194a1a9510SRong-En Fan * Cheat a little by making an empty string point to the end of the
1204a1a9510SRong-En Fan * previous string.
1214a1a9510SRong-En Fan */
122*21817992SBaptiste Daroussin if (next_free < MAX_ENTRY_SIZE) {
1234a1a9510SRong-En Fan result = (stringbuf + next_free - 1);
1244a1a9510SRong-En Fan }
125*21817992SBaptiste Daroussin } else if (next_free + len < MAX_ENTRY_SIZE) {
126*21817992SBaptiste Daroussin _nc_STRCPY(&stringbuf[next_free], string, MAX_ENTRY_SIZE);
1270e3d5408SPeter Wemm DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
1280e3d5408SPeter Wemm DEBUG(7, ("at location %d", (int) next_free));
1290e3d5408SPeter Wemm next_free += len;
1304a1a9510SRong-En Fan result = (stringbuf + old_next_free);
1314a1a9510SRong-En Fan } else {
13273f0a83dSXin LI _nc_warning("Too much data, some is lost: %s", string);
1330e3d5408SPeter Wemm }
134*21817992SBaptiste Daroussin }
1354a1a9510SRong-En Fan return result;
1360e3d5408SPeter Wemm }
1370e3d5408SPeter Wemm
1387a69bbfbSPeter Wemm NCURSES_EXPORT(void)
_nc_wrap_entry(ENTRY * const ep,bool copy_strings)1397a69bbfbSPeter Wemm _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
1400e3d5408SPeter Wemm /* copy the string parts to allocated storage, preserving pointers to it */
1410e3d5408SPeter Wemm {
1425d08fb1fSRong-En Fan int offsets[MAX_ENTRY_SIZE / sizeof(short)];
1435d08fb1fSRong-En Fan int useoffsets[MAX_USES];
1444a1a9510SRong-En Fan unsigned i, n;
145*21817992SBaptiste Daroussin unsigned nuses;
146*21817992SBaptiste Daroussin TERMTYPE2 *tp;
1470e3d5408SPeter Wemm
148*21817992SBaptiste Daroussin DEBUG(2, (T_CALLED("_nc_wrap_entry(ep=%p, copy_strings=%d)"), (void *)
149*21817992SBaptiste Daroussin ep, copy_strings));
150*21817992SBaptiste Daroussin if (ep == NULL || stringbuf == NULL)
151*21817992SBaptiste Daroussin _nc_err_abort("_nc_wrap_entry called without initialization");
152*21817992SBaptiste Daroussin
153*21817992SBaptiste Daroussin nuses = ep->nuses;
154*21817992SBaptiste Daroussin tp = &(ep->tterm);
1557a69bbfbSPeter Wemm if (copy_strings) {
1567a69bbfbSPeter Wemm next_free = 0; /* clear static storage */
1577a69bbfbSPeter Wemm
1587a69bbfbSPeter Wemm /* copy term_names, Strings, uses */
1597a69bbfbSPeter Wemm tp->term_names = _nc_save_str(tp->term_names);
1607a69bbfbSPeter Wemm for_each_string(i, tp) {
161*21817992SBaptiste Daroussin if (VALID_STRING(tp->Strings[i])) {
1627a69bbfbSPeter Wemm tp->Strings[i] = _nc_save_str(tp->Strings[i]);
1637a69bbfbSPeter Wemm }
1647a69bbfbSPeter Wemm }
1657a69bbfbSPeter Wemm
1664a1a9510SRong-En Fan for (i = 0; i < nuses; i++) {
1677a69bbfbSPeter Wemm if (ep->uses[i].name == 0) {
1687a69bbfbSPeter Wemm ep->uses[i].name = _nc_save_str(ep->uses[i].name);
1697a69bbfbSPeter Wemm }
1707a69bbfbSPeter Wemm }
1717a69bbfbSPeter Wemm
1727a69bbfbSPeter Wemm free(tp->str_table);
1737a69bbfbSPeter Wemm }
1747a69bbfbSPeter Wemm
1755d08fb1fSRong-En Fan assert(tp->term_names >= stringbuf);
1765d08fb1fSRong-En Fan n = (unsigned) (tp->term_names - stringbuf);
1770e3d5408SPeter Wemm for_each_string(i, &(ep->tterm)) {
1785d08fb1fSRong-En Fan if (i < SIZEOF(offsets)) {
1795d08fb1fSRong-En Fan if (tp->Strings[i] == ABSENT_STRING) {
1800e3d5408SPeter Wemm offsets[i] = ABSENT_OFFSET;
1815d08fb1fSRong-En Fan } else if (tp->Strings[i] == CANCELLED_STRING) {
1820e3d5408SPeter Wemm offsets[i] = CANCELLED_OFFSET;
1835d08fb1fSRong-En Fan } else {
18406bfebdeSXin LI offsets[i] = (int) (tp->Strings[i] - stringbuf);
1850e3d5408SPeter Wemm }
1865d08fb1fSRong-En Fan }
1875d08fb1fSRong-En Fan }
1880e3d5408SPeter Wemm
1894a1a9510SRong-En Fan for (i = 0; i < nuses; i++) {
19015589c42SPeter Wemm if (ep->uses[i].name == 0)
1910e3d5408SPeter Wemm useoffsets[i] = ABSENT_OFFSET;
1920e3d5408SPeter Wemm else
19306bfebdeSXin LI useoffsets[i] = (int) (ep->uses[i].name - stringbuf);
1940e3d5408SPeter Wemm }
1950e3d5408SPeter Wemm
19673f0a83dSXin LI TYPE_MALLOC(char, next_free, tp->str_table);
1970e3d5408SPeter Wemm (void) memcpy(tp->str_table, stringbuf, next_free);
1980e3d5408SPeter Wemm
1990e3d5408SPeter Wemm tp->term_names = tp->str_table + n;
2000e3d5408SPeter Wemm for_each_string(i, &(ep->tterm)) {
2015d08fb1fSRong-En Fan if (i < SIZEOF(offsets)) {
2025d08fb1fSRong-En Fan if (offsets[i] == ABSENT_OFFSET) {
2030e3d5408SPeter Wemm tp->Strings[i] = ABSENT_STRING;
2045d08fb1fSRong-En Fan } else if (offsets[i] == CANCELLED_OFFSET) {
2050e3d5408SPeter Wemm tp->Strings[i] = CANCELLED_STRING;
2065d08fb1fSRong-En Fan } else {
2070e3d5408SPeter Wemm tp->Strings[i] = tp->str_table + offsets[i];
2080e3d5408SPeter Wemm }
2095d08fb1fSRong-En Fan }
2105d08fb1fSRong-En Fan }
2110e3d5408SPeter Wemm
2120e3d5408SPeter Wemm #if NCURSES_XNAMES
2137a69bbfbSPeter Wemm if (!copy_strings) {
2145d08fb1fSRong-En Fan if ((n = (unsigned) NUM_EXT_NAMES(tp)) != 0) {
2155d08fb1fSRong-En Fan if (n < SIZEOF(offsets)) {
21606bfebdeSXin LI size_t length = 0;
21773f0a83dSXin LI size_t offset;
2180e3d5408SPeter Wemm for (i = 0; i < n; i++) {
2190e3d5408SPeter Wemm length += strlen(tp->ext_Names[i]) + 1;
22006bfebdeSXin LI offsets[i] = (int) (tp->ext_Names[i] - stringbuf);
2210e3d5408SPeter Wemm }
22273f0a83dSXin LI TYPE_MALLOC(char, length, tp->ext_str_table);
22373f0a83dSXin LI for (i = 0, offset = 0; i < n; i++) {
22473f0a83dSXin LI tp->ext_Names[i] = tp->ext_str_table + offset;
22573f0a83dSXin LI _nc_STRCPY(tp->ext_Names[i],
22673f0a83dSXin LI stringbuf + offsets[i],
22773f0a83dSXin LI length - offset);
22873f0a83dSXin LI offset += strlen(tp->ext_Names[i]) + 1;
2290e3d5408SPeter Wemm }
2300e3d5408SPeter Wemm }
2317a69bbfbSPeter Wemm }
2325d08fb1fSRong-En Fan }
2330e3d5408SPeter Wemm #endif
2340e3d5408SPeter Wemm
2354a1a9510SRong-En Fan for (i = 0; i < nuses; i++) {
236*21817992SBaptiste Daroussin if (useoffsets[i] == ABSENT_OFFSET) {
23715589c42SPeter Wemm ep->uses[i].name = 0;
238*21817992SBaptiste Daroussin } else {
239*21817992SBaptiste Daroussin ep->uses[i].name = strdup(tp->str_table + useoffsets[i]);
2400e3d5408SPeter Wemm }
2410e3d5408SPeter Wemm }
242*21817992SBaptiste Daroussin DEBUG(2, (T_RETURN("")));
243*21817992SBaptiste Daroussin }
2440e3d5408SPeter Wemm
2457a69bbfbSPeter Wemm NCURSES_EXPORT(void)
_nc_merge_entry(ENTRY * const target,ENTRY * const source)246aae38d10SBaptiste Daroussin _nc_merge_entry(ENTRY * const target, ENTRY * const source)
2470e3d5408SPeter Wemm /* merge capabilities from `from' entry into `to' entry */
2480e3d5408SPeter Wemm {
249aae38d10SBaptiste Daroussin TERMTYPE2 *to = &(target->tterm);
250aae38d10SBaptiste Daroussin TERMTYPE2 *from = &(source->tterm);
251aae38d10SBaptiste Daroussin #if NCURSES_XNAMES
252aae38d10SBaptiste Daroussin TERMTYPE2 copy;
253*21817992SBaptiste Daroussin size_t str_size, copy_size;
254*21817992SBaptiste Daroussin char *str_table;
255aae38d10SBaptiste Daroussin #endif
2564a1a9510SRong-En Fan unsigned i;
2570e3d5408SPeter Wemm
258aae38d10SBaptiste Daroussin if (source == 0 || from == 0 || target == 0 || to == 0)
259aae38d10SBaptiste Daroussin return;
260aae38d10SBaptiste Daroussin
2610e3d5408SPeter Wemm #if NCURSES_XNAMES
262aae38d10SBaptiste Daroussin _nc_copy_termtype2(©, from);
263aae38d10SBaptiste Daroussin from = ©
2640e3d5408SPeter Wemm _nc_align_termtype(to, from);
265*21817992SBaptiste Daroussin /*
266*21817992SBaptiste Daroussin * compute the maximum size of the string-table.
267*21817992SBaptiste Daroussin */
268*21817992SBaptiste Daroussin str_size = strlen(to->term_names) + 1;
269*21817992SBaptiste Daroussin for_each_string(i, from) {
270*21817992SBaptiste Daroussin if (VALID_STRING(from->Strings[i]))
271*21817992SBaptiste Daroussin str_size += strlen(from->Strings[i]) + 1;
272*21817992SBaptiste Daroussin }
273*21817992SBaptiste Daroussin for_each_string(i, to) {
274*21817992SBaptiste Daroussin if (VALID_STRING(to->Strings[i]))
275*21817992SBaptiste Daroussin str_size += strlen(to->Strings[i]) + 1;
276*21817992SBaptiste Daroussin }
277*21817992SBaptiste Daroussin /* allocate a string-table large enough for both source/target, and
278*21817992SBaptiste Daroussin * copy all of the strings into that table. In the merge, we will
279*21817992SBaptiste Daroussin * select from the original source/target lists to construct a new
280*21817992SBaptiste Daroussin * target list.
281*21817992SBaptiste Daroussin */
282*21817992SBaptiste Daroussin if (str_size != 0) {
283*21817992SBaptiste Daroussin char *str_copied;
284*21817992SBaptiste Daroussin if ((str_table = malloc(str_size)) == NULL)
285*21817992SBaptiste Daroussin _nc_err_abort(MSG_NO_MEMORY);
286*21817992SBaptiste Daroussin str_copied = str_table;
287*21817992SBaptiste Daroussin _nc_STRCPY(str_copied, to->term_names, str_size);
288*21817992SBaptiste Daroussin to->term_names = str_copied;
289*21817992SBaptiste Daroussin copy_size = strlen(str_copied) + 1;
290*21817992SBaptiste Daroussin str_copied += copy_size;
291*21817992SBaptiste Daroussin str_size -= copy_size;
292*21817992SBaptiste Daroussin for_each_string(i, from) {
293*21817992SBaptiste Daroussin if (VALID_STRING(from->Strings[i])) {
294*21817992SBaptiste Daroussin _nc_STRCPY(str_copied, from->Strings[i], str_size);
295*21817992SBaptiste Daroussin from->Strings[i] = str_copied;
296*21817992SBaptiste Daroussin copy_size = strlen(str_copied) + 1;
297*21817992SBaptiste Daroussin str_copied += copy_size;
298*21817992SBaptiste Daroussin str_size -= copy_size;
299*21817992SBaptiste Daroussin }
300*21817992SBaptiste Daroussin }
301*21817992SBaptiste Daroussin for_each_string(i, to) {
302*21817992SBaptiste Daroussin if (VALID_STRING(to->Strings[i])) {
303*21817992SBaptiste Daroussin _nc_STRCPY(str_copied, to->Strings[i], str_size);
304*21817992SBaptiste Daroussin to->Strings[i] = str_copied;
305*21817992SBaptiste Daroussin copy_size = strlen(str_copied) + 1;
306*21817992SBaptiste Daroussin str_copied += copy_size;
307*21817992SBaptiste Daroussin str_size -= copy_size;
308*21817992SBaptiste Daroussin }
309*21817992SBaptiste Daroussin }
310*21817992SBaptiste Daroussin free(to->str_table);
311*21817992SBaptiste Daroussin to->str_table = str_table;
312*21817992SBaptiste Daroussin free(from->str_table);
313*21817992SBaptiste Daroussin }
314*21817992SBaptiste Daroussin /*
315*21817992SBaptiste Daroussin * Do the same for the extended-strings (i.e., lists of capabilities).
316*21817992SBaptiste Daroussin */
317*21817992SBaptiste Daroussin str_size = 0;
318*21817992SBaptiste Daroussin for (i = 0; i < NUM_EXT_NAMES(from); ++i) {
319*21817992SBaptiste Daroussin if (VALID_STRING(from->ext_Names[i]))
320*21817992SBaptiste Daroussin str_size += strlen(from->ext_Names[i]) + 1;
321*21817992SBaptiste Daroussin }
322*21817992SBaptiste Daroussin for (i = 0; i < NUM_EXT_NAMES(to); ++i) {
323*21817992SBaptiste Daroussin if (VALID_STRING(to->ext_Names[i]))
324*21817992SBaptiste Daroussin str_size += strlen(to->ext_Names[i]) + 1;
325*21817992SBaptiste Daroussin }
326*21817992SBaptiste Daroussin /* allocate a string-table large enough for both source/target, and
327*21817992SBaptiste Daroussin * copy all of the strings into that table. In the merge, we will
328*21817992SBaptiste Daroussin * select from the original source/target lists to construct a new
329*21817992SBaptiste Daroussin * target list.
330*21817992SBaptiste Daroussin */
331*21817992SBaptiste Daroussin if (str_size != 0) {
332*21817992SBaptiste Daroussin char *str_copied;
333*21817992SBaptiste Daroussin if ((str_table = malloc(str_size)) == NULL)
334*21817992SBaptiste Daroussin _nc_err_abort(MSG_NO_MEMORY);
335*21817992SBaptiste Daroussin str_copied = str_table;
336*21817992SBaptiste Daroussin for (i = 0; i < NUM_EXT_NAMES(from); ++i) {
337*21817992SBaptiste Daroussin if (VALID_STRING(from->ext_Names[i])) {
338*21817992SBaptiste Daroussin _nc_STRCPY(str_copied, from->ext_Names[i], str_size);
339*21817992SBaptiste Daroussin from->ext_Names[i] = str_copied;
340*21817992SBaptiste Daroussin copy_size = strlen(str_copied) + 1;
341*21817992SBaptiste Daroussin str_copied += copy_size;
342*21817992SBaptiste Daroussin str_size -= copy_size;
343*21817992SBaptiste Daroussin }
344*21817992SBaptiste Daroussin }
345*21817992SBaptiste Daroussin for (i = 0; i < NUM_EXT_NAMES(to); ++i) {
346*21817992SBaptiste Daroussin if (VALID_STRING(to->ext_Names[i])) {
347*21817992SBaptiste Daroussin _nc_STRCPY(str_copied, to->ext_Names[i], str_size);
348*21817992SBaptiste Daroussin to->ext_Names[i] = str_copied;
349*21817992SBaptiste Daroussin copy_size = strlen(str_copied) + 1;
350*21817992SBaptiste Daroussin str_copied += copy_size;
351*21817992SBaptiste Daroussin str_size -= copy_size;
352*21817992SBaptiste Daroussin }
353*21817992SBaptiste Daroussin }
354*21817992SBaptiste Daroussin free(to->ext_str_table);
355*21817992SBaptiste Daroussin to->ext_str_table = str_table;
356*21817992SBaptiste Daroussin free(from->ext_str_table);
357*21817992SBaptiste Daroussin }
3580e3d5408SPeter Wemm #endif
35915589c42SPeter Wemm for_each_boolean(i, from) {
360*21817992SBaptiste Daroussin if (to->Booleans[i] != (NCURSES_SBOOL) CANCELLED_BOOLEAN) {
3610e3d5408SPeter Wemm int mergebool = from->Booleans[i];
3620e3d5408SPeter Wemm
3630e3d5408SPeter Wemm if (mergebool == CANCELLED_BOOLEAN)
3640e3d5408SPeter Wemm to->Booleans[i] = FALSE;
3650e3d5408SPeter Wemm else if (mergebool == TRUE)
366aae38d10SBaptiste Daroussin to->Booleans[i] = (NCURSES_SBOOL) mergebool;
3670e3d5408SPeter Wemm }
3684a1a9510SRong-En Fan }
3690e3d5408SPeter Wemm
37015589c42SPeter Wemm for_each_number(i, from) {
3714a1a9510SRong-En Fan if (to->Numbers[i] != CANCELLED_NUMERIC) {
372aae38d10SBaptiste Daroussin int mergenum = from->Numbers[i];
3730e3d5408SPeter Wemm
3740e3d5408SPeter Wemm if (mergenum == CANCELLED_NUMERIC)
3750e3d5408SPeter Wemm to->Numbers[i] = ABSENT_NUMERIC;
3760e3d5408SPeter Wemm else if (mergenum != ABSENT_NUMERIC)
377aae38d10SBaptiste Daroussin to->Numbers[i] = (NCURSES_INT2) mergenum;
3780e3d5408SPeter Wemm }
3794a1a9510SRong-En Fan }
3800e3d5408SPeter Wemm
3810e3d5408SPeter Wemm /*
3820e3d5408SPeter Wemm * Note: the copies of strings this makes don't have their own
3830e3d5408SPeter Wemm * storage. This is OK right now, but will be a problem if we
3840e3d5408SPeter Wemm * we ever want to deallocate entries.
3850e3d5408SPeter Wemm */
38615589c42SPeter Wemm for_each_string(i, from) {
3874a1a9510SRong-En Fan if (to->Strings[i] != CANCELLED_STRING) {
3880e3d5408SPeter Wemm char *mergestring = from->Strings[i];
3890e3d5408SPeter Wemm
3900e3d5408SPeter Wemm if (mergestring == CANCELLED_STRING)
3910e3d5408SPeter Wemm to->Strings[i] = ABSENT_STRING;
3920e3d5408SPeter Wemm else if (mergestring != ABSENT_STRING)
3930e3d5408SPeter Wemm to->Strings[i] = mergestring;
3940e3d5408SPeter Wemm }
3950e3d5408SPeter Wemm }
396aae38d10SBaptiste Daroussin #if NCURSES_XNAMES
397*21817992SBaptiste Daroussin /* cleanup */
398aae38d10SBaptiste Daroussin free(copy.Booleans);
399aae38d10SBaptiste Daroussin free(copy.Numbers);
400aae38d10SBaptiste Daroussin free(copy.Strings);
401aae38d10SBaptiste Daroussin free(copy.ext_Names);
402aae38d10SBaptiste Daroussin #endif
4034a1a9510SRong-En Fan }
4044a1a9510SRong-En Fan
4054a1a9510SRong-En Fan #if NO_LEAKS
4064a1a9510SRong-En Fan NCURSES_EXPORT(void)
_nc_alloc_entry_leaks(void)4074a1a9510SRong-En Fan _nc_alloc_entry_leaks(void)
4084a1a9510SRong-En Fan {
409*21817992SBaptiste Daroussin if (stringbuf != NULL) {
4104a1a9510SRong-En Fan FreeAndNull(stringbuf);
4114a1a9510SRong-En Fan }
4124a1a9510SRong-En Fan next_free = 0;
4134a1a9510SRong-En Fan }
4144a1a9510SRong-En Fan #endif
415