From af4c589f0c605e1a1dd3825678a0b1a97df02d37 Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 2 Oct 2011 00:58:34 +0000 Subject: [PATCH 1/1] ncurses 5.9 - patch 20111001 + modify tic "-K" option to only set the strict-flag rather than force source-output. That allows the same flag to control the parser for input and output of termcap source. + modify _nc_getent() to ignore backslash at the end of a comment line, making it consistent with ncurses' parser. + restore a special-case check for directory needed to make termcap text files load as if they were databases (cf: 20110924). + modify tic's resolution/collision checking to attempt to remove the conflicting alias from the second entry in the pair, which is normally following in the source file. Also improved the warning message to make it simpler to see which alias is the problem. + improve performance of the database iterator by caching search-list. --- NEWS | 16 +- dist.mk | 4 +- man/tic.1m | 8 +- ncurses/tinfo/comp_parse.c | 109 ++++++++-- ncurses/tinfo/db_iterator.c | 391 ++++++++++++++++++++++++----------- ncurses/tinfo/lib_data.c | 4 +- ncurses/tinfo/lib_termcap.c | 4 +- ncurses/tinfo/read_entry.c | 41 ++-- ncurses/tinfo/read_termcap.c | 23 ++- progs/tic.c | 7 +- 10 files changed, 438 insertions(+), 169 deletions(-) diff --git a/NEWS b/NEWS index 0d066dd3..ad2572e8 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.1789 2011/09/24 23:49:30 tom Exp $ +-- $Id: NEWS,v 1.1795 2011/09/26 23:48:17 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,20 @@ 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. +20111001 + + modify tic "-K" option to only set the strict-flag rather than force + source-output. That allows the same flag to control the parser for + input and output of termcap source. + + modify _nc_getent() to ignore backslash at the end of a comment line, + making it consistent with ncurses' parser. + + restore a special-case check for directory needed to make termcap + text files load as if they were databases (cf: 20110924). + + modify tic's resolution/collision checking to attempt to remove the + conflicting alias from the second entry in the pair, which is + normally following in the source file. Also improved the warning + message to make it simpler to see which alias is the problem. + + improve performance of the database iterator by caching search-list. + 20110925 + add a missing "else" in changes to _nc_read_tic_entry(). diff --git a/dist.mk b/dist.mk index 76e8469f..9ba5fab1 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.836 2011/09/24 23:48:26 tom Exp $ +# $Id: dist.mk,v 1.837 2011/09/25 12:41:00 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 = 20110925 +NCURSES_PATCH = 20111001 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/man/tic.1m b/man/tic.1m index 38cb19c0..36b54314 100644 --- a/man/tic.1m +++ b/man/tic.1m @@ -26,7 +26,7 @@ .\" authorization. * .\"*************************************************************************** .\" -.\" $Id: tic.1m,v 1.49 2011/08/06 17:49:46 tom Exp $ +.\" $Id: tic.1m,v 1.50 2011/09/26 23:59:40 tom Exp $ .TH @TIC@ 1M "" .ds n 5 .ds d @TERMINFO@ @@ -108,7 +108,7 @@ that are not translatable are left in the entry under their terminfo names but commented out with two preceding dots. The actual format used incorporates some improvements for escaped characters from terminfo format. -For a stricter BSD-compatible translation, use the \fB\-K\fR option. +For a stricter BSD-compatible translation, add the \fB\-K\fR option. .TP \fB\-c\fR tells \fBtic\fP to only check \fIfile\fR for errors, including syntax problems and @@ -147,6 +147,10 @@ rather than their decimal equivalents. \fB\-I\fR Force source translation to terminfo format. .TP +\fB\-K\fR +Suppress some longstanding ncurses extensions to termcap format, +e.g., "\\s" for space. +.TP \fB\-L\fR Force source translation to terminfo format using the long C variable names listed in <\fBterm.h\fR> diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c index 95a71ed0..a1f9f4a8 100644 --- a/ncurses/tinfo/comp_parse.c +++ b/ncurses/tinfo/comp_parse.c @@ -47,7 +47,7 @@ #include -MODULE_ID("$Id: comp_parse.c,v 1.75 2011/08/13 19:37:17 tom Exp $") +MODULE_ID("$Id: comp_parse.c,v 1.77 2011/10/01 22:43:51 tom Exp $") static void sanity_check2(TERMTYPE *, bool); NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2; @@ -103,9 +103,8 @@ skip_index(char *name) } #endif -NCURSES_EXPORT(bool) -_nc_entry_match(char *n1, char *n2) -/* do any of the aliases in a pair of terminal names match? */ +static bool +check_collisions(char *n1, char *n2, int counter) { char *pstart, *qstart, *pend, *qend; char nc1[MAX_NAME_SIZE + 2]; @@ -121,15 +120,91 @@ _nc_entry_match(char *n1, char *n2) } #endif - for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1) - for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1) + for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1) { + for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1) { if ((pend - pstart == qend - qstart) - && memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) + && memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) { + if (counter > 0) + (void) fprintf(stderr, "Name collision '%.*s' between\n", + (int) (pend - pstart), pstart); return (TRUE); + } + } + } return (FALSE); } +static char * +next_name(char *name) +{ + if (*name != '\0') + ++name; + return name; +} + +static char * +name_ending(char *name) +{ + if (*name == '\0') { + name = 0; + } else { + while (*name != '\0' && *name != '|') + ++name; + } + return name; +} + +/* + * Essentially, find the conflict reported in check_collisions() and remove + * it from the second name, unless that happens to be the last alias. + */ +static bool +remove_collision(char *n1, char *n2) +{ + char *p1 = n1; + char *p2 = n2; + char *pstart, *qstart, *pend, *qend; + bool removed = FALSE; + +#if USE_TERMCAP && NCURSES_XNAMES + if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) { + p1 = n1 = skip_index(n1); + p2 = n2 = skip_index(n2); + } +#else + (void) p1; +#endif + + for (pstart = n1; (pend = name_ending(pstart)); pstart = next_name(pend)) { + for (qstart = n2; (qend = name_ending(qstart)); qstart = next_name(qend)) { + if ((pend - pstart == qend - qstart) + && memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) { + if (qstart != p2 || *qend == '|') { + if (*qend == '|') + ++qend; + while ((*qstart++ = *qend++) != '\0') ; + fprintf(stderr, "...now\t%s\n", p2); + } else { + fprintf(stderr, "Cannot remove alias '%.*s'\n", + (int) (qend - qstart), qstart); + } + removed = TRUE; + break; + } + } + } + + return removed; +} + +/* do any of the aliases in a pair of terminal names match? */ +NCURSES_EXPORT(bool) +_nc_entry_match(char *n1, char *n2) +{ + return check_collisions(n1, n2, 0); +} + /**************************************************************************** * * Entry compiler and resolution logic @@ -215,19 +290,19 @@ _nc_resolve_uses2(bool fullresolve, bool literal) for_entry_list(rp) { if (qp > rp - && _nc_entry_match(qp->tterm.term_names, rp->tterm.term_names)) { - matchcount++; - if (matchcount == 1) { - (void) fprintf(stderr, "Name collision between %s", - _nc_first_name(qp->tterm.term_names)); - multiples++; + && check_collisions(qp->tterm.term_names, + rp->tterm.term_names, + matchcount + 1)) { + if (!matchcount++) { + (void) fprintf(stderr, "\t%s\n", rp->tterm.term_names); + } + (void) fprintf(stderr, "and\t%s\n", qp->tterm.term_names); + if (!remove_collision(rp->tterm.term_names, + qp->tterm.term_names)) { + ++multiples; } - if (matchcount >= 1) - (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names)); } } - if (matchcount >= 1) - (void) putc('\n', stderr); } if (multiples > 0) return (FALSE); diff --git a/ncurses/tinfo/db_iterator.c b/ncurses/tinfo/db_iterator.c index eec2d4f8..f7e4d606 100644 --- a/ncurses/tinfo/db_iterator.c +++ b/ncurses/tinfo/db_iterator.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2006-2007,2010 Free Software Foundation, Inc. * + * Copyright (c) 2006-2010,2011 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 * @@ -36,14 +36,143 @@ #include +#include #include -MODULE_ID("$Id: db_iterator.c,v 1.10 2011/09/24 23:44:58 tom Exp $") +#if USE_HASHED_DB +#include +#endif + +MODULE_ID("$Id: db_iterator.c,v 1.18 2011/09/26 09:52:00 tom Exp $") #define HaveTicDirectory _nc_globals.have_tic_directory #define KeepTicDirectory _nc_globals.keep_tic_directory #define TicDirectory _nc_globals.tic_directory +/* + * FIXME: need a no-leaks entrypoint. + */ +static char *my_blob; /* string-heap for my_list[] */ +static char **my_list; /* distinct places to look for data */ +static int my_size; /* length of my_list[] */ +static time_t my_time; /* cache last updated */ +static struct { + const char *name; + char *value; +} my_vars[dbdLAST]; + +static void +add_to_blob(const char *text) +{ + if (*text != '\0') { + char *last = my_blob + strlen(my_blob); + if (last != my_blob) + *last++ = ':'; + strcpy(last, text); + } +} + +static bool +check_existence(const char *name, struct stat *sb) +{ + bool result = FALSE; + + if (stat(name, sb) == 0 && sb->st_size) { + result = TRUE; + } +#if USE_HASHED_DB + else if (strlen(name) < PATH_MAX - sizeof(DBM_SUFFIX)) { + char temp[PATH_MAX]; + sprintf(temp, "%s%s", name, DBM_SUFFIX); + if (stat(temp, sb) == 0 && sb->st_size) { + result = TRUE; + } + } +#endif + + return result; +} + +/* + * Store the latest value of an environment variable in my_vars[] so we can + * detect if one changes, invalidating the cached search-list. + */ +static bool +update_getenv(const char *name, DBDIRS which) +{ + bool result = FALSE; + char *value = getenv(name); + + if (which < dbdLAST) { + if (my_vars[which].name == 0 || strcmp(my_vars[which].name, name)) { + FreeIfNeeded(my_vars[which].value); + my_vars[which].name = name; + my_vars[which].value = value; + result = TRUE; + } else if ((my_vars[which].value != 0) ^ (value != 0)) { + FreeIfNeeded(my_vars[which].value); + my_vars[which].value = value; + result = TRUE; + } else if (value != 0 && strcmp(value, my_vars[which].value)) { + FreeIfNeeded(my_vars[which].value); + my_vars[which].value = value; + result = TRUE; + } + } + return result; +} + +static char * +cache_getenv(const char *name, DBDIRS which) +{ + char *result = 0; + + (void) update_getenv(name, which); + if (which < dbdLAST) { + result = my_vars[which].value; + } + return result; +} + +/* + * The cache expires if at least a second has passed since the initial lookup, + * or if one of the environment variables changed. + * + * Only a few applications use multiple lookups of terminal entries, seems that + * aside from bulk I/O such as tic and toe, that leaves interactive programs + * which should not be modifying the terminal databases in a way that would + * invalidate the search-list. + * + * The "1-second" is to allow for user-directed changes outside the program. + */ +static bool +cache_expired(void) +{ + bool result = FALSE; + time_t now = time((time_t *) 0); + + if (now > my_time) { + result = TRUE; + } else { + DBDIRS n; + for (n = 0; n < dbdLAST; ++n) { + if (my_vars[n].name != 0 + && update_getenv(my_vars[n].name, n)) { + result = TRUE; + break; + } + } + } + return result; +} + +static void +free_cache(void) +{ + FreeAndNull(my_blob); + FreeAndNull(my_list); +} + /* * Record the "official" location of the terminfo directory, according to * the place where we're writing to, or the normal default, if not. @@ -51,6 +180,7 @@ MODULE_ID("$Id: db_iterator.c,v 1.10 2011/09/24 23:44:58 tom Exp $") NCURSES_EXPORT(const char *) _nc_tic_dir(const char *path) { + T(("_nc_tic_dir %s", NonNull(path))); if (!KeepTicDirectory) { if (path != 0) { TicDirectory = path; @@ -76,62 +206,17 @@ _nc_keep_tic_dir(const char *path) KeepTicDirectory = TRUE; } -/* - * Process the list of :-separated directories, looking for the terminal type. - * We don't use strtok because it does not show us empty tokens. - */ -#define ThisDbList _nc_globals.dbi_list -#define ThisDbSize _nc_globals.dbi_size - /* * Cleanup. */ NCURSES_EXPORT(void) _nc_last_db(void) { - if (ThisDbList != 0) { - FreeAndNull(ThisDbList); + if (my_blob != 0 && cache_expired()) { + free_cache(); } - ThisDbSize = 0; } -/* The TERMINFO_DIRS value, if defined by the configure script, begins with a - * ":", which will be interpreted as TERMINFO. - */ -static const char * -next_list_item(const char *source, int *offset) -{ - if (source != 0) { - FreeIfNeeded(ThisDbList); - ThisDbList = strdup(source); - ThisDbSize = (int) strlen(source); - } - - if (ThisDbList != 0 && ThisDbSize && *offset < ThisDbSize) { - static char system_db[] = TERMINFO; - char *result = ThisDbList + *offset; - char *marker = strchr(result, NCURSES_PATHSEP); - - /* - * Put a null on the marker if a separator was found. Set the offset - * to the next position after the marker so we can call this function - * again, using the data at the offset. - */ - if (marker == 0) { - *offset += (int) strlen(result); - } else { - *marker++ = 0; - *offset = (int) (marker - ThisDbList); - } - if (*result == 0 && result != (ThisDbList + ThisDbSize)) - result = system_db; - return result; - } - return 0; -} - -#define NEXT_DBD(var, offset) next_list_item((*offset == 0) ? var : 0, offset) - /* * This is a simple iterator which allows the caller to step through the * possible locations for a terminfo directory. ncurses uses this to find @@ -141,85 +226,157 @@ NCURSES_EXPORT(const char *) _nc_next_db(DBDIRS * state, int *offset) { const char *result; - char *envp; - - while (*state < dbdLAST) { - DBDIRS next = (DBDIRS) ((int) (*state) + 1); + (void) offset; + if ((int) *state < my_size + && my_list != 0 + && my_list[*state] != 0) { + result = my_list[*state]; + (*state)++; + } else { result = 0; + } + if (result != 0) { + T(("_nc_next_db %d %s", *state, result)); + } + return result; +} + +NCURSES_EXPORT(void) +_nc_first_db(DBDIRS * state, int *offset) +{ + *state = dbdTIC; + *offset = 0; + + T(("_nc_first_db")); + + /* build a blob containing all of the strings we will use for a lookup + * table. + */ + if (my_blob == 0) { + size_t blobsize = 0; + const char *values[dbdLAST]; + struct stat *my_stat; + int j, k; + + for (j = 0; j < dbdLAST; ++j) + values[j] = 0; + + /* + * This is the first item in the list, and is used only when tic is + * writing to the database, as a performance improvement. + */ + values[dbdTIC] = TicDirectory; - switch (*state) { - case dbdTIC: - if (HaveTicDirectory) - result = _nc_tic_dir(0); - break; #if USE_DATABASE - case dbdEnvOnce: - if (use_terminfo_vars()) { - if ((envp = getenv("TERMINFO")) != 0) - result = _nc_tic_dir(envp); - } - break; - case dbdHome: - if (use_terminfo_vars()) { - result = _nc_home_terminfo(); - } - break; - case dbdEnvList: - if (use_terminfo_vars()) { - if ((result = NEXT_DBD(getenv("TERMINFO_DIRS"), offset)) != 0) - next = *state; - } - break; - case dbdCfgList: #ifdef TERMINFO_DIRS - if ((result = NEXT_DBD(TERMINFO_DIRS, offset)) != 0) - next = *state; + values[dbdCfgList] = TERMINFO_DIRS; +#endif +#ifdef TERMINFO + values[dbdCfgOnce] = TERMINFO; #endif - break; - case dbdCfgOnce: -#ifndef TERMINFO_DIRS - result = TERMINFO; #endif - break; -#endif /* USE_DATABASE */ + #if USE_TERMCAP - case dbdEnvOnce2: - if (use_terminfo_vars()) { - if ((envp = getenv("TERMCAP")) != 0) - result = _nc_tic_dir(envp); - } - break; - case dbdEnvList2: - if (use_terminfo_vars()) { - if ((result = NEXT_DBD(getenv("TERMPATH"), offset)) != 0) - next = *state; - } - break; - case dbdCfgList2: - if ((result = NEXT_DBD(TERMPATH, offset)) != 0) - next = *state; - break; + values[dbdCfgList2] = TERMPATH; +#endif + + if (use_terminfo_vars()) { +#if USE_DATABASE + values[dbdEnvOnce] = cache_getenv("TERMINFO", dbdEnvOnce); + values[dbdHome] = _nc_home_terminfo(); + (void) cache_getenv("HOME", dbdHome); + values[dbdEnvList] = cache_getenv("TERMINFO_DIRS", dbdEnvList); +#endif +#if USE_TERMCAP + values[dbdEnvOnce2] = cache_getenv("TERMCAP", dbdEnvOnce2); + values[dbdEnvList2] = cache_getenv("TERMPATH", dbdEnvList2); #endif /* USE_TERMCAP */ - case dbdLAST: - break; } - if (*state != next) { - *state = next; - *offset = 0; - _nc_last_db(); + + for (j = 0; j < dbdLAST; ++j) { + if (values[j] == 0) + values[j] = ""; + blobsize += 2 + strlen(values[j]); } - if (result != 0) { - T(("_nc_next_db %d %s", *state, result)); - return result; + + my_blob = malloc(blobsize); + if (my_blob != 0) { + *my_blob = '\0'; + for (j = 0; j < dbdLAST; ++j) { + add_to_blob(values[j]); + } + + /* Now, build an array which will be pointers to the distinct + * strings in the blob. + */ + blobsize = 2; + for (j = 0; my_blob[j] != '\0'; ++j) { + if (my_blob[j] == ':') + ++blobsize; + } + my_list = typeCalloc(char *, blobsize); + my_stat = typeCalloc(struct stat, blobsize); + if (my_list != 0 && my_stat != 0) { + k = 0; + my_list[k++] = my_blob; + for (j = 0; my_blob[j] != '\0'; ++j) { + if (my_blob[j] == ':') { + my_blob[j] = '\0'; + my_list[k++] = &my_blob[j + 1]; + } + } + + /* + * Eliminate duplicates from the list. + */ + for (j = 0; my_list[j] != 0; ++j) { +#ifdef TERMINFO + if (*my_list[j] == '\0') + my_list[j] = TERMINFO; +#endif + for (k = 0; k < j; ++k) { + if (!strcmp(my_list[j], my_list[k])) { + k = --j; + while ((my_list[j] = my_list[j + 1]) != 0) { + ++j; + } + j = k; + break; + } + } + } + + /* + * Eliminate non-existent databases, and those that happen to + * be symlinked to another location. + */ + for (j = 0; my_list[j] != 0; ++j) { + bool found = check_existence(my_list[j], &my_stat[j]); +#if HAVE_LINK + if (found) { + for (k = 0; k < j; ++k) { + if (my_stat[j].st_dev == my_stat[k].st_dev + && my_stat[j].st_ino == my_stat[k].st_ino) { + found = FALSE; + break; + } + } + } +#endif + if (!found) { + k = j; + while ((my_list[k] = my_list[k + 1]) != 0) { + ++k; + } + --j; + } + } + my_size = j; + my_time = time((time_t *) 0); + } else { + FreeAndNull(my_blob); + } } } - return 0; -} - -NCURSES_EXPORT(void) -_nc_first_db(DBDIRS * state, int *offset) -{ - *state = dbdTIC; - *offset = 0; } diff --git a/ncurses/tinfo/lib_data.c b/ncurses/tinfo/lib_data.c index 195ddf97..9b816b5a 100644 --- a/ncurses/tinfo/lib_data.c +++ b/ncurses/tinfo/lib_data.c @@ -42,7 +42,7 @@ #include -MODULE_ID("$Id: lib_data.c,v 1.61 2010/05/15 22:06:56 tom Exp $") +MODULE_ID("$Id: lib_data.c,v 1.62 2011/09/26 09:48:08 tom Exp $") /* * OS/2's native linker complains if we don't initialize public data when @@ -125,7 +125,7 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = { FALSE, /* have_tic_directory */ FALSE, /* keep_tic_directory */ - TERMINFO, /* tic_directory */ + 0, /* tic_directory */ NULL, /* dbi_list */ 0, /* dbi_size */ diff --git a/ncurses/tinfo/lib_termcap.c b/ncurses/tinfo/lib_termcap.c index f5ebb373..0349c940 100644 --- a/ncurses/tinfo/lib_termcap.c +++ b/ncurses/tinfo/lib_termcap.c @@ -48,7 +48,7 @@ #define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_termcap.c,v 1.74 2011/08/13 14:34:56 tom Exp $") +MODULE_ID("$Id: lib_termcap.c,v 1.75 2011/09/26 22:44:30 tom Exp $") NCURSES_EXPORT_VAR(char *) UP = 0; NCURSES_EXPORT_VAR(char *) BC = 0; @@ -351,7 +351,7 @@ NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx NCURSES_CONST char *id, char **area) #endif if (j >= 0) { result = tp->Strings[j]; - TR(TRACE_DATABASE, ("found match : %s", _nc_visbuf(result))); + TR(TRACE_DATABASE, ("found match %d: %s", j, _nc_visbuf(result))); /* setupterm forces canceled strings to null */ if (VALID_STRING(result)) { if (result == exit_attribute_mode diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c index a46917d8..a237d60d 100644 --- a/ncurses/tinfo/read_entry.c +++ b/ncurses/tinfo/read_entry.c @@ -41,7 +41,7 @@ #include -MODULE_ID("$Id: read_entry.c,v 1.112 2011/09/24 23:47:45 tom Exp $") +MODULE_ID("$Id: read_entry.c,v 1.116 2011/09/27 00:35:20 tom Exp $") #define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts)) @@ -328,17 +328,18 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit) ext_str_limit, ptr->ext_str_table + base); } - T(("...done reading terminfo bool %d(%d) num %d(%d) str %d(%d)", - ptr->num_Booleans, ptr->ext_Booleans, - ptr->num_Numbers, ptr->ext_Numbers, - ptr->num_Strings, ptr->ext_Strings)); + TR(TRACE_DATABASE, + ("...done reading terminfo bool %d(%d) num %d(%d) str %d(%d)", + ptr->num_Booleans, ptr->ext_Booleans, + ptr->num_Numbers, ptr->ext_Numbers, + ptr->num_Strings, ptr->ext_Strings)); TR(TRACE_DATABASE, ("extend: num_Booleans:%d", ptr->num_Booleans)); } else #endif /* NCURSES_XNAMES */ { - T(("...done reading terminfo bool %d num %d str %d", - bool_count, num_count, str_count)); + TR(TRACE_DATABASE, ("...done reading terminfo bool %d num %d str %d", + bool_count, num_count, str_count)); #if NCURSES_XNAMES TR(TRACE_DATABASE, ("normal: num_Booleans:%d", ptr->num_Booleans)); #endif @@ -373,13 +374,13 @@ _nc_read_file_entry(const char *const filename, TERMTYPE *ptr) if (_nc_access(filename, R_OK) < 0 || (fp = fopen(filename, "rb")) == 0) { - T(("cannot open terminfo %s (errno=%d)", filename, errno)); + TR(TRACE_DATABASE, ("cannot open terminfo %s (errno=%d)", filename, errno)); code = TGETENT_NO; } else { if ((limit = (int) fread(buffer, sizeof(char), sizeof(buffer), fp)) > 0) { - T(("read terminfo %s", filename)); + TR(TRACE_DATABASE, ("read terminfo %s", filename)); if ((code = _nc_read_termtype(ptr, buffer, limit)) == TGETENT_NO) { _nc_free_termtype(ptr); } @@ -427,12 +428,18 @@ make_dir_filename(char *filename, const char *const path, const char *name) { - unsigned need = (unsigned) (LEAF_LEN + 3 + strlen(path) + strlen(name)); bool result = FALSE; - if (need <= limit) { - (void) sprintf(filename, "%s/" LEAF_FMT "/%s", path, *name, name); - result = TRUE; +#if USE_TERMCAP + if (_nc_is_dir_path(path)) +#endif + { + unsigned need = (unsigned) (LEAF_LEN + 3 + strlen(path) + strlen(name)); + + if (need <= limit) { + (void) sprintf(filename, "%s/" LEAF_FMT "/%s", path, *name, name); + result = TRUE; + } } return result; } @@ -544,14 +551,16 @@ _nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp) || strcmp(name, "..") == 0 || _nc_pathlast(name) != 0 || strchr(name, NCURSES_PATHSEP) != 0) { - T(("illegal or missing entry name '%s'", name)); + TR(TRACE_DATABASE, ("illegal or missing entry name '%s'", name)); } else { #if USE_DATABASE - DBDIRS state = dbdTIC; - int offset = 0; + DBDIRS state; + int offset; const char *path; + _nc_first_db(&state, &offset); while ((path = _nc_next_db(&state, &offset)) != 0) { + TR(TRACE_DATABASE, ("_nc_read_tic_entry path=%s, name=%s", path, name)); code = _nc_read_tic_entry(filename, PATH_MAX, path, name, tp); if (code == TGETENT_YES) { _nc_last_db(); diff --git a/ncurses/tinfo/read_termcap.c b/ncurses/tinfo/read_termcap.c index d4d1869f..29a9800b 100644 --- a/ncurses/tinfo/read_termcap.c +++ b/ncurses/tinfo/read_termcap.c @@ -56,7 +56,7 @@ #include #include -MODULE_ID("$Id: read_termcap.c,v 1.82 2011/08/13 00:20:03 tom Exp $") +MODULE_ID("$Id: read_termcap.c,v 1.84 2011/09/26 22:52:50 tom Exp $") #if !PURE_TERMINFO @@ -73,7 +73,7 @@ get_termpath(void) if (!use_terminfo_vars() || (result = getenv("TERMPATH")) == 0) result = TERMPATH; - T(("TERMPATH is %s", result)); + TR(TRACE_DATABASE, ("TERMPATH is %s", result)); return result; } @@ -383,7 +383,14 @@ _nc_getent( c = *bp++; if (c == '\n') { lineno++; - if (rp == record || *(rp - 1) != '\\') + /* + * Unlike BSD 4.3, this ignores a backslash at the + * end of a comment-line. That makes it consistent + * with the rest of ncurses -TD + */ + if (rp == record + || *record == '#' + || *(rp - 1) != '\\') break; } *rp++ = c; @@ -939,7 +946,7 @@ add_tc(char *termpaths[], char *path, int count) if (count < MAXPATHS && _nc_access(path, R_OK) == 0) { termpaths[count++] = path; - T(("Adding termpath %s", path)); + TR(TRACE_DATABASE, ("Adding termpath %s", path)); } termpaths[count] = 0; if (save != 0) @@ -963,13 +970,13 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp) static char *source; static int lineno; - T(("read termcap entry for %s", tn)); + TR(TRACE_DATABASE, ("read termcap entry for %s", tn)); if (strlen(tn) == 0 || strcmp(tn, ".") == 0 || strcmp(tn, "..") == 0 || _nc_pathlast(tn) != 0) { - T(("illegal or missing entry name '%s'", tn)); + TR(TRACE_DATABASE, ("illegal or missing entry name '%s'", tn)); return TGETENT_NO; } @@ -1082,7 +1089,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp) } } if (omit) { - T(("Path %s is a duplicate", termpaths[j])); + TR(TRACE_DATABASE, ("Path %s is a duplicate", termpaths[j])); for (k = j + 1; k < filecount; k++) { termpaths[k - 1] = termpaths[k]; test_stat[k - 1] = test_stat[k]; @@ -1107,7 +1114,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp) for (i = 0; i < filecount; i++) { - T(("Looking for %s in %s", tn, termpaths[i])); + TR(TRACE_DATABASE, ("Looking for %s in %s", tn, termpaths[i])); if (_nc_access(termpaths[i], R_OK) == 0 && (fp = fopen(termpaths[i], "r")) != (FILE *) 0) { _nc_set_source(termpaths[i]); diff --git a/progs/tic.c b/progs/tic.c index 1b0e8683..d40dde02 100644 --- a/progs/tic.c +++ b/progs/tic.c @@ -44,7 +44,7 @@ #include #include -MODULE_ID("$Id: tic.c,v 1.152 2011/08/06 17:41:36 tom Exp $") +MODULE_ID("$Id: tic.c,v 1.153 2011/09/26 23:50:46 tom Exp $") const char *_nc_progname = "tic"; @@ -554,7 +554,10 @@ main(int argc, char *argv[]) switch (this_opt) { case 'K': _nc_strict_bsd = 1; - /* FALLTHRU */ + /* the initial version of -K in 20110730 fell-thru here, but the + * same flag is useful when reading sources -TD + */ + break; case 'C': capdump = TRUE; outform = F_TERMCAP; -- 2.45.0