X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Falloc_ttype.c;h=4f9dae32561bd7241bb35a376e58a8a56ddc407b;hp=4a1b691382c86fb6551f9c2d8063342d7c3fb18e;hb=66dce3ce75bac445bd106da5322f1ec3fb1e56e4;hpb=5e1e572b71ae31a6071daa24e2460a68a6f1003c diff --git a/ncurses/tinfo/alloc_ttype.c b/ncurses/tinfo/alloc_ttype.c index 4a1b6913..4f9dae32 100644 --- a/ncurses/tinfo/alloc_ttype.c +++ b/ncurses/tinfo/alloc_ttype.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1999-2016,2017 Free Software Foundation, Inc. * + * Copyright 2018-2021,2022 Thomas E. Dickey * + * Copyright 1999-2016,2017 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 * @@ -42,7 +43,7 @@ #include -MODULE_ID("$Id: alloc_ttype.c,v 1.29 2017/04/09 23:15:34 tom Exp $") +MODULE_ID("$Id: alloc_ttype.c,v 1.43 2022/05/29 17:56:55 tom Exp $") #if NCURSES_XNAMES /* @@ -61,7 +62,7 @@ merge_names(char **dst, char **a, int na, char **b, int nb) } else if (cmp > 0) { dst[n++] = *b++; nb--; - } else if (cmp == 0) { + } else { dst[n++] = *a; a++, b++; na--, nb--; @@ -78,19 +79,27 @@ merge_names(char **dst, char **a, int na, char **b, int nb) } static bool -find_name(char **table, int length, char *name) +find_name(char **table, int item, int length, const char *name) { - while (length-- > 0) { - if (!strcmp(*table++, name)) { - DEBUG(4, ("found name '%s'", name)); - return TRUE; + int n; + int result = -1; + + for (n = item; n < length; ++n) { + if (!strcmp(table[n], name)) { + DEBUG(4, ("found name '%s' @%d", name, n)); + result = n; + break; } } - DEBUG(4, ("did not find name '%s'", name)); - return FALSE; + if (result < 0) { + DEBUG(4, ("did not find name '%s'", name)); + } + return (result >= 0); } #define EXTEND_NUM(num, ext) \ + DEBUG(4, ("extending " #num " from %d to %d", \ + to->num, (unsigned short) (to->num + (ext - to->ext)))); \ to->num = (unsigned short) (to->num + (ext - to->ext)) static void @@ -100,15 +109,29 @@ realign_data(TERMTYPE2 *to, char **ext_Names, int ext_Strings) { int n, m, base; - int limit = (to->ext_Booleans + to->ext_Numbers + to->ext_Strings); + int to_Booleans = to->ext_Booleans; + int to_Numbers = to->ext_Numbers; + int to_Strings = to->ext_Strings; + int to1, to2, from; + + DEBUG(4, ("realign_data %d/%d/%d vs %d/%d/%d", + ext_Booleans, + ext_Numbers, + ext_Strings, + to->ext_Booleans, + to->ext_Numbers, + to->ext_Strings)); if (to->ext_Booleans != ext_Booleans) { + to1 = 0; + to2 = to_Booleans + to1; + from = 0; EXTEND_NUM(num_Booleans, ext_Booleans); TYPE_REALLOC(NCURSES_SBOOL, 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])) { + if (find_name(to->ext_Names, to1, to2, ext_Names[m + from])) { to->Booleans[base + m] = to->Booleans[base + n--]; } else { to->Booleans[base + m] = FALSE; @@ -118,12 +141,15 @@ realign_data(TERMTYPE2 *to, char **ext_Names, } if (to->ext_Numbers != ext_Numbers) { + to1 = to_Booleans; + to2 = to_Numbers + to1; + from = ext_Booleans; EXTEND_NUM(num_Numbers, ext_Numbers); TYPE_REALLOC(NCURSES_INT2, 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])) { + if (find_name(to->ext_Names, to1, to2, ext_Names[m + from])) { to->Numbers[base + m] = to->Numbers[base + n--]; } else { to->Numbers[base + m] = ABSENT_NUMERIC; @@ -131,13 +157,17 @@ realign_data(TERMTYPE2 *to, char **ext_Names, } to->ext_Numbers = UShort(ext_Numbers); } + if (to->ext_Strings != ext_Strings) { + to1 = to_Booleans + to_Numbers; + to2 = to_Strings + to1; + from = ext_Booleans + ext_Numbers; EXTEND_NUM(num_Strings, ext_Strings); TYPE_REALLOC(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])) { + if (find_name(to->ext_Names, to1, to2, ext_Names[m + from])) { to->Strings[base + m] = to->Strings[base + n--]; } else { to->Strings[base + m] = ABSENT_STRING; @@ -347,6 +377,9 @@ adjust_cancels(TERMTYPE2 *to, TERMTYPE2 *from) int last = first + to->ext_Strings; int j, k; + DEBUG(3, (T_CALLED("adjust_cancels(%s), from(%s)"), + to ? NonNull(to->term_names) : "?", + from ? NonNull(from->term_names) : "?")); for (j = first; j < last;) { char *name = to->ext_Names[j]; int j_str = to->num_Strings - first - to->ext_Strings; @@ -383,19 +416,24 @@ adjust_cancels(TERMTYPE2 *to, TERMTYPE2 *from) j++; } } + DEBUG(3, (T_RETURN(""))); } NCURSES_EXPORT(void) _nc_align_termtype(TERMTYPE2 *to, TERMTYPE2 *from) { - int na = (int) NUM_EXT_NAMES(to); - int nb = (int) NUM_EXT_NAMES(from); + int na; + int nb; char **ext_Names; - DEBUG(2, ("align_termtype to(%d:%s), from(%d:%s)", na, to->term_names, - nb, from->term_names)); + na = to ? ((int) NUM_EXT_NAMES(to)) : 0; + nb = from ? ((int) NUM_EXT_NAMES(from)) : 0; - if (na != 0 || nb != 0) { + DEBUG(2, (T_CALLED("_nc_align_termtype to(%d:%s), from(%d:%s)"), + na, to ? NonNull(to->term_names) : "?", + nb, from ? NonNull(from->term_names) : "?")); + + if (to != NULL && from != NULL && (na != 0 || nb != 0)) { int ext_Booleans, ext_Numbers, ext_Strings; bool used_ext_Names = FALSE; @@ -412,11 +450,13 @@ _nc_align_termtype(TERMTYPE2 *to, TERMTYPE2 *from) break; } } - if (same) + if (same) { + DEBUG(2, (T_RETURN(""))); return; + } } /* - * This is where we pay for having a simple extension representation. + * 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). @@ -473,6 +513,7 @@ _nc_align_termtype(TERMTYPE2 *to, TERMTYPE2 *from) if (!used_ext_Names) free(ext_Names); } + DEBUG(2, (T_RETURN(""))); } #endif @@ -486,15 +527,16 @@ _nc_align_termtype(TERMTYPE2 *to, TERMTYPE2 *from) static void copy_termtype(TERMTYPE2 *dst, const TERMTYPE2 *src, int mode) { -#if NCURSES_XNAMES || NCURSES_EXT_NUMBERS unsigned i; -#endif + int pass; + char *new_table; #if NCURSES_EXT_NUMBERS short *oldptr = 0; int *newptr = 0; #endif - DEBUG(2, ("copy_termtype")); + DEBUG(2, (T_CALLED("copy_termtype(dst=%p, src=%p, mode=%d)"), (void *) + dst, (const void *) src, mode)); *dst = *src; /* ...to copy the sizes and string-tables */ TYPE_MALLOC(NCURSES_SBOOL, NUM_BOOLEANS(dst), dst->Booleans); @@ -507,6 +549,31 @@ copy_termtype(TERMTYPE2 *dst, const TERMTYPE2 *src, int mode) src->Strings, NUM_STRINGS(dst) * sizeof(dst->Strings[0])); + new_table = NULL; + for (pass = 0; pass < 2; ++pass) { + size_t str_size = 0; + if (pass) { + dst->term_names = new_table + str_size; + strcpy(dst->term_names + str_size, src->term_names); + } + str_size += strlen(src->term_names) + 1; + for (i = 0; i < STRCOUNT; ++i) { + if (VALID_STRING(src->Strings[i])) { + if (pass) { + strcpy(new_table + str_size, src->Strings[i]); + dst->Strings[i] = new_table + str_size; + } + str_size += strlen(src->Strings[i]) + 1; + } + } + if (pass) { + dst->str_table = new_table; + } else { + ++str_size; + new_table = malloc(str_size); + } + } + #if NCURSES_EXT_NUMBERS if ((mode & dstINT) == 0) { DEBUG(2, ("...convert int ->short")); @@ -550,36 +617,70 @@ copy_termtype(TERMTYPE2 *dst, const TERMTYPE2 *src, int mode) NUM_NUMBERS(dst) * sizeof(dst->Numbers[0])); #endif - /* 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) { TYPE_MALLOC(char *, i, dst->ext_Names); memcpy(dst->ext_Names, src->ext_Names, i * sizeof(char *)); + + new_table = NULL; + for (pass = 0; pass < 2; ++pass) { + size_t str_size = 0; + char *raw_data = src->ext_str_table; + if (raw_data != NULL) { + for (i = 0; i < src->ext_Strings; ++i) { + size_t skip = strlen(raw_data) + 1; + if (skip != 1) { + if (pass) { + strcpy(new_table + str_size, raw_data); + } + str_size += skip; + raw_data += skip; + } + } + } + for (i = 0; i < NUM_EXT_NAMES(dst); ++i) { + if (VALID_STRING(src->ext_Names[i])) { + if (pass) { + strcpy(new_table + str_size, src->ext_Names[i]); + dst->ext_Names[i] = new_table + str_size; + } + str_size += strlen(src->ext_Names[i]) + 1; + } + } + if (pass) { + dst->ext_str_table = new_table; + } else { + ++str_size; + new_table = calloc(str_size, 1); + } + } } else { dst->ext_Names = 0; } #endif + DEBUG(2, (T_RETURN(""))); } /* - * This entrypoint is used by tack. + * This entrypoint is used by tack 1.07 */ NCURSES_EXPORT(void) _nc_copy_termtype(TERMTYPE *dst, const TERMTYPE *src) { - DEBUG(2, ("_nc_copy_termtype...")); + DEBUG(2, (T_CALLED("_nc_copy_termtype(dst=%p, src=%p)"), (void *) dst, + (const void *) src)); copy_termtype((TERMTYPE2 *) dst, (const TERMTYPE2 *) src, 0); + DEBUG(2, (T_RETURN(""))); } #if NCURSES_EXT_NUMBERS NCURSES_EXPORT(void) _nc_copy_termtype2(TERMTYPE2 *dst, const TERMTYPE2 *src) { - DEBUG(2, ("_nc_copy_termtype2...")); + DEBUG(2, (T_CALLED("_nc_copy_termtype2(dst=%p, src=%p)"), (void *) dst, + (const void *) src)); copy_termtype(dst, src, srcINT | dstINT); + DEBUG(2, (T_RETURN(""))); } /* @@ -589,15 +690,9 @@ _nc_copy_termtype2(TERMTYPE2 *dst, const TERMTYPE2 *src) NCURSES_EXPORT(void) _nc_export_termtype2(TERMTYPE *dst, const TERMTYPE2 *src) { - DEBUG(2, ("_nc_export_termtype2...")); + DEBUG(2, (T_CALLED("_nc_export_termtype2(dst=%p, src=%p)"), (void *) + dst, (const void *) src)); copy_termtype((TERMTYPE2 *) dst, src, srcINT); -} - -/* FIXME - this will go away when conversion is complete */ -NCURSES_EXPORT(void) -_nc_import_termtype2(TERMTYPE2 *dst, const TERMTYPE *src) -{ - DEBUG(2, ("_nc_import_termtype2...")); - copy_termtype(dst, (const TERMTYPE2 *) src, dstINT); + DEBUG(2, (T_RETURN(""))); } #endif /* NCURSES_EXT_NUMBERS */