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.
This commit is contained in:
Thomas E. Dickey 2011-10-02 00:58:34 +00:00
parent b9cd971c38
commit af4c589f0c
10 changed files with 441 additions and 172 deletions

16
NEWS
View File

@ -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().

View File

@ -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)

View File

@ -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>

View File

@ -47,7 +47,7 @@
#include <tic.h>
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);

View File

@ -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 <curses.priv.h>
#include <time.h>
#include <tic.h>
MODULE_ID("$Id: db_iterator.c,v 1.10 2011/09/24 23:44:58 tom Exp $")
#if USE_HASHED_DB
#include <hashed_db.h>
#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,80 +226,20 @@ 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;
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;
#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;
#endif /* USE_TERMCAP */
case dbdLAST:
break;
}
if (*state != next) {
*state = next;
*offset = 0;
_nc_last_db();
}
if (result != 0) {
T(("_nc_next_db %d %s", *state, result));
return result;
}
}
return 0;
if (result != 0) {
T(("_nc_next_db %d %s", *state, result));
}
return result;
}
NCURSES_EXPORT(void)
@ -222,4 +247,136 @@ _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;
#if USE_DATABASE
#ifdef TERMINFO_DIRS
values[dbdCfgList] = TERMINFO_DIRS;
#endif
#ifdef TERMINFO
values[dbdCfgOnce] = TERMINFO;
#endif
#endif
#if USE_TERMCAP
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 */
}
for (j = 0; j < dbdLAST; ++j) {
if (values[j] == 0)
values[j] = "";
blobsize += 2 + strlen(values[j]);
}
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);
}
}
}
}

View File

@ -42,7 +42,7 @@
#include <curses.priv.h>
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 */

View File

@ -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

View File

@ -41,7 +41,7 @@
#include <tic.h>
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();

View File

@ -56,7 +56,7 @@
#include <sys/types.h>
#include <tic.h>
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]);

View File

@ -44,7 +44,7 @@
#include <dump_entry.h>
#include <transform.h>
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;