⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alloc_ttype.c

📁 ncurses-5.4
💻 C
字号:
/**************************************************************************** * Copyright (c) 1999-2002,2003 Free Software Foundation, Inc.              * *                                                                          * * Permission is hereby granted, free of charge, to any person obtaining a  * * copy of this software and associated documentation files (the            * * "Software"), to deal in the Software without restriction, including      * * without limitation the rights to use, copy, modify, merge, publish,      * * distribute, distribute with modifications, sublicense, and/or sell       * * copies of the Software, and to permit persons to whom the Software is    * * furnished to do so, subject to the following conditions:                 * *                                                                          * * The above copyright notice and this permission notice shall be included  * * in all copies or substantial portions of the Software.                   * *                                                                          * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    * * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               * *                                                                          * * Except as contained in this notice, the name(s) of the above copyright   * * holders shall not be used in advertising or otherwise to promote the     * * sale, use or other dealings in this Software without prior written       * * authorization.                                                           * ****************************************************************************//**************************************************************************** *  Author: Thomas E. Dickey <dickey@clark.net> 1999                        * ****************************************************************************//* * align_ttype.c --  functions for TERMTYPE * *	_nc_align_termtype() *	_nc_copy_termtype() * */#include <curses.priv.h>#include <tic.h>#include <term_entry.h>MODULE_ID("$Id: alloc_ttype.c,v 1.14 2003/05/24 21:10:28 tom Exp $")#if NCURSES_XNAMES/* * Merge the a/b lists into dst.  Both a/b are sorted (see _nc_extend_names()), * so we do not have to worry about order dependencies. */static intmerge_names(char **dst, char **a, int na, char **b, int nb){    int n = 0;    while (na > 0 && nb > 0) {	int cmp = strcmp(*a, *b);	if (cmp < 0) {	    dst[n++] = *a++;	    na--;	} else if (cmp > 0) {	    dst[n++] = *b++;	    nb--;	} else if (cmp == 0) {	    dst[n++] = *a;	    a++, b++;	    na--, nb--;	}    }    while (na-- > 0) {	dst[n++] = *a++;    }    while (nb-- > 0) {	dst[n++] = *b++;    }    DEBUG(4, ("merge_names -> %d", n));    return n;}static boolfind_name(char **table, int length, char *name){    while (length-- > 0) {	if (!strcmp(*table++, name)) {	    DEBUG(4, ("found name '%s'", name));	    return TRUE;	}    }    DEBUG(4, ("did not find name '%s'", name));    return FALSE;}static voidrealign_data(TERMTYPE * to, char **ext_Names,	     int ext_Booleans,	     int ext_Numbers,	     int ext_Strings){    int n, m, base;    int limit = (to->ext_Booleans + to->ext_Numbers + to->ext_Strings);    if (to->ext_Booleans != ext_Booleans) {	to->num_Booleans += (ext_Booleans - to->ext_Booleans);	to->Booleans = typeRealloc(char, to->num_Booleans, to->Booleans);	for (n = to->ext_Booleans - 1,	     m = ext_Booleans - 1,	     base = to->num_Booleans - (m + 1); m >= 0; m--) {	    if (find_name(to->ext_Names, limit, ext_Names[m])) {		to->Booleans[base + m] = to->Booleans[base + n--];	    } else {		to->Booleans[base + m] = FALSE;	    }	}	to->ext_Booleans = ext_Booleans;    }    if (to->ext_Numbers != ext_Numbers) {	to->num_Numbers += (ext_Numbers - to->ext_Numbers);	to->Numbers = typeRealloc(short, to->num_Numbers, to->Numbers);	for (n = to->ext_Numbers - 1,	     m = ext_Numbers - 1,	     base = to->num_Numbers - (m + 1); m >= 0; m--) {	    if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans])) {		to->Numbers[base + m] = to->Numbers[base + n--];	    } else {		to->Numbers[base + m] = ABSENT_NUMERIC;	    }	}	to->ext_Numbers = ext_Numbers;    }    if (to->ext_Strings != ext_Strings) {	to->num_Strings += (ext_Strings - to->ext_Strings);	to->Strings = typeRealloc(char *, to->num_Strings, to->Strings);	for (n = to->ext_Strings - 1,	     m = ext_Strings - 1,	     base = to->num_Strings - (m + 1); m >= 0; m--) {	    if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans + ext_Numbers])) {		to->Strings[base + m] = to->Strings[base + n--];	    } else {		to->Strings[base + m] = ABSENT_STRING;	    }	}	to->ext_Strings = ext_Strings;    }}/* * Returns the first index in ext_Names[] for the given token-type */static int_nc_first_ext_name(TERMTYPE * tp, int token_type){    int first;    switch (token_type) {    case BOOLEAN:	first = 0;	break;    case NUMBER:	first = tp->ext_Booleans;	break;    case STRING:	first = tp->ext_Booleans + tp->ext_Numbers;	break;    default:	first = 0;	break;    }    return first;}/* * Returns the last index in ext_Names[] for the given token-type */static int_nc_last_ext_name(TERMTYPE * tp, int token_type){    int last;    switch (token_type) {    case BOOLEAN:	last = tp->ext_Booleans;	break;    case NUMBER:	last = tp->ext_Booleans + tp->ext_Numbers;	break;    default:    case STRING:	last = NUM_EXT_NAMES(tp);	break;    }    return last;}/* * Lookup an entry from extended-names, returning -1 if not found */static int_nc_find_ext_name(TERMTYPE * tp, char *name, int token_type){    unsigned j;    unsigned first = _nc_first_ext_name(tp, token_type);    unsigned last = _nc_last_ext_name(tp, token_type);    for (j = first; j < last; j++) {	if (!strcmp(name, tp->ext_Names[j])) {	    return j;	}    }    return -1;}/* * Translate an index into ext_Names[] into the corresponding index into data * (e.g., Booleans[]). */static int_nc_ext_data_index(TERMTYPE * tp, int n, int token_type){    switch (token_type) {    case BOOLEAN:	n += (tp->num_Booleans - tp->ext_Booleans);	break;    case NUMBER:	n += (tp->num_Numbers - tp->ext_Numbers)	    - (tp->ext_Booleans);	break;    default:    case STRING:	n += (tp->num_Strings - tp->ext_Strings)	    - (tp->ext_Booleans + tp->ext_Numbers);    }    return n;}/* * Adjust tables to remove (not free) an extended name and its corresponding * data. */static bool_nc_del_ext_name(TERMTYPE * tp, char *name, int token_type){    int j;    int first, last;    if ((first = _nc_find_ext_name(tp, name, token_type)) >= 0) {	last = NUM_EXT_NAMES(tp) - 1;	for (j = first; j < last; j++) {	    tp->ext_Names[j] = tp->ext_Names[j + 1];	}	first = _nc_ext_data_index(tp, first, token_type);	switch (token_type) {	case BOOLEAN:	    last = tp->num_Booleans - 1;	    for (j = first; j < last; j++)		tp->Booleans[j] = tp->Booleans[j + 1];	    tp->ext_Booleans -= 1;	    tp->num_Booleans -= 1;	    break;	case NUMBER:	    last = tp->num_Numbers - 1;	    for (j = first; j < last; j++)		tp->Numbers[j] = tp->Numbers[j + 1];	    tp->ext_Numbers -= 1;	    tp->num_Numbers -= 1;	    break;	case STRING:	    last = tp->num_Strings - 1;	    for (j = first; j < last; j++)		tp->Strings[j] = tp->Strings[j + 1];	    tp->ext_Strings -= 1;	    tp->num_Strings -= 1;	    break;	}	return TRUE;    }    return FALSE;}/* * Adjust tables to insert an extended name, making room for new data.  The * index into the corresponding data array is returned. */static int_nc_ins_ext_name(TERMTYPE * tp, char *name, int token_type){    unsigned first = _nc_first_ext_name(tp, token_type);    unsigned last = _nc_last_ext_name(tp, token_type);    unsigned total = NUM_EXT_NAMES(tp) + 1;    unsigned j, k;    for (j = first; j < last; j++) {	int cmp = strcmp(name, tp->ext_Names[j]);	if (cmp == 0)	    /* already present */	    return _nc_ext_data_index(tp, (int) j, token_type);	if (cmp < 0) {	    break;	}    }    tp->ext_Names = typeRealloc(char *, total, tp->ext_Names);    for (k = total - 1; k > j; k--)	tp->ext_Names[k] = tp->ext_Names[k - 1];    tp->ext_Names[j] = name;    j = _nc_ext_data_index(tp, (int) j, token_type);    switch (token_type) {    case BOOLEAN:	tp->ext_Booleans += 1;	tp->num_Booleans += 1;	tp->Booleans = typeRealloc(char, tp->num_Booleans, tp->Booleans);	for (k = tp->num_Booleans - 1; k > j; k--)	    tp->Booleans[k] = tp->Booleans[k - 1];	break;    case NUMBER:	tp->ext_Numbers += 1;	tp->num_Numbers += 1;	tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers);	for (k = tp->num_Numbers - 1; k > j; k--)	    tp->Numbers[k] = tp->Numbers[k - 1];	break;    case STRING:	tp->ext_Strings += 1;	tp->num_Strings += 1;	tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings);	for (k = tp->num_Strings - 1; k > j; k--)	    tp->Strings[k] = tp->Strings[k - 1];	break;    }    return j;}/* * Look for strings that are marked cancelled, which happen to be the same name * as a boolean or number.  We'll get this as a special case when we get a * cancellation of a name that is inherited from another entry. */static voidadjust_cancels(TERMTYPE * to, TERMTYPE * from){    int first = to->ext_Booleans + to->ext_Numbers;    int last = first + to->ext_Strings;    int j, k;    for (j = first; j < last;) {	char *name = to->ext_Names[j];	unsigned j_str = to->num_Strings - first - to->ext_Strings;	if (to->Strings[j + j_str] == CANCELLED_STRING) {	    if ((k = _nc_find_ext_name(from, to->ext_Names[j], BOOLEAN)) >= 0) {		if (_nc_del_ext_name(to, name, STRING)		    || _nc_del_ext_name(to, name, NUMBER)) {		    k = _nc_ins_ext_name(to, name, BOOLEAN);		    to->Booleans[k] = FALSE;		} else {		    j++;		}	    } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],					      NUMBER)) >= 0) {		if (_nc_del_ext_name(to, name, STRING)		    || _nc_del_ext_name(to, name, BOOLEAN)) {		    k = _nc_ins_ext_name(to, name, NUMBER);		    to->Numbers[k] = CANCELLED_NUMERIC;		} else {		    j++;		}	    }	} else {	    j++;	}    }}NCURSES_EXPORT(void)_nc_align_termtype(TERMTYPE * to, TERMTYPE * from){    int na = NUM_EXT_NAMES(to);    int nb = NUM_EXT_NAMES(from);    int n;    bool same;    char **ext_Names;    int ext_Booleans, ext_Numbers, ext_Strings;    DEBUG(2, ("align_termtype to(%d:%s), from(%d:%s)", na, to->term_names,	      nb, from->term_names));    if (na != 0 || nb != 0) {	if ((na == nb)		/* check if the arrays are equivalent */	    &&(to->ext_Booleans == from->ext_Booleans)	    && (to->ext_Numbers == from->ext_Numbers)	    && (to->ext_Strings == from->ext_Strings)) {	    for (n = 0, same = TRUE; n < na; n++) {		if (strcmp(to->ext_Names[n], from->ext_Names[n])) {		    same = FALSE;		    break;		}	    }	    if (same)		return;	}	/*	 * This is where we pay for having a simple extension representation. 	 * Allocate a new ext_Names array and merge the two ext_Names arrays	 * into it, updating to's counts for booleans, etc.  Fortunately we do	 * this only for the terminfo compiler (tic) and comparer (infocmp).	 */	ext_Names = typeMalloc(char *, na + nb);	if (to->ext_Strings && (from->ext_Booleans + from->ext_Numbers))	    adjust_cancels(to, from);	if (from->ext_Strings && (to->ext_Booleans + to->ext_Numbers))	    adjust_cancels(from, to);	ext_Booleans = merge_names(ext_Names,				   to->ext_Names,				   to->ext_Booleans,				   from->ext_Names,				   from->ext_Booleans);	ext_Numbers = merge_names(ext_Names + ext_Booleans,				  to->ext_Names				  + to->ext_Booleans,				  to->ext_Numbers,				  from->ext_Names				  + from->ext_Booleans,				  from->ext_Numbers);	ext_Strings = merge_names(ext_Names + ext_Numbers + ext_Booleans,				  to->ext_Names				  + to->ext_Booleans				  + to->ext_Numbers,				  to->ext_Strings,				  from->ext_Names				  + from->ext_Booleans				  + from->ext_Numbers,				  from->ext_Strings);	/*	 * Now we must reallocate the Booleans, etc., to allow the data to be	 * overlaid.	 */	if (na != (ext_Booleans + ext_Numbers + ext_Strings)) {	    realign_data(to, ext_Names, ext_Booleans, ext_Numbers, ext_Strings);	    FreeIfNeeded(to->ext_Names);	    to->ext_Names = ext_Names;	    DEBUG(2, ("realigned %d extended names for '%s' (to)",		      NUM_EXT_NAMES(to), to->term_names));	}	if (nb != (ext_Booleans + ext_Numbers + ext_Strings)) {	    nb = (ext_Booleans + ext_Numbers + ext_Strings);	    realign_data(from, ext_Names, ext_Booleans, ext_Numbers, ext_Strings);	    from->ext_Names = typeRealloc(char *, nb, from->ext_Names);	    memcpy(from->ext_Names, ext_Names, sizeof(char *) * nb);	    DEBUG(2, ("realigned %d extended names for '%s' (from)",		      NUM_EXT_NAMES(from), from->term_names));	}    }}#endifNCURSES_EXPORT(void)_nc_copy_termtype(TERMTYPE * dst, TERMTYPE * src){    unsigned i;    *dst = *src;		/* ...to copy the sizes and string-tables */    dst->Booleans = typeMalloc(char, NUM_BOOLEANS(dst));    dst->Numbers = typeMalloc(short, NUM_NUMBERS(dst));    dst->Strings = typeMalloc(char *, NUM_STRINGS(dst));    /* FIXME: use memcpy for these and similar loops */    for_each_boolean(i, dst)	dst->Booleans[i] = src->Booleans[i];    for_each_number(i, dst)	dst->Numbers[i] = src->Numbers[i];    for_each_string(i, dst)	dst->Strings[i] = src->Strings[i];    /* FIXME: we probably should also copy str_table and ext_str_table,     * but tic and infocmp are not written to exploit that (yet).     */#if NCURSES_XNAMES    if ((i = NUM_EXT_NAMES(src)) != 0) {	dst->ext_Names = typeMalloc(char *, i);	memcpy(dst->ext_Names, src->ext_Names, i * sizeof(char *));    } else {	dst->ext_Names = 0;    }#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -