150276Speter/****************************************************************************
2184989Srafan * Copyright (c) 1999-2006,2008 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
30166124Srafan *  Author: Thomas E. Dickey <dickey@clark.net> 1999-on                     *
3150276Speter ****************************************************************************/
3250276Speter
3350276Speter/*
3450276Speter * align_ttype.c --  functions for TERMTYPE
3550276Speter *
3650276Speter *	_nc_align_termtype()
3750276Speter *	_nc_copy_termtype()
3850276Speter *
3950276Speter */
4050276Speter
4150276Speter#include <curses.priv.h>
4250276Speter
4350276Speter#include <tic.h>
4450276Speter#include <term_entry.h>
4550276Speter
46184989SrafanMODULE_ID("$Id: alloc_ttype.c,v 1.17 2008/10/12 16:12:00 tom Exp $")
4750276Speter
4850276Speter#if NCURSES_XNAMES
4950276Speter/*
5050276Speter * Merge the a/b lists into dst.  Both a/b are sorted (see _nc_extend_names()),
5150276Speter * so we do not have to worry about order dependencies.
5250276Speter */
5362449Speterstatic int
5462449Spetermerge_names(char **dst, char **a, int na, char **b, int nb)
5550276Speter{
5650276Speter    int n = 0;
5766963Speter    while (na > 0 && nb > 0) {
5850276Speter	int cmp = strcmp(*a, *b);
5950276Speter	if (cmp < 0) {
6050276Speter	    dst[n++] = *a++;
6150276Speter	    na--;
6250276Speter	} else if (cmp > 0) {
6350276Speter	    dst[n++] = *b++;
6450276Speter	    nb--;
6550276Speter	} else if (cmp == 0) {
6650276Speter	    dst[n++] = *a;
6750276Speter	    a++, b++;
6850276Speter	    na--, nb--;
6950276Speter	}
7050276Speter    }
7150276Speter    while (na-- > 0) {
7250276Speter	dst[n++] = *a++;
7350276Speter    }
7450276Speter    while (nb-- > 0) {
7550276Speter	dst[n++] = *b++;
7650276Speter    }
7750276Speter    DEBUG(4, ("merge_names -> %d", n));
7850276Speter    return n;
7950276Speter}
8050276Speter
8162449Speterstatic bool
8262449Speterfind_name(char **table, int length, char *name)
8350276Speter{
8450276Speter    while (length-- > 0) {
8550276Speter	if (!strcmp(*table++, name)) {
8650276Speter	    DEBUG(4, ("found name '%s'", name));
8750276Speter	    return TRUE;
8850276Speter	}
8950276Speter    }
9050276Speter    DEBUG(4, ("did not find name '%s'", name));
9150276Speter    return FALSE;
9250276Speter}
9350276Speter
9462449Speterstatic void
95166124Srafanrealign_data(TERMTYPE *to, char **ext_Names,
96166124Srafan	     int ext_Booleans,
97166124Srafan	     int ext_Numbers,
98166124Srafan	     int ext_Strings)
9950276Speter{
10050276Speter    int n, m, base;
10150276Speter    int limit = (to->ext_Booleans + to->ext_Numbers + to->ext_Strings);
10250276Speter
10350276Speter    if (to->ext_Booleans != ext_Booleans) {
10450276Speter	to->num_Booleans += (ext_Booleans - to->ext_Booleans);
105166124Srafan	to->Booleans = typeRealloc(NCURSES_SBOOL, to->num_Booleans, to->Booleans);
10662449Speter	for (n = to->ext_Booleans - 1,
10766963Speter	     m = ext_Booleans - 1,
10866963Speter	     base = to->num_Booleans - (m + 1); m >= 0; m--) {
10950276Speter	    if (find_name(to->ext_Names, limit, ext_Names[m])) {
11050276Speter		to->Booleans[base + m] = to->Booleans[base + n--];
11150276Speter	    } else {
11250276Speter		to->Booleans[base + m] = FALSE;
11350276Speter	    }
11450276Speter	}
11550276Speter	to->ext_Booleans = ext_Booleans;
11650276Speter    }
11750276Speter    if (to->ext_Numbers != ext_Numbers) {
11850276Speter	to->num_Numbers += (ext_Numbers - to->ext_Numbers);
11950276Speter	to->Numbers = typeRealloc(short, to->num_Numbers, to->Numbers);
12062449Speter	for (n = to->ext_Numbers - 1,
12166963Speter	     m = ext_Numbers - 1,
12266963Speter	     base = to->num_Numbers - (m + 1); m >= 0; m--) {
12362449Speter	    if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans])) {
12450276Speter		to->Numbers[base + m] = to->Numbers[base + n--];
12550276Speter	    } else {
12650276Speter		to->Numbers[base + m] = ABSENT_NUMERIC;
12750276Speter	    }
12850276Speter	}
12962449Speter	to->ext_Numbers = ext_Numbers;
13050276Speter    }
13150276Speter    if (to->ext_Strings != ext_Strings) {
13250276Speter	to->num_Strings += (ext_Strings - to->ext_Strings);
13362449Speter	to->Strings = typeRealloc(char *, to->num_Strings, to->Strings);
13462449Speter	for (n = to->ext_Strings - 1,
13566963Speter	     m = ext_Strings - 1,
13666963Speter	     base = to->num_Strings - (m + 1); m >= 0; m--) {
13762449Speter	    if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans + ext_Numbers])) {
13850276Speter		to->Strings[base + m] = to->Strings[base + n--];
13950276Speter	    } else {
14050276Speter		to->Strings[base + m] = ABSENT_STRING;
14150276Speter	    }
14250276Speter	}
14350276Speter	to->ext_Strings = ext_Strings;
14450276Speter    }
14550276Speter}
14650276Speter
14750276Speter/*
14850276Speter * Returns the first index in ext_Names[] for the given token-type
14950276Speter */
15062449Speterstatic int
151166124Srafan_nc_first_ext_name(TERMTYPE *tp, int token_type)
15250276Speter{
15350276Speter    int first;
15450276Speter
15550276Speter    switch (token_type) {
15650276Speter    case BOOLEAN:
15750276Speter	first = 0;
15850276Speter	break;
15950276Speter    case NUMBER:
16050276Speter	first = tp->ext_Booleans;
16150276Speter	break;
16250276Speter    case STRING:
16350276Speter	first = tp->ext_Booleans + tp->ext_Numbers;
16450276Speter	break;
16550276Speter    default:
16650276Speter	first = 0;
16750276Speter	break;
16850276Speter    }
16950276Speter    return first;
17050276Speter}
17150276Speter
17250276Speter/*
17350276Speter * Returns the last index in ext_Names[] for the given token-type
17450276Speter */
17562449Speterstatic int
176166124Srafan_nc_last_ext_name(TERMTYPE *tp, int token_type)
17750276Speter{
17850276Speter    int last;
17950276Speter
18050276Speter    switch (token_type) {
18150276Speter    case BOOLEAN:
18262449Speter	last = tp->ext_Booleans;
18350276Speter	break;
18450276Speter    case NUMBER:
18562449Speter	last = tp->ext_Booleans + tp->ext_Numbers;
18650276Speter	break;
18750276Speter    default:
18850276Speter    case STRING:
18962449Speter	last = NUM_EXT_NAMES(tp);
19050276Speter	break;
19150276Speter    }
19250276Speter    return last;
19350276Speter}
19450276Speter
19550276Speter/*
19650276Speter * Lookup an entry from extended-names, returning -1 if not found
19750276Speter */
19862449Speterstatic int
199166124Srafan_nc_find_ext_name(TERMTYPE *tp, char *name, int token_type)
20050276Speter{
20150276Speter    unsigned j;
20250276Speter    unsigned first = _nc_first_ext_name(tp, token_type);
20362449Speter    unsigned last = _nc_last_ext_name(tp, token_type);
20450276Speter
20550276Speter    for (j = first; j < last; j++) {
20650276Speter	if (!strcmp(name, tp->ext_Names[j])) {
20750276Speter	    return j;
20850276Speter	}
20950276Speter    }
21050276Speter    return -1;
21150276Speter}
21250276Speter
21350276Speter/*
21450276Speter * Translate an index into ext_Names[] into the corresponding index into data
21550276Speter * (e.g., Booleans[]).
21650276Speter */
21762449Speterstatic int
218166124Srafan_nc_ext_data_index(TERMTYPE *tp, int n, int token_type)
21950276Speter{
22050276Speter    switch (token_type) {
22150276Speter    case BOOLEAN:
22250276Speter	n += (tp->num_Booleans - tp->ext_Booleans);
22350276Speter	break;
22450276Speter    case NUMBER:
22550276Speter	n += (tp->num_Numbers - tp->ext_Numbers)
22662449Speter	    - (tp->ext_Booleans);
22750276Speter	break;
22850276Speter    default:
22950276Speter    case STRING:
23050276Speter	n += (tp->num_Strings - tp->ext_Strings)
23162449Speter	    - (tp->ext_Booleans + tp->ext_Numbers);
23250276Speter    }
23350276Speter    return n;
23450276Speter}
23550276Speter
23650276Speter/*
23750276Speter * Adjust tables to remove (not free) an extended name and its corresponding
23850276Speter * data.
23950276Speter */
24066963Speterstatic bool
241166124Srafan_nc_del_ext_name(TERMTYPE *tp, char *name, int token_type)
24250276Speter{
24350276Speter    int j;
24450276Speter    int first, last;
24550276Speter
24650276Speter    if ((first = _nc_find_ext_name(tp, name, token_type)) >= 0) {
24750276Speter	last = NUM_EXT_NAMES(tp) - 1;
24850276Speter	for (j = first; j < last; j++) {
24962449Speter	    tp->ext_Names[j] = tp->ext_Names[j + 1];
25050276Speter	}
25150276Speter	first = _nc_ext_data_index(tp, first, token_type);
25250276Speter	switch (token_type) {
25350276Speter	case BOOLEAN:
25450276Speter	    last = tp->num_Booleans - 1;
25550276Speter	    for (j = first; j < last; j++)
25662449Speter		tp->Booleans[j] = tp->Booleans[j + 1];
25750276Speter	    tp->ext_Booleans -= 1;
25850276Speter	    tp->num_Booleans -= 1;
25950276Speter	    break;
26050276Speter	case NUMBER:
26150276Speter	    last = tp->num_Numbers - 1;
26250276Speter	    for (j = first; j < last; j++)
26362449Speter		tp->Numbers[j] = tp->Numbers[j + 1];
26450276Speter	    tp->ext_Numbers -= 1;
26550276Speter	    tp->num_Numbers -= 1;
26650276Speter	    break;
26750276Speter	case STRING:
26850276Speter	    last = tp->num_Strings - 1;
26950276Speter	    for (j = first; j < last; j++)
27062449Speter		tp->Strings[j] = tp->Strings[j + 1];
27150276Speter	    tp->ext_Strings -= 1;
27250276Speter	    tp->num_Strings -= 1;
27350276Speter	    break;
27450276Speter	}
27566963Speter	return TRUE;
27650276Speter    }
27766963Speter    return FALSE;
27850276Speter}
27950276Speter
28050276Speter/*
28150276Speter * Adjust tables to insert an extended name, making room for new data.  The
28250276Speter * index into the corresponding data array is returned.
28350276Speter */
28462449Speterstatic int
285166124Srafan_nc_ins_ext_name(TERMTYPE *tp, char *name, int token_type)
28650276Speter{
28750276Speter    unsigned first = _nc_first_ext_name(tp, token_type);
28862449Speter    unsigned last = _nc_last_ext_name(tp, token_type);
28950276Speter    unsigned total = NUM_EXT_NAMES(tp) + 1;
29050276Speter    unsigned j, k;
29150276Speter
29250276Speter    for (j = first; j < last; j++) {
29350276Speter	int cmp = strcmp(name, tp->ext_Names[j]);
29450276Speter	if (cmp == 0)
29550276Speter	    /* already present */
296166124Srafan	    return _nc_ext_data_index(tp, (int) j, token_type);
29750276Speter	if (cmp < 0) {
29850276Speter	    break;
29950276Speter	}
30050276Speter    }
30150276Speter
30250276Speter    tp->ext_Names = typeRealloc(char *, total, tp->ext_Names);
30362449Speter    for (k = total - 1; k > j; k--)
30462449Speter	tp->ext_Names[k] = tp->ext_Names[k - 1];
30550276Speter    tp->ext_Names[j] = name;
306166124Srafan    j = _nc_ext_data_index(tp, (int) j, token_type);
30750276Speter
30850276Speter    switch (token_type) {
30950276Speter    case BOOLEAN:
31050276Speter	tp->ext_Booleans += 1;
31150276Speter	tp->num_Booleans += 1;
312166124Srafan	tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
31362449Speter	for (k = tp->num_Booleans - 1; k > j; k--)
31462449Speter	    tp->Booleans[k] = tp->Booleans[k - 1];
31550276Speter	break;
31650276Speter    case NUMBER:
31750276Speter	tp->ext_Numbers += 1;
31850276Speter	tp->num_Numbers += 1;
31950276Speter	tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers);
32062449Speter	for (k = tp->num_Numbers - 1; k > j; k--)
32162449Speter	    tp->Numbers[k] = tp->Numbers[k - 1];
32250276Speter	break;
32350276Speter    case STRING:
32450276Speter	tp->ext_Strings += 1;
32550276Speter	tp->num_Strings += 1;
32650276Speter	tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings);
32762449Speter	for (k = tp->num_Strings - 1; k > j; k--)
32862449Speter	    tp->Strings[k] = tp->Strings[k - 1];
32950276Speter	break;
33050276Speter    }
33150276Speter    return j;
33250276Speter}
33350276Speter
33450276Speter/*
33550276Speter * Look for strings that are marked cancelled, which happen to be the same name
33650276Speter * as a boolean or number.  We'll get this as a special case when we get a
33750276Speter * cancellation of a name that is inherited from another entry.
33850276Speter */
33962449Speterstatic void
340166124Srafanadjust_cancels(TERMTYPE *to, TERMTYPE *from)
34150276Speter{
34250276Speter    int first = to->ext_Booleans + to->ext_Numbers;
34362449Speter    int last = first + to->ext_Strings;
34450276Speter    int j, k;
34550276Speter
34662449Speter    for (j = first; j < last;) {
34750276Speter	char *name = to->ext_Names[j];
34850276Speter	unsigned j_str = to->num_Strings - first - to->ext_Strings;
34950276Speter
35050276Speter	if (to->Strings[j + j_str] == CANCELLED_STRING) {
35150276Speter	    if ((k = _nc_find_ext_name(from, to->ext_Names[j], BOOLEAN)) >= 0) {
35266963Speter		if (_nc_del_ext_name(to, name, STRING)
35366963Speter		    || _nc_del_ext_name(to, name, NUMBER)) {
35466963Speter		    k = _nc_ins_ext_name(to, name, BOOLEAN);
35566963Speter		    to->Booleans[k] = FALSE;
35666963Speter		} else {
35766963Speter		    j++;
35866963Speter		}
35962449Speter	    } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],
36066963Speter					      NUMBER)) >= 0) {
36166963Speter		if (_nc_del_ext_name(to, name, STRING)
36266963Speter		    || _nc_del_ext_name(to, name, BOOLEAN)) {
36366963Speter		    k = _nc_ins_ext_name(to, name, NUMBER);
36466963Speter		    to->Numbers[k] = CANCELLED_NUMERIC;
36566963Speter		} else {
36666963Speter		    j++;
36766963Speter		}
368184989Srafan	    } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],
369184989Srafan					      STRING)) >= 0) {
370184989Srafan		if (_nc_del_ext_name(to, name, NUMBER)
371184989Srafan		    || _nc_del_ext_name(to, name, BOOLEAN)) {
372184989Srafan		    k = _nc_ins_ext_name(to, name, STRING);
373184989Srafan		    to->Strings[k] = CANCELLED_STRING;
374184989Srafan		} else {
375184989Srafan		    j++;
376184989Srafan		}
377184989Srafan	    } else {
378184989Srafan		j++;
37950276Speter	    }
38050276Speter	} else {
38150276Speter	    j++;
38250276Speter	}
38350276Speter    }
38450276Speter}
38550276Speter
38676726SpeterNCURSES_EXPORT(void)
387166124Srafan_nc_align_termtype(TERMTYPE *to, TERMTYPE *from)
38850276Speter{
38950276Speter    int na = NUM_EXT_NAMES(to);
39050276Speter    int nb = NUM_EXT_NAMES(from);
39150276Speter    int n;
39250276Speter    bool same;
39350276Speter    char **ext_Names;
39450276Speter    int ext_Booleans, ext_Numbers, ext_Strings;
395166124Srafan    bool used_ext_Names = FALSE;
39650276Speter
39762449Speter    DEBUG(2, ("align_termtype to(%d:%s), from(%d:%s)", na, to->term_names,
39866963Speter	      nb, from->term_names));
39950276Speter
40050276Speter    if (na != 0 || nb != 0) {
40150276Speter	if ((na == nb)		/* check if the arrays are equivalent */
40262449Speter	    &&(to->ext_Booleans == from->ext_Booleans)
40362449Speter	    && (to->ext_Numbers == from->ext_Numbers)
40462449Speter	    && (to->ext_Strings == from->ext_Strings)) {
40550276Speter	    for (n = 0, same = TRUE; n < na; n++) {
40650276Speter		if (strcmp(to->ext_Names[n], from->ext_Names[n])) {
40750276Speter		    same = FALSE;
40850276Speter		    break;
40950276Speter		}
41050276Speter	    }
41150276Speter	    if (same)
41250276Speter		return;
41350276Speter	}
41450276Speter	/*
41550276Speter	 * This is where we pay for having a simple extension representation.
41650276Speter	 * Allocate a new ext_Names array and merge the two ext_Names arrays
41750276Speter	 * into it, updating to's counts for booleans, etc.  Fortunately we do
41850276Speter	 * this only for the terminfo compiler (tic) and comparer (infocmp).
41950276Speter	 */
42062449Speter	ext_Names = typeMalloc(char *, na + nb);
42150276Speter
42250276Speter	if (to->ext_Strings && (from->ext_Booleans + from->ext_Numbers))
42350276Speter	    adjust_cancels(to, from);
42450276Speter
42550276Speter	if (from->ext_Strings && (to->ext_Booleans + to->ext_Numbers))
42650276Speter	    adjust_cancels(from, to);
42750276Speter
42850276Speter	ext_Booleans = merge_names(ext_Names,
42966963Speter				   to->ext_Names,
43066963Speter				   to->ext_Booleans,
43166963Speter				   from->ext_Names,
43266963Speter				   from->ext_Booleans);
43362449Speter	ext_Numbers = merge_names(ext_Names + ext_Booleans,
43466963Speter				  to->ext_Names
43566963Speter				  + to->ext_Booleans,
43666963Speter				  to->ext_Numbers,
43766963Speter				  from->ext_Names
43866963Speter				  + from->ext_Booleans,
43966963Speter				  from->ext_Numbers);
44062449Speter	ext_Strings = merge_names(ext_Names + ext_Numbers + ext_Booleans,
44166963Speter				  to->ext_Names
44266963Speter				  + to->ext_Booleans
44366963Speter				  + to->ext_Numbers,
44466963Speter				  to->ext_Strings,
44566963Speter				  from->ext_Names
44666963Speter				  + from->ext_Booleans
44766963Speter				  + from->ext_Numbers,
44866963Speter				  from->ext_Strings);
44950276Speter	/*
45050276Speter	 * Now we must reallocate the Booleans, etc., to allow the data to be
45150276Speter	 * overlaid.
45250276Speter	 */
45350276Speter	if (na != (ext_Booleans + ext_Numbers + ext_Strings)) {
45450276Speter	    realign_data(to, ext_Names, ext_Booleans, ext_Numbers, ext_Strings);
45562449Speter	    FreeIfNeeded(to->ext_Names);
45650276Speter	    to->ext_Names = ext_Names;
45762449Speter	    DEBUG(2, ("realigned %d extended names for '%s' (to)",
45866963Speter		      NUM_EXT_NAMES(to), to->term_names));
459166124Srafan	    used_ext_Names = TRUE;
46050276Speter	}
46150276Speter	if (nb != (ext_Booleans + ext_Numbers + ext_Strings)) {
46250276Speter	    nb = (ext_Booleans + ext_Numbers + ext_Strings);
46350276Speter	    realign_data(from, ext_Names, ext_Booleans, ext_Numbers, ext_Strings);
46450276Speter	    from->ext_Names = typeRealloc(char *, nb, from->ext_Names);
46550276Speter	    memcpy(from->ext_Names, ext_Names, sizeof(char *) * nb);
46662449Speter	    DEBUG(2, ("realigned %d extended names for '%s' (from)",
46766963Speter		      NUM_EXT_NAMES(from), from->term_names));
46850276Speter	}
469166124Srafan	if (!used_ext_Names)
470166124Srafan	    free(ext_Names);
47150276Speter    }
47250276Speter}
47350276Speter#endif
47450276Speter
47576726SpeterNCURSES_EXPORT(void)
476166124Srafan_nc_copy_termtype(TERMTYPE *dst, TERMTYPE *src)
47750276Speter{
478166124Srafan    unsigned i;
47950276Speter
48062449Speter    *dst = *src;		/* ...to copy the sizes and string-tables */
481166124Srafan    dst->Booleans = typeMalloc(NCURSES_SBOOL, NUM_BOOLEANS(dst));
48262449Speter    dst->Numbers = typeMalloc(short, NUM_NUMBERS(dst));
48362449Speter    dst->Strings = typeMalloc(char *, NUM_STRINGS(dst));
48450276Speter
48550276Speter    /* FIXME: use memcpy for these and similar loops */
48662449Speter    for_each_boolean(i, dst)
48750276Speter	dst->Booleans[i] = src->Booleans[i];
48862449Speter    for_each_number(i, dst)
48950276Speter	dst->Numbers[i] = src->Numbers[i];
49062449Speter    for_each_string(i, dst)
49150276Speter	dst->Strings[i] = src->Strings[i];
49250276Speter
49350276Speter    /* FIXME: we probably should also copy str_table and ext_str_table,
49450276Speter     * but tic and infocmp are not written to exploit that (yet).
49550276Speter     */
49650276Speter
49750276Speter#if NCURSES_XNAMES
49850276Speter    if ((i = NUM_EXT_NAMES(src)) != 0) {
49950276Speter	dst->ext_Names = typeMalloc(char *, i);
50050276Speter	memcpy(dst->ext_Names, src->ext_Names, i * sizeof(char *));
50162449Speter    } else {
50262449Speter	dst->ext_Names = 0;
50350276Speter    }
50450276Speter#endif
50550276Speter
50650276Speter}
507