ncurses 4.1
[ncurses.git] / ncurses / alloc_entry.c
1
2 /***************************************************************************
3 *                            COPYRIGHT NOTICE                              *
4 ****************************************************************************
5 *                ncurses is copyright (C) 1992-1995                        *
6 *                          Zeyd M. Ben-Halim                               *
7 *                          zmbenhal@netcom.com                             *
8 *                          Eric S. Raymond                                 *
9 *                          esr@snark.thyrsus.com                           *
10 *                                                                          *
11 *        Permission is hereby granted to reproduce and distribute ncurses  *
12 *        by any means and for any fee, whether alone or as part of a       *
13 *        larger distribution, in source or in binary form, PROVIDED        *
14 *        this notice is included with any such distribution, and is not    *
15 *        removed from any of its header files. Mention of ncurses in any   *
16 *        applications linked with it is highly appreciated.                *
17 *                                                                          *
18 *        ncurses comes AS IS with no warranty, implied or expressed.       *
19 *                                                                          *
20 ***************************************************************************/
21
22
23 /*
24  * alloc_entry.c -- allocation functions for terminfo entries
25  *
26  *      _nc_init_entry()
27  *      _nc_save_str()
28  *      _nc_merge_entry();
29  *      _nc_wrap_entry();
30  *
31  */
32
33 #include <curses.priv.h>
34
35 #include <tic.h>
36 #include <term.h>
37 #include <term_entry.h>
38
39 MODULE_ID("$Id: alloc_entry.c,v 1.12 1997/02/01 22:59:47 tom Exp $")
40
41 #define MAX_STRTAB      4096    /* documented maximum entry size */
42
43 static char     stringbuf[MAX_STRTAB];  /* buffer for string capabilities */
44 static size_t   next_free;              /* next free character in stringbuf */
45
46 void _nc_init_entry(TERMTYPE *const tp)
47 /* initialize a terminal type data block */
48 {
49 int     i;
50
51         for (i=0; i < BOOLCOUNT; i++)
52                     tp->Booleans[i] = FALSE;
53
54         for (i=0; i < NUMCOUNT; i++)
55                     tp->Numbers[i] = -1;
56
57         for (i=0; i < STRCOUNT; i++)
58                     tp->Strings[i] = (char *)NULL;
59
60         next_free = 0;
61 }
62
63 char *_nc_save_str(const char *const string)
64 /* save a copy of string in the string buffer */
65 {
66 size_t  old_next_free = next_free;
67 size_t  len = strlen(string) + 1;
68
69         if (next_free + len < MAX_STRTAB)
70         {
71                 strcpy(&stringbuf[next_free], string);
72                 DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
73                 DEBUG(7, ("at location %d", (int) next_free));
74                 next_free += len;
75         }
76         return(stringbuf + old_next_free);
77 }
78
79 void _nc_wrap_entry(ENTRY *const ep)
80 /* copy the string parts to allocated storage, preserving pointers to it */
81 {
82 int     offsets[STRCOUNT], useoffsets[MAX_USES];
83 int     i, n;
84
85         n = ep->tterm.term_names - stringbuf;
86         for (i=0; i < STRCOUNT; i++)
87                 if (ep->tterm.Strings[i] == (char *)NULL)
88                         offsets[i] = -1;
89                 else if (ep->tterm.Strings[i] == CANCELLED_STRING)
90                         offsets[i] = -2;
91                 else
92                         offsets[i] = ep->tterm.Strings[i] - stringbuf;
93
94         for (i=0; i < ep->nuses; i++)
95                 if (ep->uses[i].parent == (void *)NULL)
96                         useoffsets[i] = -1;
97                 else
98                         useoffsets[i] = (char *)(ep->uses[i].parent) - stringbuf;
99
100         if ((ep->tterm.str_table = (char *)malloc(next_free)) == (char *)NULL)
101                 _nc_err_abort("Out of memory");
102         (void) memcpy(ep->tterm.str_table, stringbuf, next_free);
103
104         ep->tterm.term_names = ep->tterm.str_table + n;
105         for (i=0; i < STRCOUNT; i++)
106                 if (offsets[i] == -1)
107                         ep->tterm.Strings[i] = (char *)NULL;
108                 else if (offsets[i] == -2)
109                         ep->tterm.Strings[i] = CANCELLED_STRING;
110                 else
111                         ep->tterm.Strings[i] = ep->tterm.str_table + offsets[i];
112
113         for (i=0; i < ep->nuses; i++)
114                 if (useoffsets[i] == -1)
115                         ep->uses[i].parent = (void *)NULL;
116                 else
117                         ep->uses[i].parent = (char *)(ep->tterm.str_table + useoffsets[i]);
118 }
119
120 void _nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
121 /* merge capabilities from `from' entry into `to' entry */
122 {
123     int i;
124
125     for (i=0; i < BOOLCOUNT; i++)
126     {
127         int     mergebool = from->Booleans[i];
128
129         if (mergebool == CANCELLED_BOOLEAN)
130             to->Booleans[i] = FALSE;
131         else if (mergebool == TRUE)
132             to->Booleans[i] = mergebool;
133     }
134
135     for (i=0; i < NUMCOUNT; i++)
136     {
137         int     mergenum = from->Numbers[i];
138
139         if (mergenum == CANCELLED_NUMERIC)
140             to->Numbers[i] = ABSENT_NUMERIC;
141         else if (mergenum != ABSENT_NUMERIC)
142             to->Numbers[i] = mergenum;
143     }
144
145     /*
146      * Note: the copies of strings this makes don't have their own
147      * storage.  This is OK right now, but will be a problem if we
148      * we ever want to deallocate entries.
149      */
150     for (i=0; i < STRCOUNT; i++)
151     {
152         char    *mergestring = from->Strings[i];
153
154         if (mergestring == CANCELLED_STRING)
155             to->Strings[i] = ABSENT_STRING;
156         else if (mergestring != ABSENT_STRING)
157             to->Strings[i] = mergestring;
158     }
159 }
160