GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcurses/tinfo/alloc_entry.c Lines: 0 118 0.0 %
Date: 2017-11-07 Branches: 0 98 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: alloc_entry.c,v 1.6 2010/01/12 23:22:06 nicm Exp $ */
2
3
/****************************************************************************
4
 * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
5
 *                                                                          *
6
 * Permission is hereby granted, free of charge, to any person obtaining a  *
7
 * copy of this software and associated documentation files (the            *
8
 * "Software"), to deal in the Software without restriction, including      *
9
 * without limitation the rights to use, copy, modify, merge, publish,      *
10
 * distribute, distribute with modifications, sublicense, and/or sell       *
11
 * copies of the Software, and to permit persons to whom the Software is    *
12
 * furnished to do so, subject to the following conditions:                 *
13
 *                                                                          *
14
 * The above copyright notice and this permission notice shall be included  *
15
 * in all copies or substantial portions of the Software.                   *
16
 *                                                                          *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
20
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
21
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
22
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
23
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
24
 *                                                                          *
25
 * Except as contained in this notice, the name(s) of the above copyright   *
26
 * holders shall not be used in advertising or otherwise to promote the     *
27
 * sale, use or other dealings in this Software without prior written       *
28
 * authorization.                                                           *
29
 ****************************************************************************/
30
31
/****************************************************************************
32
 *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
33
 *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
34
 *     and: Thomas E. Dickey                        1996-on                 *
35
 ****************************************************************************/
36
37
/*
38
 * alloc_entry.c -- allocation functions for terminfo entries
39
 *
40
 *	_nc_copy_entry()
41
 *	_nc_init_entry()
42
 *	_nc_merge_entry()
43
 *	_nc_save_str()
44
 *	_nc_wrap_entry()
45
 *
46
 */
