10e3d5408SPeter Wemm /**************************************************************************** 215589c42SPeter Wemm * Copyright (c) 1999,2000 Free Software Foundation, Inc. * 30e3d5408SPeter Wemm * * 40e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a * 50e3d5408SPeter Wemm * copy of this software and associated documentation files (the * 60e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including * 70e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, * 80e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell * 90e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is * 100e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: * 110e3d5408SPeter Wemm * * 120e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included * 130e3d5408SPeter Wemm * in all copies or substantial portions of the Software. * 140e3d5408SPeter Wemm * * 150e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 160e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 170e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 180e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 190e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 200e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 210e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 220e3d5408SPeter Wemm * * 230e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright * 240e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the * 250e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written * 260e3d5408SPeter Wemm * authorization. * 270e3d5408SPeter Wemm ****************************************************************************/ 280e3d5408SPeter Wemm 290e3d5408SPeter Wemm /**************************************************************************** 300e3d5408SPeter Wemm * Author: Thomas E. Dickey <dickey@clark.net> 1999 * 310e3d5408SPeter Wemm ****************************************************************************/ 320e3d5408SPeter Wemm 330e3d5408SPeter Wemm /* 340e3d5408SPeter Wemm * align_ttype.c -- functions for TERMTYPE 350e3d5408SPeter Wemm * 360e3d5408SPeter Wemm * _nc_align_termtype() 370e3d5408SPeter Wemm * _nc_copy_termtype() 380e3d5408SPeter Wemm * 390e3d5408SPeter Wemm */ 400e3d5408SPeter Wemm 410e3d5408SPeter Wemm #include <curses.priv.h> 420e3d5408SPeter Wemm 430e3d5408SPeter Wemm #include <tic.h> 440e3d5408SPeter Wemm #include <term_entry.h> 450e3d5408SPeter Wemm 4618259542SPeter Wemm MODULE_ID("$Id: alloc_ttype.c,v 1.10 2000/08/12 21:56:24 tom Exp $") 470e3d5408SPeter Wemm 480e3d5408SPeter Wemm #if NCURSES_XNAMES 490e3d5408SPeter Wemm /* 500e3d5408SPeter Wemm * Merge the a/b lists into dst. Both a/b are sorted (see _nc_extend_names()), 510e3d5408SPeter Wemm * so we do not have to worry about order dependencies. 520e3d5408SPeter Wemm */ 5315589c42SPeter Wemm static int 5415589c42SPeter Wemm merge_names(char **dst, char **a, int na, char **b, int nb) 550e3d5408SPeter Wemm { 560e3d5408SPeter Wemm int n = 0; 5718259542SPeter Wemm while (na > 0 && nb > 0) { 580e3d5408SPeter Wemm int cmp = strcmp(*a, *b); 590e3d5408SPeter Wemm if (cmp < 0) { 600e3d5408SPeter Wemm dst[n++] = *a++; 610e3d5408SPeter Wemm na--; 620e3d5408SPeter Wemm } else if (cmp > 0) { 630e3d5408SPeter Wemm dst[n++] = *b++; 640e3d5408SPeter Wemm nb--; 650e3d5408SPeter Wemm } else if (cmp == 0) { 660e3d5408SPeter Wemm dst[n++] = *a; 670e3d5408SPeter Wemm a++, b++; 680e3d5408SPeter Wemm na--, nb--; 690e3d5408SPeter Wemm } 700e3d5408SPeter Wemm } 710e3d5408SPeter Wemm while (na-- > 0) { 720e3d5408SPeter Wemm dst[n++] = *a++; 730e3d5408SPeter Wemm } 740e3d5408SPeter Wemm while (nb-- > 0) { 750e3d5408SPeter Wemm dst[n++] = *b++; 760e3d5408SPeter Wemm } 770e3d5408SPeter Wemm DEBUG(4, ("merge_names -> %d", n)); 780e3d5408SPeter Wemm return n; 790e3d5408SPeter Wemm } 800e3d5408SPeter Wemm 8115589c42SPeter Wemm static bool 8215589c42SPeter Wemm find_name(char **table, int length, char *name) 830e3d5408SPeter Wemm { 840e3d5408SPeter Wemm while (length-- > 0) { 850e3d5408SPeter Wemm if (!strcmp(*table++, name)) { 860e3d5408SPeter Wemm DEBUG(4, ("found name '%s'", name)); 870e3d5408SPeter Wemm return TRUE; 880e3d5408SPeter Wemm } 890e3d5408SPeter Wemm } 900e3d5408SPeter Wemm DEBUG(4, ("did not find name '%s'", name)); 910e3d5408SPeter Wemm return FALSE; 920e3d5408SPeter Wemm } 930e3d5408SPeter Wemm 9415589c42SPeter Wemm static void 9515589c42SPeter Wemm realign_data(TERMTYPE * to, char **ext_Names, int ext_Booleans, int 9615589c42SPeter Wemm ext_Numbers, int ext_Strings) 970e3d5408SPeter Wemm { 980e3d5408SPeter Wemm int n, m, base; 990e3d5408SPeter Wemm int limit = (to->ext_Booleans + to->ext_Numbers + to->ext_Strings); 1000e3d5408SPeter Wemm 1010e3d5408SPeter Wemm if (to->ext_Booleans != ext_Booleans) { 1020e3d5408SPeter Wemm to->num_Booleans += (ext_Booleans - to->ext_Booleans); 1030e3d5408SPeter Wemm to->Booleans = typeRealloc(char, to->num_Booleans, to->Booleans); 1040e3d5408SPeter Wemm for (n = to->ext_Booleans - 1, 1050e3d5408SPeter Wemm m = ext_Booleans - 1, 1060e3d5408SPeter Wemm base = to->num_Booleans - (m + 1); m >= 0; m--) { 1070e3d5408SPeter Wemm if (find_name(to->ext_Names, limit, ext_Names[m])) { 1080e3d5408SPeter Wemm to->Booleans[base + m] = to->Booleans[base + n--]; 1090e3d5408SPeter Wemm } else { 1100e3d5408SPeter Wemm to->Booleans[base + m] = FALSE; 1110e3d5408SPeter Wemm } 1120e3d5408SPeter Wemm } 1130e3d5408SPeter Wemm to->ext_Booleans = ext_Booleans; 1140e3d5408SPeter Wemm } 1150e3d5408SPeter Wemm if (to->ext_Numbers != ext_Numbers) { 1160e3d5408SPeter Wemm to->num_Numbers += (ext_Numbers - to->ext_Numbers); 1170e3d5408SPeter Wemm to->Numbers = typeRealloc(short, to->num_Numbers, to->Numbers); 1180e3d5408SPeter Wemm for (n = to->ext_Numbers - 1, 1190e3d5408SPeter Wemm m = ext_Numbers - 1, 1200e3d5408SPeter Wemm base = to->num_Numbers - (m + 1); m >= 0; m--) { 1210e3d5408SPeter Wemm if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans])) { 1220e3d5408SPeter Wemm to->Numbers[base + m] = to->Numbers[base + n--]; 1230e3d5408SPeter Wemm } else { 1240e3d5408SPeter Wemm to->Numbers[base + m] = ABSENT_NUMERIC; 1250e3d5408SPeter Wemm } 1260e3d5408SPeter Wemm } 1270e3d5408SPeter Wemm to->ext_Numbers = ext_Numbers; 1280e3d5408SPeter Wemm } 1290e3d5408SPeter Wemm if (to->ext_Strings != ext_Strings) { 1300e3d5408SPeter Wemm to->num_Strings += (ext_Strings - to->ext_Strings); 1310e3d5408SPeter Wemm to->Strings = typeRealloc(char *, to->num_Strings, to->Strings); 1320e3d5408SPeter Wemm for (n = to->ext_Strings - 1, 1330e3d5408SPeter Wemm m = ext_Strings - 1, 1340e3d5408SPeter Wemm base = to->num_Strings - (m + 1); m >= 0; m--) { 1350e3d5408SPeter Wemm if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans + ext_Numbers])) { 1360e3d5408SPeter Wemm to->Strings[base + m] = to->Strings[base + n--]; 1370e3d5408SPeter Wemm } else { 1380e3d5408SPeter Wemm to->Strings[base + m] = ABSENT_STRING; 1390e3d5408SPeter Wemm } 1400e3d5408SPeter Wemm } 1410e3d5408SPeter Wemm to->ext_Strings = ext_Strings; 1420e3d5408SPeter Wemm } 1430e3d5408SPeter Wemm } 1440e3d5408SPeter Wemm 1450e3d5408SPeter Wemm /* 1460e3d5408SPeter Wemm * Returns the first index in ext_Names[] for the given token-type 1470e3d5408SPeter Wemm */ 14815589c42SPeter Wemm static int 14915589c42SPeter Wemm _nc_first_ext_name(TERMTYPE * tp, int token_type) 1500e3d5408SPeter Wemm { 1510e3d5408SPeter Wemm int first; 1520e3d5408SPeter Wemm 1530e3d5408SPeter Wemm switch (token_type) { 1540e3d5408SPeter Wemm case BOOLEAN: 1550e3d5408SPeter Wemm first = 0; 1560e3d5408SPeter Wemm break; 1570e3d5408SPeter Wemm case NUMBER: 1580e3d5408SPeter Wemm first = tp->ext_Booleans; 1590e3d5408SPeter Wemm break; 1600e3d5408SPeter Wemm case STRING: 1610e3d5408SPeter Wemm first = tp->ext_Booleans + tp->ext_Numbers; 1620e3d5408SPeter Wemm break; 1630e3d5408SPeter Wemm default: 1640e3d5408SPeter Wemm first = 0; 1650e3d5408SPeter Wemm break; 1660e3d5408SPeter Wemm } 1670e3d5408SPeter Wemm return first; 1680e3d5408SPeter Wemm } 1690e3d5408SPeter Wemm 1700e3d5408SPeter Wemm /* 1710e3d5408SPeter Wemm * Returns the last index in ext_Names[] for the given token-type 1720e3d5408SPeter Wemm */ 17315589c42SPeter Wemm static int 17415589c42SPeter Wemm _nc_last_ext_name(TERMTYPE * tp, int token_type) 1750e3d5408SPeter Wemm { 1760e3d5408SPeter Wemm int last; 1770e3d5408SPeter Wemm 1780e3d5408SPeter Wemm switch (token_type) { 1790e3d5408SPeter Wemm case BOOLEAN: 1800e3d5408SPeter Wemm last = tp->ext_Booleans; 1810e3d5408SPeter Wemm break; 1820e3d5408SPeter Wemm case NUMBER: 1830e3d5408SPeter Wemm last = tp->ext_Booleans + tp->ext_Numbers; 1840e3d5408SPeter Wemm break; 1850e3d5408SPeter Wemm default: 1860e3d5408SPeter Wemm case STRING: 1870e3d5408SPeter Wemm last = NUM_EXT_NAMES(tp); 1880e3d5408SPeter Wemm break; 1890e3d5408SPeter Wemm } 1900e3d5408SPeter Wemm return last; 1910e3d5408SPeter Wemm } 1920e3d5408SPeter Wemm 1930e3d5408SPeter Wemm /* 1940e3d5408SPeter Wemm * Lookup an entry from extended-names, returning -1 if not found 1950e3d5408SPeter Wemm */ 19615589c42SPeter Wemm static int 19715589c42SPeter Wemm _nc_find_ext_name(TERMTYPE * tp, char *name, int token_type) 1980e3d5408SPeter Wemm { 1990e3d5408SPeter Wemm unsigned j; 2000e3d5408SPeter Wemm unsigned first = _nc_first_ext_name(tp, token_type); 2010e3d5408SPeter Wemm unsigned last = _nc_last_ext_name(tp, token_type); 2020e3d5408SPeter Wemm 2030e3d5408SPeter Wemm for (j = first; j < last; j++) { 2040e3d5408SPeter Wemm if (!strcmp(name, tp->ext_Names[j])) { 2050e3d5408SPeter Wemm return j; 2060e3d5408SPeter Wemm } 2070e3d5408SPeter Wemm } 2080e3d5408SPeter Wemm return -1; 2090e3d5408SPeter Wemm } 2100e3d5408SPeter Wemm 2110e3d5408SPeter Wemm /* 2120e3d5408SPeter Wemm * Translate an index into ext_Names[] into the corresponding index into data 2130e3d5408SPeter Wemm * (e.g., Booleans[]). 2140e3d5408SPeter Wemm */ 21515589c42SPeter Wemm static int 21615589c42SPeter Wemm _nc_ext_data_index(TERMTYPE * tp, int n, int token_type) 2170e3d5408SPeter Wemm { 2180e3d5408SPeter Wemm switch (token_type) { 2190e3d5408SPeter Wemm case BOOLEAN: 2200e3d5408SPeter Wemm n += (tp->num_Booleans - tp->ext_Booleans); 2210e3d5408SPeter Wemm break; 2220e3d5408SPeter Wemm case NUMBER: 2230e3d5408SPeter Wemm n += (tp->num_Numbers - tp->ext_Numbers) 2240e3d5408SPeter Wemm - (tp->ext_Booleans); 2250e3d5408SPeter Wemm break; 2260e3d5408SPeter Wemm default: 2270e3d5408SPeter Wemm case STRING: 2280e3d5408SPeter Wemm n += (tp->num_Strings - tp->ext_Strings) 2290e3d5408SPeter Wemm - (tp->ext_Booleans + tp->ext_Numbers); 2300e3d5408SPeter Wemm } 2310e3d5408SPeter Wemm return n; 2320e3d5408SPeter Wemm } 2330e3d5408SPeter Wemm 2340e3d5408SPeter Wemm /* 2350e3d5408SPeter Wemm * Adjust tables to remove (not free) an extended name and its corresponding 2360e3d5408SPeter Wemm * data. 2370e3d5408SPeter Wemm */ 23818259542SPeter Wemm static bool 23915589c42SPeter Wemm _nc_del_ext_name(TERMTYPE * tp, char *name, int token_type) 2400e3d5408SPeter Wemm { 2410e3d5408SPeter Wemm int j; 2420e3d5408SPeter Wemm int first, last; 2430e3d5408SPeter Wemm 2440e3d5408SPeter Wemm if ((first = _nc_find_ext_name(tp, name, token_type)) >= 0) { 2450e3d5408SPeter Wemm last = NUM_EXT_NAMES(tp) - 1; 2460e3d5408SPeter Wemm for (j = first; j < last; j++) { 2470e3d5408SPeter Wemm tp->ext_Names[j] = tp->ext_Names[j + 1]; 2480e3d5408SPeter Wemm } 2490e3d5408SPeter Wemm first = _nc_ext_data_index(tp, first, token_type); 2500e3d5408SPeter Wemm switch (token_type) { 2510e3d5408SPeter Wemm case BOOLEAN: 2520e3d5408SPeter Wemm last = tp->num_Booleans - 1; 2530e3d5408SPeter Wemm for (j = first; j < last; j++) 2540e3d5408SPeter Wemm tp->Booleans[j] = tp->Booleans[j + 1]; 2550e3d5408SPeter Wemm tp->ext_Booleans -= 1; 2560e3d5408SPeter Wemm tp->num_Booleans -= 1; 2570e3d5408SPeter Wemm break; 2580e3d5408SPeter Wemm case NUMBER: 2590e3d5408SPeter Wemm last = tp->num_Numbers - 1; 2600e3d5408SPeter Wemm for (j = first; j < last; j++) 2610e3d5408SPeter Wemm tp->Numbers[j] = tp->Numbers[j + 1]; 2620e3d5408SPeter Wemm tp->ext_Numbers -= 1; 2630e3d5408SPeter Wemm tp->num_Numbers -= 1; 2640e3d5408SPeter Wemm break; 2650e3d5408SPeter Wemm case STRING: 2660e3d5408SPeter Wemm last = tp->num_Strings - 1; 2670e3d5408SPeter Wemm for (j = first; j < last; j++) 2680e3d5408SPeter Wemm tp->Strings[j] = tp->Strings[j + 1]; 2690e3d5408SPeter Wemm tp->ext_Strings -= 1; 2700e3d5408SPeter Wemm tp->num_Strings -= 1; 2710e3d5408SPeter Wemm break; 2720e3d5408SPeter Wemm } 27318259542SPeter Wemm return TRUE; 2740e3d5408SPeter Wemm } 27518259542SPeter Wemm return FALSE; 2760e3d5408SPeter Wemm } 2770e3d5408SPeter Wemm 2780e3d5408SPeter Wemm /* 2790e3d5408SPeter Wemm * Adjust tables to insert an extended name, making room for new data. The 2800e3d5408SPeter Wemm * index into the corresponding data array is returned. 2810e3d5408SPeter Wemm */ 28215589c42SPeter Wemm static int 28315589c42SPeter Wemm _nc_ins_ext_name(TERMTYPE * tp, char *name, int token_type) 2840e3d5408SPeter Wemm { 2850e3d5408SPeter Wemm unsigned first = _nc_first_ext_name(tp, token_type); 2860e3d5408SPeter Wemm unsigned last = _nc_last_ext_name(tp, token_type); 2870e3d5408SPeter Wemm unsigned total = NUM_EXT_NAMES(tp) + 1; 2880e3d5408SPeter Wemm unsigned j, k; 2890e3d5408SPeter Wemm 2900e3d5408SPeter Wemm for (j = first; j < last; j++) { 2910e3d5408SPeter Wemm int cmp = strcmp(name, tp->ext_Names[j]); 2920e3d5408SPeter Wemm if (cmp == 0) 2930e3d5408SPeter Wemm /* already present */ 2940e3d5408SPeter Wemm return _nc_ext_data_index(tp, j, token_type); 2950e3d5408SPeter Wemm if (cmp < 0) { 2960e3d5408SPeter Wemm break; 2970e3d5408SPeter Wemm } 2980e3d5408SPeter Wemm } 2990e3d5408SPeter Wemm 3000e3d5408SPeter Wemm tp->ext_Names = typeRealloc(char *, total, tp->ext_Names); 3010e3d5408SPeter Wemm for (k = total - 1; k > j; k--) 3020e3d5408SPeter Wemm tp->ext_Names[k] = tp->ext_Names[k - 1]; 3030e3d5408SPeter Wemm tp->ext_Names[j] = name; 3040e3d5408SPeter Wemm j = _nc_ext_data_index(tp, j, token_type); 3050e3d5408SPeter Wemm 3060e3d5408SPeter Wemm switch (token_type) { 3070e3d5408SPeter Wemm case BOOLEAN: 3080e3d5408SPeter Wemm tp->ext_Booleans += 1; 3090e3d5408SPeter Wemm tp->num_Booleans += 1; 3100e3d5408SPeter Wemm tp->Booleans = typeRealloc(char, tp->num_Booleans, tp->Booleans); 3110e3d5408SPeter Wemm for (k = tp->num_Booleans - 1; k > j; k--) 3120e3d5408SPeter Wemm tp->Booleans[k] = tp->Booleans[k - 1]; 3130e3d5408SPeter Wemm break; 3140e3d5408SPeter Wemm case NUMBER: 3150e3d5408SPeter Wemm tp->ext_Numbers += 1; 3160e3d5408SPeter Wemm tp->num_Numbers += 1; 3170e3d5408SPeter Wemm tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers); 3180e3d5408SPeter Wemm for (k = tp->num_Numbers - 1; k > j; k--) 3190e3d5408SPeter Wemm tp->Numbers[k] = tp->Numbers[k - 1]; 3200e3d5408SPeter Wemm break; 3210e3d5408SPeter Wemm case STRING: 3220e3d5408SPeter Wemm tp->ext_Strings += 1; 3230e3d5408SPeter Wemm tp->num_Strings += 1; 3240e3d5408SPeter Wemm tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings); 3250e3d5408SPeter Wemm for (k = tp->num_Strings - 1; k > j; k--) 3260e3d5408SPeter Wemm tp->Strings[k] = tp->Strings[k - 1]; 3270e3d5408SPeter Wemm break; 3280e3d5408SPeter Wemm } 3290e3d5408SPeter Wemm return j; 3300e3d5408SPeter Wemm } 3310e3d5408SPeter Wemm 3320e3d5408SPeter Wemm /* 3330e3d5408SPeter Wemm * Look for strings that are marked cancelled, which happen to be the same name 3340e3d5408SPeter Wemm * as a boolean or number. We'll get this as a special case when we get a 3350e3d5408SPeter Wemm * cancellation of a name that is inherited from another entry. 3360e3d5408SPeter Wemm */ 33715589c42SPeter Wemm static void 33815589c42SPeter Wemm adjust_cancels(TERMTYPE * to, TERMTYPE * from) 3390e3d5408SPeter Wemm { 3400e3d5408SPeter Wemm int first = to->ext_Booleans + to->ext_Numbers; 3410e3d5408SPeter Wemm int last = first + to->ext_Strings; 3420e3d5408SPeter Wemm int j, k; 3430e3d5408SPeter Wemm 3440e3d5408SPeter Wemm for (j = first; j < last;) { 3450e3d5408SPeter Wemm char *name = to->ext_Names[j]; 3460e3d5408SPeter Wemm unsigned j_str = to->num_Strings - first - to->ext_Strings; 3470e3d5408SPeter Wemm 3480e3d5408SPeter Wemm if (to->Strings[j + j_str] == CANCELLED_STRING) { 3490e3d5408SPeter Wemm if ((k = _nc_find_ext_name(from, to->ext_Names[j], BOOLEAN)) >= 0) { 35018259542SPeter Wemm if (_nc_del_ext_name(to, name, STRING) 35118259542SPeter Wemm || _nc_del_ext_name(to, name, NUMBER)) { 3520e3d5408SPeter Wemm k = _nc_ins_ext_name(to, name, BOOLEAN); 3530e3d5408SPeter Wemm to->Booleans[k] = FALSE; 35418259542SPeter Wemm } else { 35518259542SPeter Wemm j++; 35618259542SPeter Wemm } 35715589c42SPeter Wemm } else if ((k = _nc_find_ext_name(from, to->ext_Names[j], 35815589c42SPeter Wemm NUMBER)) >= 0) { 35918259542SPeter Wemm if (_nc_del_ext_name(to, name, STRING) 36018259542SPeter Wemm || _nc_del_ext_name(to, name, BOOLEAN)) { 3610e3d5408SPeter Wemm k = _nc_ins_ext_name(to, name, NUMBER); 3620e3d5408SPeter Wemm to->Numbers[k] = CANCELLED_NUMERIC; 36318259542SPeter Wemm } else { 36418259542SPeter Wemm j++; 36518259542SPeter Wemm } 3660e3d5408SPeter Wemm } 3670e3d5408SPeter Wemm } else { 3680e3d5408SPeter Wemm j++; 3690e3d5408SPeter Wemm } 3700e3d5408SPeter Wemm } 3710e3d5408SPeter Wemm } 3720e3d5408SPeter Wemm 37315589c42SPeter Wemm void 37415589c42SPeter Wemm _nc_align_termtype(TERMTYPE * to, TERMTYPE * from) 3750e3d5408SPeter Wemm { 3760e3d5408SPeter Wemm int na = NUM_EXT_NAMES(to); 3770e3d5408SPeter Wemm int nb = NUM_EXT_NAMES(from); 3780e3d5408SPeter Wemm int n; 3790e3d5408SPeter Wemm bool same; 3800e3d5408SPeter Wemm char **ext_Names; 3810e3d5408SPeter Wemm int ext_Booleans, ext_Numbers, ext_Strings; 3820e3d5408SPeter Wemm 38315589c42SPeter Wemm DEBUG(2, ("align_termtype to(%d:%s), from(%d:%s)", na, to->term_names, 38415589c42SPeter Wemm nb, from->term_names)); 3850e3d5408SPeter Wemm 3860e3d5408SPeter Wemm if (na != 0 || nb != 0) { 3870e3d5408SPeter Wemm if ((na == nb) /* check if the arrays are equivalent */ 3880e3d5408SPeter Wemm &&(to->ext_Booleans == from->ext_Booleans) 3890e3d5408SPeter Wemm && (to->ext_Numbers == from->ext_Numbers) 3900e3d5408SPeter Wemm && (to->ext_Strings == from->ext_Strings)) { 3910e3d5408SPeter Wemm for (n = 0, same = TRUE; n < na; n++) { 3920e3d5408SPeter Wemm if (strcmp(to->ext_Names[n], from->ext_Names[n])) { 3930e3d5408SPeter Wemm same = FALSE; 3940e3d5408SPeter Wemm break; 3950e3d5408SPeter Wemm } 3960e3d5408SPeter Wemm } 3970e3d5408SPeter Wemm if (same) 3980e3d5408SPeter Wemm return; 3990e3d5408SPeter Wemm } 4000e3d5408SPeter Wemm /* 4010e3d5408SPeter Wemm * This is where we pay for having a simple extension representation. 4020e3d5408SPeter Wemm * Allocate a new ext_Names array and merge the two ext_Names arrays 4030e3d5408SPeter Wemm * into it, updating to's counts for booleans, etc. Fortunately we do 4040e3d5408SPeter Wemm * this only for the terminfo compiler (tic) and comparer (infocmp). 4050e3d5408SPeter Wemm */ 4060e3d5408SPeter Wemm ext_Names = typeMalloc(char *, na + nb); 4070e3d5408SPeter Wemm 4080e3d5408SPeter Wemm if (to->ext_Strings && (from->ext_Booleans + from->ext_Numbers)) 4090e3d5408SPeter Wemm adjust_cancels(to, from); 4100e3d5408SPeter Wemm 4110e3d5408SPeter Wemm if (from->ext_Strings && (to->ext_Booleans + to->ext_Numbers)) 4120e3d5408SPeter Wemm adjust_cancels(from, to); 4130e3d5408SPeter Wemm 4140e3d5408SPeter Wemm ext_Booleans = merge_names(ext_Names, 4150e3d5408SPeter Wemm to->ext_Names, 4160e3d5408SPeter Wemm to->ext_Booleans, 4170e3d5408SPeter Wemm from->ext_Names, 4180e3d5408SPeter Wemm from->ext_Booleans); 4190e3d5408SPeter Wemm ext_Numbers = merge_names(ext_Names + ext_Booleans, 4200e3d5408SPeter Wemm to->ext_Names 4210e3d5408SPeter Wemm + to->ext_Booleans, 4220e3d5408SPeter Wemm to->ext_Numbers, 4230e3d5408SPeter Wemm from->ext_Names 4240e3d5408SPeter Wemm + from->ext_Booleans, 4250e3d5408SPeter Wemm from->ext_Numbers); 4260e3d5408SPeter Wemm ext_Strings = merge_names(ext_Names + ext_Numbers + ext_Booleans, 4270e3d5408SPeter Wemm to->ext_Names 4280e3d5408SPeter Wemm + to->ext_Booleans 4290e3d5408SPeter Wemm + to->ext_Numbers, 4300e3d5408SPeter Wemm to->ext_Strings, 4310e3d5408SPeter Wemm from->ext_Names 4320e3d5408SPeter Wemm + from->ext_Booleans 4330e3d5408SPeter Wemm + from->ext_Numbers, 4340e3d5408SPeter Wemm from->ext_Strings); 4350e3d5408SPeter Wemm /* 4360e3d5408SPeter Wemm * Now we must reallocate the Booleans, etc., to allow the data to be 4370e3d5408SPeter Wemm * overlaid. 4380e3d5408SPeter Wemm */ 4390e3d5408SPeter Wemm if (na != (ext_Booleans + ext_Numbers + ext_Strings)) { 4400e3d5408SPeter Wemm realign_data(to, ext_Names, ext_Booleans, ext_Numbers, ext_Strings); 44115589c42SPeter Wemm FreeIfNeeded(to->ext_Names); 4420e3d5408SPeter Wemm to->ext_Names = ext_Names; 44315589c42SPeter Wemm DEBUG(2, ("realigned %d extended names for '%s' (to)", 44415589c42SPeter Wemm NUM_EXT_NAMES(to), to->term_names)); 4450e3d5408SPeter Wemm } 4460e3d5408SPeter Wemm if (nb != (ext_Booleans + ext_Numbers + ext_Strings)) { 4470e3d5408SPeter Wemm nb = (ext_Booleans + ext_Numbers + ext_Strings); 4480e3d5408SPeter Wemm realign_data(from, ext_Names, ext_Booleans, ext_Numbers, ext_Strings); 4490e3d5408SPeter Wemm from->ext_Names = typeRealloc(char *, nb, from->ext_Names); 4500e3d5408SPeter Wemm memcpy(from->ext_Names, ext_Names, sizeof(char *) * nb); 45115589c42SPeter Wemm DEBUG(2, ("realigned %d extended names for '%s' (from)", 45215589c42SPeter Wemm NUM_EXT_NAMES(from), from->term_names)); 4530e3d5408SPeter Wemm } 4540e3d5408SPeter Wemm } 4550e3d5408SPeter Wemm } 4560e3d5408SPeter Wemm #endif 4570e3d5408SPeter Wemm 45815589c42SPeter Wemm void 45915589c42SPeter Wemm _nc_copy_termtype(TERMTYPE * dst, TERMTYPE * src) 4600e3d5408SPeter Wemm { 4610e3d5408SPeter Wemm int i; 4620e3d5408SPeter Wemm 4630e3d5408SPeter Wemm *dst = *src; /* ...to copy the sizes and string-tables */ 4640e3d5408SPeter Wemm dst->Booleans = typeMalloc(char, NUM_BOOLEANS(dst)); 4650e3d5408SPeter Wemm dst->Numbers = typeMalloc(short, NUM_NUMBERS(dst)); 4660e3d5408SPeter Wemm dst->Strings = typeMalloc(char *, NUM_STRINGS(dst)); 4670e3d5408SPeter Wemm 4680e3d5408SPeter Wemm /* FIXME: use memcpy for these and similar loops */ 4690e3d5408SPeter Wemm for_each_boolean(i, dst) 4700e3d5408SPeter Wemm dst->Booleans[i] = src->Booleans[i]; 4710e3d5408SPeter Wemm for_each_number(i, dst) 4720e3d5408SPeter Wemm dst->Numbers[i] = src->Numbers[i]; 4730e3d5408SPeter Wemm for_each_string(i, dst) 4740e3d5408SPeter Wemm dst->Strings[i] = src->Strings[i]; 4750e3d5408SPeter Wemm 4760e3d5408SPeter Wemm /* FIXME: we probably should also copy str_table and ext_str_table, 4770e3d5408SPeter Wemm * but tic and infocmp are not written to exploit that (yet). 4780e3d5408SPeter Wemm */ 4790e3d5408SPeter Wemm 4800e3d5408SPeter Wemm #if NCURSES_XNAMES 4810e3d5408SPeter Wemm if ((i = NUM_EXT_NAMES(src)) != 0) { 4820e3d5408SPeter Wemm dst->ext_Names = typeMalloc(char *, i); 4830e3d5408SPeter Wemm memcpy(dst->ext_Names, src->ext_Names, i * sizeof(char *)); 48415589c42SPeter Wemm } else { 48515589c42SPeter Wemm dst->ext_Names = 0; 4860e3d5408SPeter Wemm } 4870e3d5408SPeter Wemm #endif 4880e3d5408SPeter Wemm 4890e3d5408SPeter Wemm } 490