1 /**************************************************************************** 2 * Copyright (c) 1998,2000 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 31 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 32 ****************************************************************************/ 33 34 /* 35 * alloc_entry.c -- allocation functions for terminfo entries 36 * 37 * _nc_copy_entry() 38 * _nc_init_entry() 39 * _nc_merge_entry() 40 * _nc_save_str() 41 * _nc_wrap_entry() 42 * 43 */ 44 45 #include <curses.priv.h> 46 47 #include <tic.h> 48 #include <term_entry.h> 49 50 MODULE_ID("$Id: alloc_entry.c,v 1.32 2000/03/12 00:16:31 tom Exp $") 51 52 #define ABSENT_OFFSET -1 53 #define CANCELLED_OFFSET -2 54 55 #define MAX_STRTAB 4096 /* documented maximum entry size */ 56 57 static char stringbuf[MAX_STRTAB]; /* buffer for string capabilities */ 58 static size_t next_free; /* next free character in stringbuf */ 59 60 void 61 _nc_init_entry(TERMTYPE * const tp) 62 /* initialize a terminal type data block */ 63 { 64 int i; 65 66 #if NCURSES_XNAMES 67 tp->num_Booleans = BOOLCOUNT; 68 tp->num_Numbers = NUMCOUNT; 69 tp->num_Strings = STRCOUNT; 70 tp->ext_Booleans = 0; 71 tp->ext_Numbers = 0; 72 tp->ext_Strings = 0; 73 #endif 74 if (tp->Booleans == 0) 75 tp->Booleans = typeMalloc(char, BOOLCOUNT); 76 if (tp->Numbers == 0) 77 tp->Numbers = typeMalloc(short, NUMCOUNT); 78 if (tp->Strings == 0) 79 tp->Strings = typeMalloc(char *, STRCOUNT); 80 81 for_each_boolean(i, tp) 82 tp->Booleans[i] = FALSE; 83 84 for_each_number(i, tp) 85 tp->Numbers[i] = ABSENT_NUMERIC; 86 87 for_each_string(i, tp) 88 tp->Strings[i] = ABSENT_STRING; 89 90 next_free = 0; 91 } 92 93 ENTRY * 94 _nc_copy_entry(ENTRY * oldp) 95 { 96 ENTRY *newp = typeCalloc(ENTRY, 1); 97 98 if (newp != 0) { 99 *newp = *oldp; 100 _nc_copy_termtype(&(newp->tterm), &(oldp->tterm)); 101 } 102 return newp; 103 } 104 105 char * 106 _nc_save_str(const char *const string) 107 /* save a copy of string in the string buffer */ 108 { 109 size_t old_next_free = next_free; 110 size_t len = strlen(string) + 1; 111 112 if (next_free + len < MAX_STRTAB) { 113 strcpy(&stringbuf[next_free], string); 114 DEBUG(7, ("Saved string %s", _nc_visbuf(string))); 115 DEBUG(7, ("at location %d", (int) next_free)); 116 next_free += len; 117 } 118 return (stringbuf + old_next_free); 119 } 120 121 void 122 _nc_wrap_entry(ENTRY * const ep) 123 /* copy the string parts to allocated storage, preserving pointers to it */ 124 { 125 int offsets[MAX_ENTRY_SIZE / 2], useoffsets[MAX_USES]; 126 int i, n; 127 TERMTYPE *tp = &(ep->tterm); 128 129 n = tp->term_names - stringbuf; 130 for_each_string(i, &(ep->tterm)) { 131 if (tp->Strings[i] == ABSENT_STRING) 132 offsets[i] = ABSENT_OFFSET; 133 else if (tp->Strings[i] == CANCELLED_STRING) 134 offsets[i] = CANCELLED_OFFSET; 135 else 136 offsets[i] = tp->Strings[i] - stringbuf; 137 } 138 139 for (i = 0; i < ep->nuses; i++) { 140 if (ep->uses[i].name == 0) 141 useoffsets[i] = ABSENT_OFFSET; 142 else 143 useoffsets[i] = ep->uses[i].name - stringbuf; 144 } 145 146 if ((tp->str_table = typeMalloc(char, next_free)) == (char *) 0) 147 _nc_err_abort("Out of memory"); 148 (void) memcpy(tp->str_table, stringbuf, next_free); 149 150 tp->term_names = tp->str_table + n; 151 for_each_string(i, &(ep->tterm)) { 152 if (offsets[i] == ABSENT_OFFSET) 153 tp->Strings[i] = ABSENT_STRING; 154 else if (offsets[i] == CANCELLED_OFFSET) 155 tp->Strings[i] = CANCELLED_STRING; 156 else 157 tp->Strings[i] = tp->str_table + offsets[i]; 158 } 159 160 #if NCURSES_XNAMES 161 if ((n = NUM_EXT_NAMES(tp)) != 0) { 162 unsigned length = 0; 163 for (i = 0; i < n; i++) { 164 length += strlen(tp->ext_Names[i]) + 1; 165 offsets[i] = tp->ext_Names[i] - stringbuf; 166 } 167 if ((tp->ext_str_table = typeMalloc(char, length)) == 0) 168 _nc_err_abort("Out of memory"); 169 for (i = 0, length = 0; i < n; i++) { 170 tp->ext_Names[i] = tp->ext_str_table + length; 171 strcpy(tp->ext_Names[i], stringbuf + offsets[i]); 172 length += strlen(tp->ext_Names[i]) + 1; 173 } 174 } 175 #endif 176 177 for (i = 0; i < ep->nuses; i++) { 178 if (useoffsets[i] == ABSENT_OFFSET) 179 ep->uses[i].name = 0; 180 else 181 ep->uses[i].name = (tp->str_table + useoffsets[i]); 182 } 183 } 184 185 void 186 _nc_merge_entry(TERMTYPE * const to, TERMTYPE * const from) 187 /* merge capabilities from `from' entry into `to' entry */ 188 { 189 int i; 190 191 #if NCURSES_XNAMES 192 _nc_align_termtype(to, from); 193 #endif 194 for_each_boolean(i, from) { 195 int mergebool = from->Booleans[i]; 196 197 if (mergebool == CANCELLED_BOOLEAN) 198 to->Booleans[i] = FALSE; 199 else if (mergebool == TRUE) 200 to->Booleans[i] = mergebool; 201 } 202 203 for_each_number(i, from) { 204 int mergenum = from->Numbers[i]; 205 206 if (mergenum == CANCELLED_NUMERIC) 207 to->Numbers[i] = ABSENT_NUMERIC; 208 else if (mergenum != ABSENT_NUMERIC) 209 to->Numbers[i] = mergenum; 210 } 211 212 /* 213 * Note: the copies of strings this makes don't have their own 214 * storage. This is OK right now, but will be a problem if we 215 * we ever want to deallocate entries. 216 */ 217 for_each_string(i, from) { 218 char *mergestring = from->Strings[i]; 219 220 if (mergestring == CANCELLED_STRING) 221 to->Strings[i] = ABSENT_STRING; 222 else if (mergestring != ABSENT_STRING) 223 to->Strings[i] = mergestring; 224 } 225 } 226