xref: /openbsd-src/lib/libcurses/tinfo/alloc_entry.c (revision 92dd1ec0a89df25171bc5d61a3d95ea1a68cef0b)
1 /*	$OpenBSD: alloc_entry.c,v 1.1 1999/01/18 19:10:13 millert Exp $	*/
2 
3 /****************************************************************************
4  * Copyright (c) 1998 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  ****************************************************************************/
35 
36 
37 /*
38  * alloc_entry.c -- allocation functions for terminfo entries
39  *
40  *	_nc_init_entry()
41  *	_nc_save_str()
42  *	_nc_merge_entry();
43  *	_nc_wrap_entry();
44  *
45  */
46 
47 #include <curses.priv.h>
48 
49 #include <tic.h>
50 #include <term.h>
51 #include <term_entry.h>
52 
53 MODULE_ID("$From: alloc_entry.c,v 1.14 1998/07/04 23:17:42 tom 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[MAX_STRTAB];	/* buffer for string capabilities */
61 static size_t	next_free;		/* next free character in stringbuf */
62 
63 void _nc_init_entry(TERMTYPE *const tp)
64 /* initialize a terminal type data block */
65 {
66 int	i;
67 
68 	for (i=0; i < BOOLCOUNT; i++)
69 		tp->Booleans[i] = FALSE; /* FIXME: why not ABSENT_BOOLEAN? */
70 
71 	for (i=0; i < NUMCOUNT; i++)
72 		tp->Numbers[i] = ABSENT_NUMERIC;
73 
74 	for (i=0; i < STRCOUNT; i++)
75 		tp->Strings[i] = ABSENT_STRING;
76 
77 	next_free = 0;
78 }
79 
80 char *_nc_save_str(const char *const string)
81 /* save a copy of string in the string buffer */
82 {
83 size_t	old_next_free = next_free;
84 size_t	len = strlen(string) + 1;
85 
86 	if (next_free + len < MAX_STRTAB)
87 	{
88 		strcpy(&stringbuf[next_free], string);
89 		DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
90 		DEBUG(7, ("at location %d", (int) next_free));
91 		next_free += len;
92 	}
93 	return(stringbuf + old_next_free);
94 }
95 
96 void _nc_wrap_entry(ENTRY *const ep)
97 /* copy the string parts to allocated storage, preserving pointers to it */
98 {
99 int	offsets[STRCOUNT], useoffsets[MAX_USES];
100 int	i, n;
101 
102 	n = ep->tterm.term_names - stringbuf;
103 	for (i=0; i < STRCOUNT; i++)
104 		if (ep->tterm.Strings[i] == ABSENT_STRING)
105 			offsets[i] = ABSENT_OFFSET;
106 		else if (ep->tterm.Strings[i] == CANCELLED_STRING)
107 			offsets[i] = CANCELLED_OFFSET;
108 		else
109 			offsets[i] = ep->tterm.Strings[i] - stringbuf;
110 
111 	for (i=0; i < ep->nuses; i++)
112 		if (ep->uses[i].parent == (void *)0)
113 			useoffsets[i] = ABSENT_OFFSET;
114 		else
115 			useoffsets[i] = (char *)(ep->uses[i].parent) - stringbuf;
116 
117 	if ((ep->tterm.str_table = (char *)malloc(next_free)) == (char *)0)
118 		_nc_err_abort("Out of memory");
119 	(void) memcpy(ep->tterm.str_table, stringbuf, next_free);
120 
121 	ep->tterm.term_names = ep->tterm.str_table + n;
122 	for (i=0; i < STRCOUNT; i++)
123 		if (offsets[i] == ABSENT_OFFSET)
124 			ep->tterm.Strings[i] = ABSENT_STRING;
125 		else if (offsets[i] == CANCELLED_OFFSET)
126 			ep->tterm.Strings[i] = CANCELLED_STRING;
127 		else
128 			ep->tterm.Strings[i] = ep->tterm.str_table + offsets[i];
129 
130 	for (i=0; i < ep->nuses; i++)
131 		if (useoffsets[i] == ABSENT_OFFSET)
132 			ep->uses[i].parent = (void *)0;
133 		else
134 			ep->uses[i].parent = (char *)(ep->tterm.str_table + useoffsets[i]);
135 }
136 
137 void _nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
138 /* merge capabilities from `from' entry into `to' entry */
139 {
140     int	i;
141 
142     for (i=0; i < BOOLCOUNT; i++)
143     {
144 	int	mergebool = from->Booleans[i];
145 
146 	if (mergebool == CANCELLED_BOOLEAN)
147 	    to->Booleans[i] = FALSE;
148 	else if (mergebool == TRUE)
149 	    to->Booleans[i] = mergebool;
150     }
151 
152     for (i=0; i < NUMCOUNT; i++)
153     {
154 	int	mergenum = from->Numbers[i];
155 
156 	if (mergenum == CANCELLED_NUMERIC)
157 	    to->Numbers[i] = ABSENT_NUMERIC;
158 	else if (mergenum != ABSENT_NUMERIC)
159 	    to->Numbers[i] = mergenum;
160     }
161 
162     /*
163      * Note: the copies of strings this makes don't have their own
164      * storage.  This is OK right now, but will be a problem if we
165      * we ever want to deallocate entries.
166      */
167     for (i=0; i < STRCOUNT; i++)
168     {
169 	char	*mergestring = from->Strings[i];
170 
171 	if (mergestring == CANCELLED_STRING)
172 	    to->Strings[i] = ABSENT_STRING;
173 	else if (mergestring != ABSENT_STRING)
174 	    to->Strings[i] = mergestring;
175     }
176 }
177 
178