From 292968cf29abc10835415a6352607b38ce7c9cbd Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 1 Jan 2012 03:05:05 +0000 Subject: [PATCH] ncurses 5.9 - patch 20111231 + modify toe's report when -a and -s options are combined, to add a column showing which entries belong to a given database. + add -s option to toe, to sort its output. + modify progs/toe.c, simplifying use of db-iterator results to use caching improvements from 20111001 and 20111126. + correct generation of pc-files when ticlib or termlib options are given to rename the corresponding tic- or tinfo-libraries (report by Sven Joachim). --- NEWS | 12 +- aclocal.m4 | 14 +- configure | 10 +- dist.mk | 4 +- man/toe.1m | 13 +- misc/gen-pkgconfig.in | 6 +- progs/tic.c | 4 +- progs/toe.c | 331 +++++++++++++++++++++++++++++++----------- 8 files changed, 289 insertions(+), 105 deletions(-) diff --git a/NEWS b/NEWS index 2271f8bb..42eb7421 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.1835 2011/12/25 01:40:20 tom Exp $ +-- $Id: NEWS,v 1.1838 2012/01/01 00:18:49 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,16 @@ See the AUTHORS file for the corresponding full names. Changes through 1.9.9e did not credit all contributions; it is not possible to add this information. +20111231 + + modify toe's report when -a and -s options are combined, to add + a column showing which entries belong to a given database. + + add -s option to toe, to sort its output. + + modify progs/toe.c, simplifying use of db-iterator results to use + caching improvements from 20111001 and 20111126. + + correct generation of pc-files when ticlib or termlib options are + given to rename the corresponding tic- or tinfo-libraries (report + by Sven Joachim). + 20111224 + document a portability issue with tput, i.e., that scripts which work with ncurses may fail in other implementations that do no parameter diff --git a/aclocal.m4 b/aclocal.m4 index bfd3cee7..b5bfb49d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -28,7 +28,7 @@ dnl*************************************************************************** dnl dnl Author: Thomas E. Dickey 1995-on dnl -dnl $Id: aclocal.m4,v 1.596 2011/12/17 21:19:09 tom Exp $ +dnl $Id: aclocal.m4,v 1.599 2012/01/01 01:55:05 tom Exp $ dnl Macros used in NCURSES auto-configuration script. dnl dnl These macros are maintained separately from NCURSES. The copyright on @@ -5702,7 +5702,7 @@ if test "$cf_cv_sizechange" != no ; then fi ])dnl dnl --------------------------------------------------------------------------- -dnl CF_SRC_MODULES version: 24 updated: 2011/12/10 18:58:47 +dnl CF_SRC_MODULES version: 25 updated: 2011/12/31 15:32:02 dnl -------------- dnl For each parameter, test if the source-directory exists, and if it contains dnl a 'modules' file. If so, add to the list $cf_cv_src_modules which we'll @@ -5725,7 +5725,7 @@ else TEST_ARG2="-l${LIB_NAME}${DFT_ARG_SUFFIX} $TEST_ARG2" fi -PC_MODULES_TO_MAKE="ncurses" +PC_MODULES_TO_MAKE="ncurses${DFT_ARG_SUFFIX}" cf_cv_src_modules= for cf_dir in $1 do @@ -5764,7 +5764,7 @@ do TEST_ARGS="-l${cf_dir}${DFT_ARG_SUFFIX} $TEST_ARGS" TEST_ARG2="-l${cf_dir}${DFT_ARG_SUFFIX} $TEST_ARG2" fi - PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ${cf_dir}" + PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ${cf_dir}${DFT_ARG_SUFFIX}" fi fi done @@ -5793,12 +5793,12 @@ if test "x$cf_with_tests" != "xno" ; then fi test -z "$MAKE_TERMINFO" && SRC_SUBDIRS="$SRC_SUBDIRS misc" if test "$cf_with_cxx_binding" != no; then - PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ncurses++" + PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ncurses++${DFT_ARG_SUFFIX}" SRC_SUBDIRS="$SRC_SUBDIRS c++" fi -test "x$with_termlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE $TINFO_NAME" -test "x$with_ticlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE tic" +test "x$with_termlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE $TINFO_ARG_SUFFIX" +test "x$with_ticlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE $TICS_ARG_SUFFIX" AC_SUBST(PC_MODULES_TO_MAKE) diff --git a/configure b/configure index dc0fd84f..9ff7eb2f 100755 --- a/configure +++ b/configure @@ -20087,7 +20087,7 @@ else TEST_ARG2="-l${LIB_NAME}${DFT_ARG_SUFFIX} $TEST_ARG2" fi -PC_MODULES_TO_MAKE="ncurses" +PC_MODULES_TO_MAKE="ncurses${DFT_ARG_SUFFIX}" cf_cv_src_modules= for cf_dir in $modules_to_build do @@ -20134,7 +20134,7 @@ EOF TEST_ARGS="-l${cf_dir}${DFT_ARG_SUFFIX} $TEST_ARGS" TEST_ARG2="-l${cf_dir}${DFT_ARG_SUFFIX} $TEST_ARG2" fi - PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ${cf_dir}" + PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ${cf_dir}${DFT_ARG_SUFFIX}" fi fi done @@ -20158,12 +20158,12 @@ if test "x$cf_with_tests" != "xno" ; then fi test -z "$MAKE_TERMINFO" && SRC_SUBDIRS="$SRC_SUBDIRS misc" if test "$cf_with_cxx_binding" != no; then - PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ncurses++" + PC_MODULES_TO_MAKE="${PC_MODULES_TO_MAKE} ncurses++${DFT_ARG_SUFFIX}" SRC_SUBDIRS="$SRC_SUBDIRS c++" fi -test "x$with_termlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE $TINFO_NAME" -test "x$with_ticlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE tic" +test "x$with_termlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE $TINFO_ARG_SUFFIX" +test "x$with_ticlib" != xno && PC_MODULES_TO_MAKE="$PC_MODULES_TO_MAKE $TICS_ARG_SUFFIX" ADA_SUBDIRS= if test "x$cf_with_ada" = "xyes" && test "x$cf_cv_prog_gnat_correct" = xyes && test -f $srcdir/Ada95/Makefile.in; then diff --git a/dist.mk b/dist.mk index 04b50f36..ecbe6e8e 100644 --- a/dist.mk +++ b/dist.mk @@ -25,7 +25,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.849 2011/12/24 18:09:48 tom Exp $ +# $Id: dist.mk,v 1.850 2011/12/31 14:27:53 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -37,7 +37,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 5 NCURSES_MINOR = 9 -NCURSES_PATCH = 20111224 +NCURSES_PATCH = 20111231 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/man/toe.1m b/man/toe.1m index 9ef3b1a3..26af319b 100644 --- a/man/toe.1m +++ b/man/toe.1m @@ -26,14 +26,14 @@ .\" authorization. * .\"*************************************************************************** .\" -.\" $Id: toe.1m,v 1.24 2011/12/17 23:31:21 tom Exp $ +.\" $Id: toe.1m,v 1.26 2012/01/01 00:40:51 tom Exp $ .TH @TOE@ 1M "" .ds n 5 .ds d @TERMINFO@ .SH NAME \fB@TOE@\fR \- table of (terminfo) entries .SH SYNOPSIS -\fB@TOE@\fR [\fB\-v\fR[\fIn\fR]] [\fB\-ahuUV\fR] \fIfile...\fR +\fB@TOE@\fR [\fB\-v\fR[\fIn\fR]] [\fB\-ahsuUV\fR] \fIfile...\fR .br .SH DESCRIPTION .PP @@ -52,6 +52,15 @@ There are other options intended for use by terminfo file maintainers: \fB\-a\fR report on all of the terminal databases which ncurses would search, rather than only the first one that it finds. +.IP +If the \fB\-s\fR is also given, \fB@TOE@\fR +adds a column to the report, +showing (like \fBconflict\fP(1)) which entries which +belong to a given terminal database. +An "*" marks entries which differ, and "+" marks equivalent entries. +.TP +\fB\-s\fR +sort the output by the entry names. .TP \fB\-u\fR \fIfile\fR says to write a report to the standard output, diff --git a/misc/gen-pkgconfig.in b/misc/gen-pkgconfig.in index f58ecf7e..56b170f1 100644 --- a/misc/gen-pkgconfig.in +++ b/misc/gen-pkgconfig.in @@ -1,5 +1,5 @@ #!@SHELL@ -# $Id: gen-pkgconfig.in,v 1.12 2011/12/10 18:39:20 tom Exp $ +# $Id: gen-pkgconfig.in,v 1.14 2012/01/01 01:48:23 tom Exp $ ############################################################################## # Copyright (c) 2009-2010,2011 Free Software Foundation, Inc. # # # @@ -77,7 +77,7 @@ fi for name in @PC_MODULES_TO_MAKE@ do - name="${name}@DFT_ARG_SUFFIX@" + name="${name}" desc="ncurses @NCURSES_MAJOR@.@NCURSES_MINOR@" reqs= @@ -94,7 +94,7 @@ do desc="$desc add-on library" fi - if test $name != $SUB_LIBRARY ; then + if test $name != $SUB_LIBRARY && test $SUB_LIBRARY != $MAIN_LIBRARY ; then if test $name != $TINFO_NAME ; then test -n "$reqs" && reqs="$reqs, " reqs="${reqs}${SUB_LIBRARY}" diff --git a/progs/tic.c b/progs/tic.c index 1b0aea85..04ab3e52 100644 --- a/progs/tic.c +++ b/progs/tic.c @@ -45,7 +45,7 @@ #include #include -MODULE_ID("$Id: tic.c,v 1.156 2011/11/27 01:32:06 tom Exp $") +MODULE_ID("$Id: tic.c,v 1.157 2011/12/31 21:11:59 tom Exp $") const char *_nc_progname = "tic"; @@ -178,7 +178,7 @@ usage(void) #define L_BRACE '{' #define R_BRACE '}' -#define S_QUOTE '\''; +#define S_QUOTE '\'' static void write_it(ENTRY * ep) diff --git a/progs/toe.c b/progs/toe.c index 3d35fcd3..34216e95 100644 --- a/progs/toe.c +++ b/progs/toe.c @@ -44,12 +44,23 @@ #include #endif -MODULE_ID("$Id: toe.c,v 1.58 2011/08/07 18:36:31 tom Exp $") +MODULE_ID("$Id: toe.c,v 1.64 2012/01/01 02:56:17 tom Exp $") #define isDotname(name) (!strcmp(name, ".") || !strcmp(name, "..")) +typedef struct { + int db_index; + unsigned long checksum; + char *term_name; + char *description; +} TERMDATA; + const char *_nc_progname; +static TERMDATA *ptr_termdata; /* array of terminal data */ +static size_t use_termdata; /* actual usage in ptr_termdata[] */ +static size_t len_termdata; /* allocated size of ptr_termdata[] */ + #if NO_LEAKS #undef ExitProgram static void ExitProgram(int code) GCC_NORETURN; @@ -70,6 +81,148 @@ failed(const char *msg) ExitProgram(EXIT_FAILURE); } +static char * +strmalloc(const char *value) +{ + char *result = strdup(value); + if (result == 0) { + failed("strmalloc"); + } + return result; +} + +static TERMDATA * +new_termdata(void) +{ + size_t want = use_termdata + 1; + + if (want >= len_termdata) { + len_termdata = (2 * want) + 10; + ptr_termdata = typeRealloc(TERMDATA, len_termdata, ptr_termdata); + } + + return ptr_termdata + use_termdata++; +} + +static int +compare_termdata(const void *a, const void *b) +{ + const TERMDATA *p = (const TERMDATA *) a; + const TERMDATA *q = (const TERMDATA *) b; + int result = strcmp(p->term_name, q->term_name); + + if (result == 0) { + result = (p->db_index - q->db_index); + } + return result; +} + +/* + * Sort the array of TERMDATA and print it. If more than one database is being + * reported, add a column to show which database has a given entry. + */ +static void +show_termdata(int eargc, char **eargv) +{ + int j, k; + size_t n; + + if (use_termdata) { + if (eargc > 1) { + for (j = 0; j < eargc; ++j) { + for (k = 0; k <= j; ++k) { + printf("--"); + } + printf("> "); + printf("%s\n", eargv[j]); + } + } + if (use_termdata > 1) + qsort(ptr_termdata, use_termdata, sizeof(TERMDATA), compare_termdata); + for (n = 0; n < use_termdata; ++n) { + + /* + * If there is more than one database, show how they differ. + */ + if (eargc > 1) { + unsigned long check = 0; + k = 0; + for (;;) { + for (; k < ptr_termdata[n].db_index; ++k) { + printf("--"); + } + + /* + * If this is the first entry, or its checksum differs + * from the first entry's checksum, print "*". Otherwise + * it looks enough like a duplicate to print "+". + */ + printf("%c-", ((check == 0 + || (check != ptr_termdata[n].checksum)) + ? '*' + : '+')); + check = ptr_termdata[n].checksum; + + ++k; + if ((n + 1) >= use_termdata + || strcmp(ptr_termdata[n].term_name, + ptr_termdata[n + 1].term_name)) { + break; + } + ++n; + } + for (; k < eargc; ++k) { + printf("--"); + } + printf(":\t"); + } + + (void) printf("%-10s\t%s\n", + ptr_termdata[n].term_name, + ptr_termdata[n].description); + } + } +} + +static void +free_termdata(void) +{ + if (ptr_termdata != 0) { + while (use_termdata != 0) { + --use_termdata; + free(ptr_termdata[use_termdata].term_name); + free(ptr_termdata[use_termdata].description); + } + free(ptr_termdata); + ptr_termdata = 0; + } + use_termdata = 0; + len_termdata = 0; +} + +static char ** +allocArgv(size_t count) +{ + char **result = typeCalloc(char *, count + 1); + if (result == 0) + failed("realloc eargv"); + + assert(result != 0); + return result; +} + +static void +freeArgv(char **argv) +{ + if (argv) { + int count = 0; + while (argv[count]) { + free(argv[count++]); + } + free(argv); + } +} + #if USE_HASHED_DB static bool make_db_name(char *dst, const char *src, unsigned limit) @@ -93,51 +246,80 @@ make_db_name(char *dst, const char *src, unsigned limit) } #endif -static bool -is_database(const char *path) +typedef void (DescHook) (int /* db_index */ , + int /* db_limit */ , + const char * /* term_name */ , + TERMTYPE * /* term */ ); + +static const char * +term_description(TERMTYPE *tp) { - bool result = FALSE; -#if USE_DATABASE - if (_nc_is_dir_path(path) && access(path, R_OK | X_OK) == 0) { - result = TRUE; + const char *desc; + + if ((desc = strrchr(tp->term_names, '|')) == 0 || *++desc == '\0') + desc = "(No description)"; + + return desc; +} + +/* display a description for the type */ +static void +deschook(int db_index, int db_limit, const char *term_name, TERMTYPE *tp) +{ + (void) db_index; + (void) db_limit; + (void) printf("%-10s\t%s\n", term_name, term_description(tp)); +} + +static unsigned long +string_sum(const char *value) +{ + unsigned long result = 0; + + if ((intptr_t) value == (intptr_t) (-1)) { + result = ~result; + } else if (value) { + while (*value) { + result += UChar(*value); + ++value; + } } -#endif -#if USE_TERMCAP - if (_nc_is_file_path(path) && access(path, R_OK) == 0) { - result = TRUE; + return result; +} + +static unsigned long +checksum_of(TERMTYPE *tp) +{ + unsigned long result = string_sum(tp->term_names); + unsigned i; + + for (i = 0; i < NUM_BOOLEANS(tp); i++) { + result += (tp->Booleans[i]); } -#endif -#if USE_HASHED_DB - if (!result) { - char filename[PATH_MAX]; - if (_nc_is_file_path(path) && access(path, R_OK) == 0) { - result = TRUE; - } else if (make_db_name(filename, path, sizeof(filename))) { - if (_nc_is_file_path(filename) && access(filename, R_OK) == 0) { - result = TRUE; - } - } + for (i = 0; i < NUM_NUMBERS(tp); i++) { + result += (tp->Numbers[i]); + } + for (i = 0; i < NUM_STRINGS(tp); i++) { + result += string_sum(tp->Strings[i]); } -#endif return result; } +/* collect data, to sort before display */ static void -deschook(const char *cn, TERMTYPE *tp) -/* display a description for the type */ +sorthook(int db_index, int db_limit, const char *term_name, TERMTYPE *tp) { - const char *desc; + TERMDATA *data = new_termdata(); - if ((desc = strrchr(tp->term_names, '|')) == 0 || *++desc == '\0') - desc = "(No description)"; - - (void) printf("%-10s\t%s\n", cn, desc); + data->db_index = db_index; + data->checksum = ((db_limit > 1) ? checksum_of(tp) : 0); + data->term_name = strmalloc(term_name); + data->description = strmalloc(term_description(tp)); } #if USE_TERMCAP static void -show_termcap(char *buffer, - void (*hook) (const char *, TERMTYPE *tp)) +show_termcap(int db_index, int db_limit, char *buffer, DescHook hook) { TERMTYPE data; char *next = strchr(buffer, ':'); @@ -151,10 +333,11 @@ show_termcap(char *buffer, if (last) ++last; - data.term_names = strdup(buffer); + memset(&data, 0, sizeof(data)); + data.term_names = strmalloc(buffer); while ((next = strtok(list, "|")) != 0) { if (next != last) - hook(next, &data); + hook(db_index, db_limit, next, &data); list = 0; } free(data.term_names); @@ -164,7 +347,7 @@ show_termcap(char *buffer, static int typelist(int eargc, char *eargv[], bool verbosity, - void (*hook) (const char *, TERMTYPE *tp)) + DescHook hook) /* apply a function to each entry in given terminfo directories */ { int i; @@ -237,7 +420,7 @@ typelist(int eargc, char *eargv[], cn = _nc_first_name(lterm.term_names); if (!strcmp(cn, name_2)) { /* apply the selected hook function */ - (*hook) (cn, <erm); + hook(i, eargc, cn, <erm); } _nc_free_termtype(<erm); } @@ -273,7 +456,7 @@ typelist(int eargc, char *eargv[], /* only visit things once, by primary name */ cn = _nc_first_name(lterm.term_names); /* apply the selected hook function */ - (*hook) (cn, <erm); + hook(i, eargc, cn, <erm); _nc_free_termtype(<erm); } } @@ -300,10 +483,10 @@ typelist(int eargc, char *eargv[], db_array[1] = 0; if (cgetfirst(&buffer, db_array) > 0) { - show_termcap(buffer, hook); + show_termcap(i, eargc, buffer, hook); free(buffer); while (cgetnext(&buffer, db_array) > 0) { - show_termcap(buffer, hook); + show_termcap(i, eargc, buffer, hook); free(buffer); } cgetclose(); @@ -325,7 +508,7 @@ typelist(int eargc, char *eargv[], continue; if (isspace(*buffer)) continue; - show_termcap(buffer, hook); + show_termcap(i, eargc, buffer, hook); } fclose(fp); } @@ -334,13 +517,18 @@ typelist(int eargc, char *eargv[], #endif } + if (hook == sorthook) { + show_termdata(eargc, eargv); + free_termdata(); + } + return (EXIT_SUCCESS); } static void usage(void) { - (void) fprintf(stderr, "usage: %s [-ahuUV] [-v n] [file...]\n", _nc_progname); + (void) fprintf(stderr, "usage: %s [-ahsuUV] [-v n] [file...]\n", _nc_progname); ExitProgram(EXIT_FAILURE); } @@ -356,10 +544,11 @@ main(int argc, char *argv[]) int code; int this_opt, last_opt = '?'; unsigned v_opt = 0; + DescHook *hook = deschook; _nc_progname = _nc_rootname(argv[0]); - while ((this_opt = getopt(argc, argv, "0123456789ahu:vU:V")) != -1) { + while ((this_opt = getopt(argc, argv, "0123456789ahsu:vU:V")) != -1) { /* handle optional parameter */ if (isdigit(this_opt)) { switch (last_opt) { @@ -383,6 +572,9 @@ main(int argc, char *argv[]) case 'h': header = TRUE; break; + case 's': + hook = sorthook; + break; case 'u': direct_dependencies = TRUE; report_file = optarg; @@ -465,7 +657,7 @@ main(int argc, char *argv[]) * If we get this far, user wants a simple terminal type listing. */ if (optind < argc) { - code = typelist(argc - optind, argv + optind, header, deschook); + code = typelist(argc - optind, argv + optind, header, hook); } else if (all_dirs) { DBDIRS state; int offset; @@ -475,64 +667,37 @@ main(int argc, char *argv[]) code = EXIT_FAILURE; for (pass = 0; pass < 2; ++pass) { - unsigned count = 0; + size_t count = 0; _nc_first_db(&state, &offset); while ((path = _nc_next_db(&state, &offset)) != 0) { - if (!is_database(path)) { - ; - } else if (eargv != 0) { - unsigned n; - int found = FALSE; - - /* eliminate duplicates */ - for (n = 0; n < count; ++n) { - if (!strcmp(path, eargv[n])) { - found = TRUE; - break; - } - } - if (!found) { - eargv[count] = strdup(path); - ++count; - } - } else { - ++count; + if (pass) { + eargv[count] = strmalloc(path); } + ++count; } if (!pass) { - eargv = typeCalloc(char *, count + 1); - if (eargv == 0) - failed("realloc eargv"); - - assert(eargv != 0); + eargv = allocArgv(count); } else { - code = typelist((int) count, eargv, header, deschook); - while (count-- > 0) - free(eargv[count]); - free(eargv); + code = typelist((int) count, eargv, header, hook); + freeArgv(eargv); } } } else { DBDIRS state; int offset; const char *path; - char *eargv[3]; - int count = 0; + char **eargv = allocArgv(2); + size_t count = 0; _nc_first_db(&state, &offset); - while ((path = _nc_next_db(&state, &offset)) != 0) { - if (is_database(path)) { - eargv[count++] = strdup(path); - break; - } + if ((path = _nc_next_db(&state, &offset)) != 0) { + eargv[count++] = strmalloc(path); } - eargv[count] = 0; - code = typelist(count, eargv, header, deschook); + code = typelist((int) count, eargv, header, hook); - while (count-- > 0) - free(eargv[count]); + freeArgv(eargv); } _nc_last_db(); -- 2.44.0