Back to index

tetex-bin  3.0
alloc_entry.c
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Copyright (c) 1998-2003,2004 Free Software Foundation, Inc.              *
00003  *                                                                          *
00004  * Permission is hereby granted, free of charge, to any person obtaining a  *
00005  * copy of this software and associated documentation files (the            *
00006  * "Software"), to deal in the Software without restriction, including      *
00007  * without limitation the rights to use, copy, modify, merge, publish,      *
00008  * distribute, distribute with modifications, sublicense, and/or sell       *
00009  * copies of the Software, and to permit persons to whom the Software is    *
00010  * furnished to do so, subject to the following conditions:                 *
00011  *                                                                          *
00012  * The above copyright notice and this permission notice shall be included  *
00013  * in all copies or substantial portions of the Software.                   *
00014  *                                                                          *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00016  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00017  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00018  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00020  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00021  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00022  *                                                                          *
00023  * Except as contained in this notice, the name(s) of the above copyright   *
00024  * holders shall not be used in advertising or otherwise to promote the     *
00025  * sale, use or other dealings in this Software without prior written       *
00026  * authorization.                                                           *
00027  ****************************************************************************/
00028 
00029 /****************************************************************************
00030  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
00031  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
00032  *     and: Thomas E. Dickey                        1996-on                 *
00033  ****************************************************************************/
00034 
00035 /*
00036  * alloc_entry.c -- allocation functions for terminfo entries
00037  *
00038  *     _nc_copy_entry()
00039  *     _nc_init_entry()
00040  *     _nc_merge_entry()
00041  *     _nc_save_str()
00042  *     _nc_wrap_entry()
00043  *
00044  */
00045 
00046 #include <curses.priv.h>
00047 
00048 #include <tic.h>
00049 #include <term_entry.h>
00050 
00051 MODULE_ID("$Id: alloc_entry.c,v 1.41 2004/04/17 22:06:25 tom Exp $")
00052 
00053 #define ABSENT_OFFSET    -1
00054 #define CANCELLED_OFFSET -2
00055 
00056 #define MAX_STRTAB   4096   /* documented maximum entry size */
00057 
00058 static char *stringbuf;            /* buffer for string capabilities */
00059 static size_t next_free;    /* next free character in stringbuf */
00060 
00061 NCURSES_EXPORT(void)
00062 _nc_init_entry(TERMTYPE * const tp)
00063 /* initialize a terminal type data block */
00064 {
00065     unsigned i;
00066 
00067 #if NO_LEAKS
00068     if (tp == 0) {
00069        FreeAndNull(stringbuf);
00070        return;
00071     }
00072 #endif
00073 
00074     if (stringbuf == 0)
00075        stringbuf = (char *) malloc(MAX_STRTAB);
00076 
00077 #if NCURSES_XNAMES
00078     tp->num_Booleans = BOOLCOUNT;
00079     tp->num_Numbers = NUMCOUNT;
00080     tp->num_Strings = STRCOUNT;
00081     tp->ext_Booleans = 0;
00082     tp->ext_Numbers = 0;
00083     tp->ext_Strings = 0;
00084 #endif
00085     if (tp->Booleans == 0)
00086        tp->Booleans = typeMalloc(char, BOOLCOUNT);
00087     if (tp->Numbers == 0)
00088        tp->Numbers = typeMalloc(short, NUMCOUNT);
00089     if (tp->Strings == 0)
00090        tp->Strings = typeMalloc(char *, STRCOUNT);
00091 
00092     for_each_boolean(i, tp)
00093        tp->Booleans[i] = FALSE;
00094 
00095     for_each_number(i, tp)
00096        tp->Numbers[i] = ABSENT_NUMERIC;
00097 
00098     for_each_string(i, tp)
00099        tp->Strings[i] = ABSENT_STRING;
00100 
00101     next_free = 0;
00102 }
00103 
00104 NCURSES_EXPORT(ENTRY *)
00105 _nc_copy_entry(ENTRY * oldp)
00106 {
00107     ENTRY *newp = typeCalloc(ENTRY, 1);
00108 
00109     if (newp != 0) {
00110        *newp = *oldp;
00111        _nc_copy_termtype(&(newp->tterm), &(oldp->tterm));
00112     }
00113     return newp;
00114 }
00115 
00116 NCURSES_EXPORT(char *)
00117 _nc_save_str(const char *const string)
00118 /* save a copy of string in the string buffer */
00119 {
00120     size_t old_next_free = next_free;
00121     size_t len = strlen(string) + 1;
00122 
00123     if (next_free + len < MAX_STRTAB) {
00124        strcpy(&stringbuf[next_free], string);
00125        DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
00126        DEBUG(7, ("at location %d", (int) next_free));
00127        next_free += len;
00128     }
00129     return (stringbuf + old_next_free);
00130 }
00131 
00132 NCURSES_EXPORT(void)
00133 _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
00134 /* copy the string parts to allocated storage, preserving pointers to it */
00135 {
00136     int offsets[MAX_ENTRY_SIZE / 2], useoffsets[MAX_USES];
00137     unsigned i, n;
00138     unsigned nuses = ep->nuses;
00139     TERMTYPE *tp = &(ep->tterm);
00140 
00141     if (copy_strings) {
00142        next_free = 0;              /* clear static storage */
00143 
00144        /* copy term_names, Strings, uses */
00145        tp->term_names = _nc_save_str(tp->term_names);
00146        for_each_string(i, tp) {
00147            if (tp->Strings[i] != ABSENT_STRING &&
00148               tp->Strings[i] != CANCELLED_STRING) {
00149               tp->Strings[i] = _nc_save_str(tp->Strings[i]);
00150            }
00151        }
00152 
00153        for (i = 0; i < nuses; i++) {
00154            if (ep->uses[i].name == 0) {
00155               ep->uses[i].name = _nc_save_str(ep->uses[i].name);
00156            }
00157        }
00158 
00159        free(tp->str_table);
00160     }
00161 
00162     n = tp->term_names - stringbuf;
00163     for_each_string(i, &(ep->tterm)) {
00164        if (tp->Strings[i] == ABSENT_STRING)
00165            offsets[i] = ABSENT_OFFSET;
00166        else if (tp->Strings[i] == CANCELLED_STRING)
00167            offsets[i] = CANCELLED_OFFSET;
00168        else
00169            offsets[i] = tp->Strings[i] - stringbuf;
00170     }
00171 
00172     for (i = 0; i < nuses; i++) {
00173        if (ep->uses[i].name == 0)
00174            useoffsets[i] = ABSENT_OFFSET;
00175        else
00176            useoffsets[i] = ep->uses[i].name - stringbuf;
00177     }
00178 
00179     if ((tp->str_table = typeMalloc(char, next_free)) == (char *) 0)
00180          _nc_err_abort(MSG_NO_MEMORY);
00181     (void) memcpy(tp->str_table, stringbuf, next_free);
00182 
00183     tp->term_names = tp->str_table + n;
00184     for_each_string(i, &(ep->tterm)) {
00185        if (offsets[i] == ABSENT_OFFSET)
00186            tp->Strings[i] = ABSENT_STRING;
00187        else if (offsets[i] == CANCELLED_OFFSET)
00188            tp->Strings[i] = CANCELLED_STRING;
00189        else
00190            tp->Strings[i] = tp->str_table + offsets[i];
00191     }
00192 
00193 #if NCURSES_XNAMES
00194     if (!copy_strings) {
00195        if ((n = NUM_EXT_NAMES(tp)) != 0) {
00196            unsigned length = 0;
00197            for (i = 0; i < n; i++) {
00198               length += strlen(tp->ext_Names[i]) + 1;
00199               offsets[i] = tp->ext_Names[i] - stringbuf;
00200            }
00201            if ((tp->ext_str_table = typeMalloc(char, length)) == 0)
00202                 _nc_err_abort(MSG_NO_MEMORY);
00203            for (i = 0, length = 0; i < n; i++) {
00204               tp->ext_Names[i] = tp->ext_str_table + length;
00205               strcpy(tp->ext_Names[i], stringbuf + offsets[i]);
00206               length += strlen(tp->ext_Names[i]) + 1;
00207            }
00208        }
00209     }
00210 #endif
00211 
00212     for (i = 0; i < nuses; i++) {
00213        if (useoffsets[i] == ABSENT_OFFSET)
00214            ep->uses[i].name = 0;
00215        else
00216            ep->uses[i].name = (tp->str_table + useoffsets[i]);
00217     }
00218 }
00219 
00220 NCURSES_EXPORT(void)
00221 _nc_merge_entry(TERMTYPE * const to, TERMTYPE * const from)
00222 /* merge capabilities from `from' entry into `to' entry */
00223 {
00224     unsigned i;
00225 
00226 #if NCURSES_XNAMES
00227     _nc_align_termtype(to, from);
00228 #endif
00229     for_each_boolean(i, from) {
00230        if (to->Booleans[i] != CANCELLED_BOOLEAN) {
00231            int mergebool = from->Booleans[i];
00232 
00233            if (mergebool == CANCELLED_BOOLEAN)
00234               to->Booleans[i] = FALSE;
00235            else if (mergebool == TRUE)
00236               to->Booleans[i] = mergebool;
00237        }
00238     }
00239 
00240     for_each_number(i, from) {
00241        if (to->Numbers[i] != CANCELLED_NUMERIC) {
00242            int mergenum = from->Numbers[i];
00243 
00244            if (mergenum == CANCELLED_NUMERIC)
00245               to->Numbers[i] = ABSENT_NUMERIC;
00246            else if (mergenum != ABSENT_NUMERIC)
00247               to->Numbers[i] = mergenum;
00248        }
00249     }
00250 
00251     /*
00252      * Note: the copies of strings this makes don't have their own
00253      * storage.  This is OK right now, but will be a problem if we
00254      * we ever want to deallocate entries.
00255      */
00256     for_each_string(i, from) {
00257        if (to->Strings[i] != CANCELLED_STRING) {
00258            char *mergestring = from->Strings[i];
00259 
00260            if (mergestring == CANCELLED_STRING)
00261               to->Strings[i] = ABSENT_STRING;
00262            else if (mergestring != ABSENT_STRING)
00263               to->Strings[i] = mergestring;
00264        }
00265     }
00266 }