Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 1 | /**************************************************************************** |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 2 | * Copyright 2018-2022,2023 Thomas E. Dickey * |
| 3 | * Copyright 1998-2013,2017 Free Software Foundation, Inc. * |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * |
| 32 | * and: Eric S. Raymond <esr@snark.thyrsus.com> * |
| 33 | * and: Thomas E. Dickey 1996-on * |
| 34 | ****************************************************************************/ |
| 35 | |
| 36 | /* |
| 37 | * alloc_entry.c -- allocation functions for terminfo entries |
| 38 | * |
| 39 | * _nc_copy_entry() |
| 40 | * _nc_init_entry() |
| 41 | * _nc_merge_entry() |
| 42 | * _nc_save_str() |
| 43 | * _nc_wrap_entry() |
| 44 | * |
| 45 | */ |
| 46 | |
| 47 | #include <curses.priv.h> |
| 48 | |
| 49 | #include <tic.h> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 50 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 51 | MODULE_ID("$Id: alloc_entry.c,v 1.79 2023/09/15 08:16:12 tom Exp $") |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 52 | |
| 53 | #define ABSENT_OFFSET -1 |
| 54 | #define CANCELLED_OFFSET -2 |
| 55 | |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 56 | static char *stringbuf; /* buffer for string capabilities */ |
| 57 | static size_t next_free; /* next free character in stringbuf */ |
| 58 | |
| 59 | NCURSES_EXPORT(void) |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 60 | _nc_init_entry(ENTRY * const tp) |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 61 | /* initialize a terminal type data block */ |
| 62 | { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 63 | DEBUG(2, (T_CALLED("_nc_init_entry(tp=%p)"), (void *) tp)); |
| 64 | |
| 65 | if (tp == NULL) { |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 66 | #if NO_LEAKS |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 67 | if (stringbuf != NULL) { |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 68 | FreeAndNull(stringbuf); |
| 69 | } |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 70 | return; |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 71 | #else |
| 72 | _nc_err_abort("_nc_init_entry called without initialization"); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 73 | #endif |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 74 | } |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 75 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 76 | if (stringbuf == NULL) |
| 77 | TYPE_CALLOC(char, (size_t) MAX_ENTRY_SIZE, stringbuf); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 78 | |
| 79 | next_free = 0; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 80 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 81 | _nc_init_termtype(&(tp->tterm)); |
| 82 | |
| 83 | DEBUG(2, (T_RETURN(""))); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | NCURSES_EXPORT(ENTRY *) |
| 87 | _nc_copy_entry(ENTRY * oldp) |
| 88 | { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 89 | ENTRY *newp; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 90 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 91 | DEBUG(2, (T_CALLED("_nc_copy_entry(oldp=%p)"), (void *) oldp)); |
| 92 | |
| 93 | newp = typeCalloc(ENTRY, 1); |
| 94 | if (newp != NULL) { |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 95 | *newp = *oldp; |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 96 | _nc_copy_termtype2(&(newp->tterm), &(oldp->tterm)); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 97 | } |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 98 | |
| 99 | DEBUG(2, (T_RETURN("%p"), (void *) newp)); |
| 100 | return (newp); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | /* save a copy of string in the string buffer */ |
| 104 | NCURSES_EXPORT(char *) |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 105 | _nc_save_str(const char *string) |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 106 | { |
| 107 | char *result = 0; |
| 108 | size_t old_next_free = next_free; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 109 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 110 | if (stringbuf != NULL) { |
| 111 | size_t len; |
| 112 | |
| 113 | if (!VALID_STRING(string)) |
| 114 | string = ""; |
| 115 | len = strlen(string) + 1; |
| 116 | |
| 117 | if (len == 1 && next_free != 0) { |
| 118 | /* |
| 119 | * Cheat a little by making an empty string point to the end of the |
| 120 | * previous string. |
| 121 | */ |
| 122 | if (next_free < MAX_ENTRY_SIZE) { |
| 123 | result = (stringbuf + next_free - 1); |
| 124 | } |
| 125 | } else if (next_free + len < MAX_ENTRY_SIZE) { |
| 126 | _nc_STRCPY(&stringbuf[next_free], string, MAX_ENTRY_SIZE); |
| 127 | DEBUG(7, ("Saved string %s", _nc_visbuf(string))); |
| 128 | DEBUG(7, ("at location %d", (int) next_free)); |
| 129 | next_free += len; |
| 130 | result = (stringbuf + old_next_free); |
| 131 | } else { |
| 132 | _nc_warning("Too much data, some is lost: %s", string); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 133 | } |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 134 | } |
| 135 | return result; |
| 136 | } |
| 137 | |
| 138 | NCURSES_EXPORT(void) |
| 139 | _nc_wrap_entry(ENTRY * const ep, bool copy_strings) |
| 140 | /* copy the string parts to allocated storage, preserving pointers to it */ |
| 141 | { |
| 142 | int offsets[MAX_ENTRY_SIZE / sizeof(short)]; |
| 143 | int useoffsets[MAX_USES]; |
| 144 | unsigned i, n; |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 145 | unsigned nuses; |
| 146 | TERMTYPE2 *tp; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 147 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 148 | DEBUG(2, (T_CALLED("_nc_wrap_entry(ep=%p, copy_strings=%d)"), (void *) |
| 149 | ep, copy_strings)); |
| 150 | if (ep == NULL || stringbuf == NULL) |
| 151 | _nc_err_abort("_nc_wrap_entry called without initialization"); |
| 152 | |
| 153 | nuses = ep->nuses; |
| 154 | tp = &(ep->tterm); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 155 | if (copy_strings) { |
| 156 | next_free = 0; /* clear static storage */ |
| 157 | |
| 158 | /* copy term_names, Strings, uses */ |
| 159 | tp->term_names = _nc_save_str(tp->term_names); |
| 160 | for_each_string(i, tp) { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 161 | if (VALID_STRING(tp->Strings[i])) { |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 162 | tp->Strings[i] = _nc_save_str(tp->Strings[i]); |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | for (i = 0; i < nuses; i++) { |
| 167 | if (ep->uses[i].name == 0) { |
| 168 | ep->uses[i].name = _nc_save_str(ep->uses[i].name); |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | free(tp->str_table); |
| 173 | } |
| 174 | |
| 175 | assert(tp->term_names >= stringbuf); |
| 176 | n = (unsigned) (tp->term_names - stringbuf); |
| 177 | for_each_string(i, &(ep->tterm)) { |
| 178 | if (i < SIZEOF(offsets)) { |
| 179 | if (tp->Strings[i] == ABSENT_STRING) { |
| 180 | offsets[i] = ABSENT_OFFSET; |
| 181 | } else if (tp->Strings[i] == CANCELLED_STRING) { |
| 182 | offsets[i] = CANCELLED_OFFSET; |
| 183 | } else { |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 184 | offsets[i] = (int) (tp->Strings[i] - stringbuf); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | for (i = 0; i < nuses; i++) { |
| 190 | if (ep->uses[i].name == 0) |
| 191 | useoffsets[i] = ABSENT_OFFSET; |
| 192 | else |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 193 | useoffsets[i] = (int) (ep->uses[i].name - stringbuf); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 194 | } |
| 195 | |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 196 | TYPE_MALLOC(char, next_free, tp->str_table); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 197 | (void) memcpy(tp->str_table, stringbuf, next_free); |
| 198 | |
| 199 | tp->term_names = tp->str_table + n; |
| 200 | for_each_string(i, &(ep->tterm)) { |
| 201 | if (i < SIZEOF(offsets)) { |
| 202 | if (offsets[i] == ABSENT_OFFSET) { |
| 203 | tp->Strings[i] = ABSENT_STRING; |
| 204 | } else if (offsets[i] == CANCELLED_OFFSET) { |
| 205 | tp->Strings[i] = CANCELLED_STRING; |
| 206 | } else { |
| 207 | tp->Strings[i] = tp->str_table + offsets[i]; |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | #if NCURSES_XNAMES |
| 213 | if (!copy_strings) { |
| 214 | if ((n = (unsigned) NUM_EXT_NAMES(tp)) != 0) { |
| 215 | if (n < SIZEOF(offsets)) { |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 216 | size_t length = 0; |
| 217 | size_t offset; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 218 | for (i = 0; i < n; i++) { |
| 219 | length += strlen(tp->ext_Names[i]) + 1; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 220 | offsets[i] = (int) (tp->ext_Names[i] - stringbuf); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 221 | } |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 222 | TYPE_MALLOC(char, length, tp->ext_str_table); |
| 223 | for (i = 0, offset = 0; i < n; i++) { |
| 224 | tp->ext_Names[i] = tp->ext_str_table + offset; |
| 225 | _nc_STRCPY(tp->ext_Names[i], |
| 226 | stringbuf + offsets[i], |
| 227 | length - offset); |
| 228 | offset += strlen(tp->ext_Names[i]) + 1; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 229 | } |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | #endif |
| 234 | |
| 235 | for (i = 0; i < nuses; i++) { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 236 | if (useoffsets[i] == ABSENT_OFFSET) { |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 237 | ep->uses[i].name = 0; |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 238 | } else { |
| 239 | ep->uses[i].name = strdup(tp->str_table + useoffsets[i]); |
| 240 | } |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 241 | } |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 242 | DEBUG(2, (T_RETURN(""))); |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 243 | } |
| 244 | |
| 245 | NCURSES_EXPORT(void) |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 246 | _nc_merge_entry(ENTRY * const target, ENTRY * const source) |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 247 | /* merge capabilities from `from' entry into `to' entry */ |
| 248 | { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 249 | TERMTYPE2 *to = &(target->tterm); |
| 250 | TERMTYPE2 *from = &(source->tterm); |
| 251 | #if NCURSES_XNAMES |
| 252 | TERMTYPE2 copy; |
| 253 | size_t str_size, copy_size; |
| 254 | char *str_table; |
| 255 | #endif |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 256 | unsigned i; |
| 257 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 258 | if (source == 0 || from == 0 || target == 0 || to == 0) |
| 259 | return; |
| 260 | |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 261 | #if NCURSES_XNAMES |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 262 | _nc_copy_termtype2(©, from); |
| 263 | from = © |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 264 | _nc_align_termtype(to, from); |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 265 | /* |
| 266 | * compute the maximum size of the string-table. |
| 267 | */ |
| 268 | str_size = strlen(to->term_names) + 1; |
| 269 | for_each_string(i, from) { |
| 270 | if (VALID_STRING(from->Strings[i])) |
| 271 | str_size += strlen(from->Strings[i]) + 1; |
| 272 | } |
| 273 | for_each_string(i, to) { |
| 274 | if (VALID_STRING(to->Strings[i])) |
| 275 | str_size += strlen(to->Strings[i]) + 1; |
| 276 | } |
| 277 | /* allocate a string-table large enough for both source/target, and |
| 278 | * copy all of the strings into that table. In the merge, we will |
| 279 | * select from the original source/target lists to construct a new |
| 280 | * target list. |
| 281 | */ |
| 282 | if (str_size != 0) { |
| 283 | char *str_copied; |
| 284 | if ((str_table = malloc(str_size)) == NULL) |
| 285 | _nc_err_abort(MSG_NO_MEMORY); |
| 286 | str_copied = str_table; |
| 287 | _nc_STRCPY(str_copied, to->term_names, str_size); |
| 288 | to->term_names = str_copied; |
| 289 | copy_size = strlen(str_copied) + 1; |
| 290 | str_copied += copy_size; |
| 291 | str_size -= copy_size; |
| 292 | for_each_string(i, from) { |
| 293 | if (VALID_STRING(from->Strings[i])) { |
| 294 | _nc_STRCPY(str_copied, from->Strings[i], str_size); |
| 295 | from->Strings[i] = str_copied; |
| 296 | copy_size = strlen(str_copied) + 1; |
| 297 | str_copied += copy_size; |
| 298 | str_size -= copy_size; |
| 299 | } |
| 300 | } |
| 301 | for_each_string(i, to) { |
| 302 | if (VALID_STRING(to->Strings[i])) { |
| 303 | _nc_STRCPY(str_copied, to->Strings[i], str_size); |
| 304 | to->Strings[i] = str_copied; |
| 305 | copy_size = strlen(str_copied) + 1; |
| 306 | str_copied += copy_size; |
| 307 | str_size -= copy_size; |
| 308 | } |
| 309 | } |
| 310 | free(to->str_table); |
| 311 | to->str_table = str_table; |
| 312 | free(from->str_table); |
| 313 | } |
| 314 | /* |
| 315 | * Do the same for the extended-strings (i.e., lists of capabilities). |
| 316 | */ |
| 317 | str_size = 0; |
| 318 | for (i = 0; i < NUM_EXT_NAMES(from); ++i) { |
| 319 | if (VALID_STRING(from->ext_Names[i])) |
| 320 | str_size += strlen(from->ext_Names[i]) + 1; |
| 321 | } |
| 322 | for (i = 0; i < NUM_EXT_NAMES(to); ++i) { |
| 323 | if (VALID_STRING(to->ext_Names[i])) |
| 324 | str_size += strlen(to->ext_Names[i]) + 1; |
| 325 | } |
| 326 | /* allocate a string-table large enough for both source/target, and |
| 327 | * copy all of the strings into that table. In the merge, we will |
| 328 | * select from the original source/target lists to construct a new |
| 329 | * target list. |
| 330 | */ |
| 331 | if (str_size != 0) { |
| 332 | char *str_copied; |
| 333 | if ((str_table = malloc(str_size)) == NULL) |
| 334 | _nc_err_abort(MSG_NO_MEMORY); |
| 335 | str_copied = str_table; |
| 336 | for (i = 0; i < NUM_EXT_NAMES(from); ++i) { |
| 337 | if (VALID_STRING(from->ext_Names[i])) { |
| 338 | _nc_STRCPY(str_copied, from->ext_Names[i], str_size); |
| 339 | from->ext_Names[i] = str_copied; |
| 340 | copy_size = strlen(str_copied) + 1; |
| 341 | str_copied += copy_size; |
| 342 | str_size -= copy_size; |
| 343 | } |
| 344 | } |
| 345 | for (i = 0; i < NUM_EXT_NAMES(to); ++i) { |
| 346 | if (VALID_STRING(to->ext_Names[i])) { |
| 347 | _nc_STRCPY(str_copied, to->ext_Names[i], str_size); |
| 348 | to->ext_Names[i] = str_copied; |
| 349 | copy_size = strlen(str_copied) + 1; |
| 350 | str_copied += copy_size; |
| 351 | str_size -= copy_size; |
| 352 | } |
| 353 | } |
| 354 | free(to->ext_str_table); |
| 355 | to->ext_str_table = str_table; |
| 356 | free(from->ext_str_table); |
| 357 | } |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 358 | #endif |
| 359 | for_each_boolean(i, from) { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 360 | if (to->Booleans[i] != (NCURSES_SBOOL) CANCELLED_BOOLEAN) { |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 361 | int mergebool = from->Booleans[i]; |
| 362 | |
| 363 | if (mergebool == CANCELLED_BOOLEAN) |
| 364 | to->Booleans[i] = FALSE; |
| 365 | else if (mergebool == TRUE) |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 366 | to->Booleans[i] = (NCURSES_SBOOL) mergebool; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 367 | } |
| 368 | } |
| 369 | |
| 370 | for_each_number(i, from) { |
| 371 | if (to->Numbers[i] != CANCELLED_NUMERIC) { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 372 | int mergenum = from->Numbers[i]; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 373 | |
| 374 | if (mergenum == CANCELLED_NUMERIC) |
| 375 | to->Numbers[i] = ABSENT_NUMERIC; |
| 376 | else if (mergenum != ABSENT_NUMERIC) |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 377 | to->Numbers[i] = (NCURSES_INT2) mergenum; |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 378 | } |
| 379 | } |
| 380 | |
| 381 | /* |
| 382 | * Note: the copies of strings this makes don't have their own |
| 383 | * storage. This is OK right now, but will be a problem if we |
| 384 | * we ever want to deallocate entries. |
| 385 | */ |
| 386 | for_each_string(i, from) { |
| 387 | if (to->Strings[i] != CANCELLED_STRING) { |
| 388 | char *mergestring = from->Strings[i]; |
| 389 | |
| 390 | if (mergestring == CANCELLED_STRING) |
| 391 | to->Strings[i] = ABSENT_STRING; |
| 392 | else if (mergestring != ABSENT_STRING) |
| 393 | to->Strings[i] = mergestring; |
| 394 | } |
| 395 | } |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 396 | #if NCURSES_XNAMES |
| 397 | /* cleanup */ |
| 398 | free(copy.Booleans); |
| 399 | free(copy.Numbers); |
| 400 | free(copy.Strings); |
| 401 | free(copy.ext_Names); |
| 402 | #endif |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 403 | } |
| 404 | |
| 405 | #if NO_LEAKS |
| 406 | NCURSES_EXPORT(void) |
| 407 | _nc_alloc_entry_leaks(void) |
| 408 | { |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 409 | if (stringbuf != NULL) { |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 410 | FreeAndNull(stringbuf); |
| 411 | } |
| 412 | next_free = 0; |
| 413 | } |
| 414 | #endif |