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