47
48
#include <curses.priv.h>
49
50
#include <tic.h>
51
#include <term_entry.h>
52
53
MODULE_ID("$Id: alloc_entry.c,v 1.6 2010/01/12 23:22:06 nicm Exp $")
54
55
#define ABSENT_OFFSET    -1
56
#define CANCELLED_OFFSET -2
57
58
#define MAX_STRTAB	4096	/* documented maximum entry size */
59
60
static char *stringbuf;		/* buffer for string capabilities */
61
static size_t next_free;	/* next free character in stringbuf */
62
63
NCURSES_EXPORT(void)
64
_nc_init_entry(TERMTYPE *const tp)
65
/* initialize a terminal type data block */
66
{
67
    unsigned i;
68
69
#if NO_LEAKS
70
    if (tp == 0 && stringbuf != 0) {
71
	FreeAndNull(stringbuf);
72
	return;
73
    }
74
#endif
75
76
    if (stringbuf == 0)
77
	stringbuf = (char *) malloc(MAX_STRTAB);
78
79
#if NCURSES_XNAMES
80
    tp->num_Booleans = BOOLCOUNT;
81
    tp->num_Numbers = NUMCOUNT;
82
    tp->num_Strings = STRCOUNT;
83
    tp->ext_Booleans = 0;
84
    tp->ext_Numbers = 0;
85
    tp->ext_Strings = 0;
86
#endif
87
    if (tp->Booleans == 0)
88
	tp->Booleans = typeMalloc(NCURSES_SBOOL, BOOLCOUNT);
89
    if (tp->Numbers == 0)
90
	tp->Numbers = typeMalloc(short, NUMCOUNT);
91
    if (tp->Strings == 0)
92
	tp->Strings = typeMalloc(char *, STRCOUNT);
93
94
    for_each_boolean(i, tp)
95
	tp->Booleans[i] = FALSE;
96
97
    for_each_number(i, tp)
98
	tp->Numbers[i] = ABSENT_NUMERIC;
99
100
    for_each_string(i, tp)
101
	tp->Strings[i] = ABSENT_STRING;
102
103
    next_free = 0;
104
}
105
106
NCURSES_EXPORT(ENTRY *)
107
_nc_copy_entry(ENTRY * oldp)
108
{
109
    ENTRY *newp = typeCalloc(ENTRY, 1);
110
111
    if (newp != 0) {
112
	*newp = *oldp;
113
	_nc_copy_termtype(&(newp->tterm), &(oldp->tterm));
114
    }
115
    return newp;
116
}
117
118
/* save a copy of string in the string buffer */
119
NCURSES_EXPORT(char *)
120
_nc_save_str(const char *const string)
121
{
122
    char *result = 0;
123
    size_t old_next_free = next_free;
124
    size_t len = strlen(string) + 1;
125
126
    if (len == 1 && next_free != 0) {
127
	/*
128
	 * Cheat a little by making an empty string point to the end of the
129
	 * previous string.
130
	 */
131
	if (next_free < MAX_STRTAB) {
132
	    result = (stringbuf + next_free - 1);
133
	}
134
    } else if (next_free + len < MAX_STRTAB) {
135
	strlcpy(&stringbuf[next_free], string, MAX_STRTAB - next_free);
136
	DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
137
	DEBUG(7, ("at location %d", (int) next_free));
138
	next_free += len;
139
	result = (stringbuf + old_next_free);
140
    } else {
141
	_nc_warning("Too much data, some is lost");
142
    }
143
    return result;
144
}
145
146
NCURSES_EXPORT(void)
147
_nc_wrap_entry(ENTRY * const ep, bool copy_strings)
148
/* copy the string parts to allocated storage, preserving pointers to it */
149
{
150
    int offsets[MAX_ENTRY_SIZE / sizeof(short)];
151
    int useoffsets[MAX_USES];
152
    unsigned i, n;
153
    unsigned nuses = ep->nuses;
154
    TERMTYPE *tp = &(ep->tterm);
155
156
    if (copy_strings) {
157
	next_free = 0;		/* clear static storage */
158
159
	/* copy term_names, Strings, uses */
160
	tp->term_names = _nc_save_str(tp->term_names);
161
	for_each_string(i, tp) {
162
	    if (tp->Strings[i] != ABSENT_STRING &&
163
		tp->Strings[i] != CANCELLED_STRING) {
164
		tp->Strings[i] = _nc_save_str(tp->Strings[i]);
165
	    }
166
	}
167
168
	for (i = 0; i < nuses; i++) {
169
	    if (ep->uses[i].name == 0) {
170
		ep->uses[i].name = _nc_save_str(ep->uses[i].name);
171
	    }
172
	}
173
174
	free(tp->str_table);
175
    }
176
177
    assert(tp->term_names >= stringbuf);
178
    n = (unsigned) (tp->term_names - stringbuf);
179
    for_each_string(i, &(ep->tterm)) {
180
	if (i < SIZEOF(offsets)) {
181
	    if (tp->Strings[i] == ABSENT_STRING) {
182
		offsets[i] = ABSENT_OFFSET;
183
	    } else if (tp->Strings[i] == CANCELLED_STRING) {
184
		offsets[i] = CANCELLED_OFFSET;
185
	    } else {
186
		offsets[i] = tp->Strings[i] - stringbuf;
187
	    }
188
	}
189
    }
190
191
    for (i = 0; i < nuses; i++) {
192
	if (ep->uses[i].name == 0)
193
	    useoffsets[i] = ABSENT_OFFSET;
194
	else
195
	    useoffsets[i] = ep->uses[i].name - stringbuf;
196
    }
197
198
    if ((tp->str_table = typeMalloc(char, next_free)) == (char *) 0)
199
	  _nc_err_abort(MSG_NO_MEMORY);
200
    (void) memcpy(tp->str_table, stringbuf, next_free);
201
202
    tp->term_names = tp->str_table + n;
203
    for_each_string(i, &(ep->tterm)) {
204
	if (i < SIZEOF(offsets)) {
205
	    if (offsets[i] == ABSENT_OFFSET) {
206
		tp->Strings[i] = ABSENT_STRING;
207
	    } else if (offsets[i] == CANCELLED_OFFSET) {
208
		tp->Strings[i] = CANCELLED_STRING;
209
	    } else {
210
		tp->Strings[i] = tp->str_table + offsets[i];
211
	    }
212
	}
213
    }
214
215
#if NCURSES_XNAMES
216
    if (!copy_strings) {
217
	if ((n = (unsigned) NUM_EXT_NAMES(tp)) != 0) {
218
	    if (n < SIZEOF(offsets)) {
219
		size_t copied, length, strtabsize = 0;
220
		for (i = 0; i < n; i++) {
221
		    strtabsize += strlen(tp->ext_Names[i]) + 1;
222
		    offsets[i] = tp->ext_Names[i] - stringbuf;
223
		}
224
		if ((tp->ext_str_table = typeMalloc(char, strtabsize)) == 0)
225
		      _nc_err_abort(MSG_NO_MEMORY);
226
		for (i = 0, length = 0; i < n; i++) {
227
		    tp->ext_Names[i] = tp->ext_str_table + length;
228
		    copied = strlcpy(tp->ext_Names[i], stringbuf + offsets[i],
229
			strtabsize) + 1;
230
		    if (copied > strtabsize)
231
			    _nc_err_abort("Buffer overflow");
232
		    length += copied;
233
		    strtabsize -= copied;
234
		}
235
	    }
236
	}
237
    }
238
#endif
239
240
    for (i = 0; i < nuses; i++) {
241
	if (useoffsets[i] == ABSENT_OFFSET)
242
	    ep->uses[i].name = 0;
243
	else
244
	    ep->uses[i].name = (tp->str_table + useoffsets[i]);
245
    }
246
}
247
248
NCURSES_EXPORT(void)
249
_nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
250
/* merge capabilities from `from' entry into `to' entry */
251
{
252
    unsigned i;
253
254
#if NCURSES_XNAMES
255
    _nc_align_termtype(to, from);
256
#endif
257
    for_each_boolean(i, from) {
258
	if (to->Booleans[i] != (char) CANCELLED_BOOLEAN) {
259
	    int mergebool = from->Booleans[i];
260
261
	    if (mergebool == CANCELLED_BOOLEAN)
262
		to->Booleans[i] = FALSE;
263
	    else if (mergebool == TRUE)
264
		to->Booleans[i] = (char) mergebool;
265
	}
266
    }
267
268
    for_each_number(i, from) {
269
	if (to->Numbers[i] != CANCELLED_NUMERIC) {
270
	    short mergenum = from->Numbers[i];
271
272
	    if (mergenum == CANCELLED_NUMERIC)
273
		to->Numbers[i] = ABSENT_NUMERIC;
274
	    else if (mergenum != ABSENT_NUMERIC)
275
		to->Numbers[i] = mergenum;
276
	}
277
    }
278
279
    /*
280
     * Note: the copies of strings this makes don't have their own
281
     * storage.  This is OK right now, but will be a problem if we
282
     * we ever want to deallocate entries.
283
     */
284
    for_each_string(i, from) {
285
	if (to->Strings[i] != CANCELLED_STRING) {
286
	    char *mergestring = from->Strings[i];
287
288
	    if (mergestring == CANCELLED_STRING)
289
		to->Strings[i] = ABSENT_STRING;
290
	    else if (mergestring != ABSENT_STRING)
291
		to->Strings[i] = mergestring;
292
	}
293
    }
294
}
295
296
#if NO_LEAKS
297
NCURSES_EXPORT(void)
298
_nc_alloc_entry_leaks(void)
299
{
300
    if (stringbuf != 0) {
301
	FreeAndNull(stringbuf);
302
    }
303
    next_free = 0;
304
}
305
#endif