ncurses 5.9 - patch 20110813

+ add substitution for $RPATH_LIST to misc/ncurses-config.in
+ improve performance of tic with hashed-database by caching the
  database connection, using atexit() to cleanup.
+ modify treatment of 2-character aliases at the beginning of termcap
  entries so they are not counted in use-resolution, since these are
  guaranteed to be unique.  Also ignore these aliases when reporting
  the primary name of the entry (cf: 20040501)
+ double-check gn (generic) flag in terminal descriptions to
  accommodate old/buggy termcap databases which misused that feature.
+ minor fixes to _nc_tgetent(), ensure buffer is initialized even on
  error-return.
This commit is contained in:
Thomas E. Dickey 2011-08-14 00:27:10 +00:00
parent d4d1d81ab6
commit c002077d39
13 changed files with 239 additions and 121 deletions

15
NEWS
View File

@ -25,7 +25,7 @@
-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
-- $Id: NEWS,v 1.1762 2011/08/07 15:45:26 tom Exp $
-- $Id: NEWS,v 1.1768 2011/08/14 00:26:46 tom Exp $
-------------------------------------------------------------------------------
This is a log of changes that ncurses has gone through since Zeyd started
@ -45,6 +45,19 @@ 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.
20110813
+ add substitution for $RPATH_LIST to misc/ncurses-config.in
+ improve performance of tic with hashed-database by caching the
database connection, using atexit() to cleanup.
+ modify treatment of 2-character aliases at the beginning of termcap
entries so they are not counted in use-resolution, since these are
guaranteed to be unique. Also ignore these aliases when reporting
the primary name of the entry (cf: 20040501)
+ double-check gn (generic) flag in terminal descriptions to
accommodate old/buggy termcap databases which misused that feature.
+ minor fixes to _nc_tgetent(), ensure buffer is initialized even on
error-return.
20110807
+ improve rpath fix from 20110730 by ensuring that the new $RPATH_LIST
variable is defined in the makefiles which use it.

View File

@ -25,7 +25,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
# $Id: dist.mk,v 1.829 2011/08/07 15:43:48 tom Exp $
# $Id: dist.mk,v 1.830 2011/08/12 19:25:31 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 = 20110807
NCURSES_PATCH = 20110813
# We don't append the patch to the version, since this only applies to releases
VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)

View File

@ -1,5 +1,5 @@
#!@SHELL@
# $Id: ncurses-config.in,v 1.26 2011/05/07 19:23:01 tom Exp $
# $Id: ncurses-config.in,v 1.27 2011/08/13 22:11:20 tom Exp $
##############################################################################
# Copyright (c) 2006-2010,2011 Free Software Foundation, Inc. #
# #
@ -41,6 +41,7 @@ mandir="@mandir@"
THIS="@LIB_NAME@@DFT_ARG_SUFFIX@"
TINFO_LIB="@TINFO_ARG_SUFFIX@"
RPATH_LIST="@RPATH_LIST@"
LANG=C; export LANG
LANGUAGE=C; export LANGUAGE

View File

@ -34,7 +34,7 @@
****************************************************************************/
/*
* $Id: curses.priv.h,v 1.481 2011/07/28 22:47:09 tom Exp $
* $Id: curses.priv.h,v 1.482 2011/08/13 14:28:05 tom Exp $
*
* curses.priv.h
*
@ -1841,6 +1841,25 @@ extern NCURSES_EXPORT(void) _nc_tinfo_cmdch(TERMINAL *, char);
/* lib_set_term.c */
extern NCURSES_EXPORT(int) _nc_ripoffline(int, int(*)(WINDOW*, int));
/* lib_setup.c */
#define ret_error(code, fmt, arg) if (errret) {\
*errret = code;\
returnCode(ERR);\
} else {\
fprintf(stderr, fmt, arg);\
exit(EXIT_FAILURE);\
}
#define ret_error1(code, fmt, arg) ret_error(code, "'%s': " fmt, arg)
#define ret_error0(code, msg) if (errret) {\
*errret = code;\
returnCode(ERR);\
} else {\
fprintf(stderr, msg);\
exit(EXIT_FAILURE);\
}
/* lib_tstp.c */
#if USE_SIGWINCH
extern NCURSES_EXPORT(int) _nc_handle_sigwinch(SCREEN *);

View File

@ -47,7 +47,7 @@
#include <tic.h>
MODULE_ID("$Id: comp_parse.c,v 1.74 2011/07/25 22:46:47 tom Exp $")
MODULE_ID("$Id: comp_parse.c,v 1.75 2011/08/13 19:37:17 tom Exp $")
static void sanity_check2(TERMTYPE *, bool);
NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2;
@ -90,6 +90,19 @@ force_bar(char *dst, char *src)
}
#define ForceBar(dst, src) ((strchr(src, '|') == 0) ? force_bar(dst, src) : src)
#if USE_TERMCAP && NCURSES_XNAMES
static char *
skip_index(char *name)
{
char *bar = strchr(name, '|');
if (bar != 0 && (bar - name) == 2)
name = bar + 1;
return name;
}
#endif
NCURSES_EXPORT(bool)
_nc_entry_match(char *n1, char *n2)
/* do any of the aliases in a pair of terminal names match? */
@ -101,6 +114,13 @@ _nc_entry_match(char *n1, char *n2)
n1 = ForceBar(nc1, n1);
n2 = ForceBar(nc2, n2);
#if USE_TERMCAP && NCURSES_XNAMES
if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) {
n1 = skip_index(n1);
n2 = skip_index(n2);
}
#endif
for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1)
for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1)
if ((pend - pstart == qend - qstart)

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 2006,2008 Free Software Foundation, Inc. *
* Copyright (c) 2006-2008,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,12 +36,79 @@
#if USE_HASHED_DB
MODULE_ID("$Id: hashed_db.c,v 1.14 2008/12/13 20:59:02 tom Exp $")
MODULE_ID("$Id: hashed_db.c,v 1.15 2011/08/13 21:08:08 tom Exp $")
#if HASHED_DB_API >= 2
static DBC *cursor;
#endif
typedef struct _myconn {
struct _myconn *next;
DB *db;
char *path;
bool modify;
} MYCONN;
static MYCONN *connections;
static void
cleanup(void)
{
while (connections != 0) {
_nc_db_close(connections->db);
}
}
static DB *
find_connection(const char *path, bool modify)
{
DB *result = 0;
MYCONN *p;
for (p = connections; p != 0; p = p->next) {
if (!strcmp(p->path, path) && p->modify == modify) {
result = p->db;
break;
}
}
return result;
}
static void
drop_connection(DB * db)
{
MYCONN *p, *q;
for (p = connections, q = 0; p != 0; q = p, p = p->next) {
if (p->db == db) {
if (q != 0)
q->next = p->next;
else
connections = p->next;
free(p->path);
free(p);
break;
}
}
}
static void
make_connection(DB * db, const char *path, bool modify)
{
MYCONN *p = typeCalloc(MYCONN, 1);
if (p != 0) {
p->db = db;
p->path = strdup(path);
p->modify = modify;
if (p->path != 0) {
p->next = connections;
connections = p;
}
}
}
/*
* Open the database.
*/
@ -51,50 +118,57 @@ _nc_db_open(const char *path, bool modify)
DB *result = 0;
int code;
if (connections == 0)
atexit(cleanup);
if ((result = find_connection(path, modify)) == 0) {
#if HASHED_DB_API >= 4
db_create(&result, NULL, 0);
if ((code = result->open(result,
NULL,
path,
NULL,
DB_HASH,
modify ? DB_CREATE : DB_RDONLY,
0644)) != 0) {
result = 0;
}
db_create(&result, NULL, 0);
if ((code = result->open(result,
NULL,
path,
NULL,
DB_HASH,
modify ? DB_CREATE : DB_RDONLY,
0644)) != 0) {
result = 0;
}
#elif HASHED_DB_API >= 3
db_create(&result, NULL, 0);
if ((code = result->open(result,
path,
NULL,
DB_HASH,
modify ? DB_CREATE : DB_RDONLY,
0644)) != 0) {
result = 0;
}
db_create(&result, NULL, 0);
if ((code = result->open(result,
path,
NULL,
DB_HASH,
modify ? DB_CREATE : DB_RDONLY,
0644)) != 0) {
result = 0;
}
#elif HASHED_DB_API >= 2
if ((code = db_open(path,
DB_HASH,
modify ? DB_CREATE : DB_RDONLY,
0644,
(DB_ENV *) 0,
(DB_INFO *) 0,
&result)) != 0) {
result = 0;
}
if ((code = db_open(path,
DB_HASH,
modify ? DB_CREATE : DB_RDONLY,
0644,
(DB_ENV *) 0,
(DB_INFO *) 0,
&result)) != 0) {
result = 0;
}
#else
if ((result = dbopen(path,
modify ? (O_CREAT | O_RDWR) : O_RDONLY,
0644,
DB_HASH,
NULL)) == 0) {
code = errno;
}
if ((result = dbopen(path,
modify ? (O_CREAT | O_RDWR) : O_RDONLY,
0644,
DB_HASH,
NULL)) == 0) {
code = errno;
}
#endif
if (result != 0) {
T(("opened %s", path));
} else {
T(("cannot open %s: %s", path, strerror(code)));
if (result != 0) {
make_connection(result, path, modify);
T(("opened %s", path));
} else {
T(("cannot open %s: %s", path, strerror(code)));
}
}
return result;
}
@ -107,6 +181,7 @@ _nc_db_close(DB * db)
{
int result;
drop_connection(db);
#if HASHED_DB_API >= 2
result = db->close(db, 0);
#else

View File

@ -47,7 +47,7 @@
#include <locale.h>
#endif
MODULE_ID("$Id: lib_setup.c,v 1.139 2011/08/05 21:56:40 tom Exp $")
MODULE_ID("$Id: lib_setup.c,v 1.141 2011/08/13 16:07:22 tom Exp $")
/****************************************************************************
*
@ -412,22 +412,6 @@ _nc_update_screensize(SCREEN *sp)
*
****************************************************************************/
#define ret_error(code, fmt, arg) if (errret) {\
*errret = code;\
returnCode(ERR);\
} else {\
fprintf(stderr, fmt, arg);\
exit(EXIT_FAILURE);\
}
#define ret_error0(code, msg) if (errret) {\
*errret = code;\
returnCode(ERR);\
} else {\
fprintf(stderr, msg);\
exit(EXIT_FAILURE);\
}
#if USE_DATABASE || USE_TERMCAP
/*
* Return 1 if entry found, 0 if not found, -1 if database not accessible,
@ -692,7 +676,7 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
if (status == TGETENT_ERR) {
ret_error0(status, "terminals database is inaccessible\n");
} else if (status == TGETENT_NO) {
ret_error(status, "'%s': unknown terminal type.\n", tname);
ret_error1(status, "unknown terminal type.\n", tname);
}
}
#if !USE_REENTRANT
@ -740,10 +724,19 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
#ifndef USE_TERM_DRIVER
if (generic_type) {
ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname);
}
if (hard_copy) {
ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname);
/*
* BSD 4.3's termcap contains mis-typed "gn" for wy99. Do a sanity
* check before giving up.
*/
if ((VALID_STRING(cursor_address)
|| (VALID_STRING(cursor_down) && VALID_STRING(cursor_home)))
&& VALID_STRING(clear_screen)) {
ret_error1(TGETENT_YES, "terminal is not really generic.\n", tname);
} else {
ret_error1(TGETENT_NO, "I need something more specific.\n", tname);
}
} else if (hard_copy) {
ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname);
}
#endif
returnCode(code);

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
* Copyright (c) 1998-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 *
@ -48,7 +48,7 @@
#define CUR SP_TERMTYPE
#endif
MODULE_ID("$Id: lib_termcap.c,v 1.73 2010/12/25 19:27:12 tom Exp $")
MODULE_ID("$Id: lib_termcap.c,v 1.74 2011/08/13 14:34:56 tom Exp $")
NCURSES_EXPORT_VAR(char *) UP = 0;
NCURSES_EXPORT_VAR(char *) BC = 0;
@ -97,7 +97,7 @@ NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
#ifdef USE_TERM_DRIVER
if (termp == 0 ||
!((TERMINAL_CONTROL_BLOCK *) termp)->drv->isTerminfo)
return (rc);
returnCode(rc);
#endif
/*

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 1999-2007,2008 Free Software Foundation, Inc. *
* Copyright (c) 1999-2008,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 *
@ -33,18 +33,30 @@
#include <curses.priv.h>
#include <tic.h>
MODULE_ID("$Id: name_match.c,v 1.18 2008/11/16 00:19:59 juergen Exp $")
MODULE_ID("$Id: name_match.c,v 1.21 2011/08/13 20:23:12 tom Exp $")
/*
* _nc_first_name(char *names)
*
* Extract the primary name from a compiled entry.
*/
#define FirstName _nc_globals.first_name
#if USE_TERMCAP && NCURSES_XNAMES
static const char *
skip_index(const char *name)
{
if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) {
const char *bar = strchr(name, '|');
if (bar != 0 && (bar - name) == 2)
name = bar + 1;
}
return name;
}
#endif
/*
* Get the primary name from the given name list. For terminfo, this is the
* first name. For termcap, this may be the second name, if the first one
* happens to be two characters.
*/
NCURSES_EXPORT(char *)
_nc_first_name(const char *const sp)
/* get the first name from the given name list */
{
unsigned n;
@ -59,8 +71,12 @@ _nc_first_name(const char *const sp)
FirstName = typeMalloc(char, MAX_NAME_SIZE + 1);
if (FirstName != 0) {
const char *src = sp;
#if USE_TERMCAP && NCURSES_XNAMES
src = skip_index(sp);
#endif
for (n = 0; n < MAX_NAME_SIZE; n++) {
if ((FirstName[n] = sp[n]) == '\0'
if ((FirstName[n] = src[n]) == '\0'
|| (FirstName[n] == '|'))
break;
}
@ -71,11 +87,8 @@ _nc_first_name(const char *const sp)
}
/*
* int _nc_name_match(namelist, name, delim)
*
* Is the given name matched in namelist?
* Is the given name matched in namelist?
*/
NCURSES_EXPORT(int)
_nc_name_match(const char *const namelst, const char *const name, const char *const delim)
{

View File

@ -41,7 +41,7 @@
#include <tic.h>
MODULE_ID("$Id: read_entry.c,v 1.109 2011/07/25 22:21:34 tom Exp $")
MODULE_ID("$Id: read_entry.c,v 1.110 2011/08/13 21:10:03 tom Exp $")
#define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts))
@ -428,12 +428,6 @@ _nc_read_tic_entry(char *filename,
else
(void) sprintf(filename, "%s%s", path, suffix);
/*
* It would be nice to optimize the dbopen/close activity, as
* done in the cgetent implementation for tc= clauses. However,
* since we support multiple database locations, we cannot do
* that.
*/
if ((capdbp = _nc_db_open(filename, FALSE)) != 0) {
DBT key, data;
int reccnt = 0;
@ -489,7 +483,6 @@ _nc_read_tic_entry(char *filename,
key.size = used;
}
_nc_db_close(capdbp);
free(save);
}
}

View File

@ -56,7 +56,7 @@
#include <sys/types.h>
#include <tic.h>
MODULE_ID("$Id: read_termcap.c,v 1.81 2011/08/07 18:56:35 tom Exp $")
MODULE_ID("$Id: read_termcap.c,v 1.82 2011/08/13 00:20:03 tom Exp $")
#if !PURE_TERMINFO
@ -702,8 +702,6 @@ _nc_nfcmp(const char *nf, char *rec)
#define PVECSIZ 32 /* max number of names in path */
#define TBUFSIZ (2048*2)
static char *tbuf;
/*
* On entry, srcp points to a non ':' character which is the beginning of the
* token, if any. We'll try to return a string that doesn't end with a ':'.
@ -781,7 +779,7 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
register char *p;
register char *cp;
char *dummy = NULL;
const char **fname;
CGETENT_CONST char **fname;
char *home;
int i;
char pathbuf[PBUFSIZ]; /* holds raw path of filenames */
@ -793,7 +791,6 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
*lineno = 1;
fname = pathvec;
pvec = pathvec;
tbuf = bp;
p = pathbuf;
cp = use_terminfo_vars()? getenv("TERMCAP") : NULL;
@ -862,6 +859,7 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
* empty fields, and mistakenly use the last valid cap entry instead of
* the first (breaks tc= includes)
*/
*bp = '\0';
if (i >= 0) {
char *pd, *ps, *tok;
int endflag = FALSE;

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 2008-2009,2010 Free Software Foundation, Inc. *
* Copyright (c) 2008-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 *
@ -50,7 +50,7 @@
# endif
#endif
MODULE_ID("$Id: tinfo_driver.c,v 1.13 2010/12/20 01:47:09 tom Exp $")
MODULE_ID("$Id: tinfo_driver.c,v 1.15 2011/08/13 16:11:15 tom Exp $")
/*
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
@ -106,22 +106,6 @@ drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
return TINFO_DOUPDATE(TCB->csp);
}
#define ret_error(code, fmt, arg) if (errret) {\
*errret = code;\
return(FALSE); \
} else {\
fprintf(stderr, fmt, arg);\
exit(EXIT_FAILURE);\
}
#define ret_error0(code, msg) if (errret) {\
*errret = code;\
return(FALSE);\
} else {\
fprintf(stderr, msg);\
exit(EXIT_FAILURE);\
}
static bool
drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
{
@ -156,7 +140,7 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
if (status == TGETENT_ERR) {
ret_error0(status, "terminals database is inaccessible\n");
} else if (status == TGETENT_NO) {
ret_error(status, "'%s': unknown terminal type.\n", tname);
ret_error1(status, "unknown terminal type.\n", tname);
}
}
result = TRUE;
@ -169,10 +153,20 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
_nc_tinfo_cmdch(termp, *command_character);
if (generic_type) {
ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname);
/*
* BSD 4.3's termcap contains mis-typed "gn" for wy99. Do a sanity
* check before giving up.
*/
if ((VALID_STRING(cursor_address)
|| (VALID_STRING(cursor_down) && VALID_STRING(cursor_home)))
&& VALID_STRING(clear_screen)) {
ret_error1(TGETENT_YES, "terminal is not really generic.\n", tname);
} else {
ret_error1(TGETENT_NO, "I need something more specific.\n", tname);
}
}
if (hard_copy) {
ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname);
ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname);
}
return result;

View File

@ -47,7 +47,7 @@
#define TRACE_OUT(p) /*nothing */
#endif
MODULE_ID("$Id: write_entry.c,v 1.79 2011/06/05 00:46:26 tom Exp $")
MODULE_ID("$Id: write_entry.c,v 1.80 2011/08/13 20:52:40 tom Exp $")
static int total_written;
@ -349,7 +349,6 @@ _nc_write_entry(TERMTYPE *const tp)
_nc_db_put(capdb, &key, &data);
}
_nc_db_close(capdb);
}
}
#else /* !USE_HASHED_DB */