ncurses 5.9 - patch 20111001
authorThomas E. Dickey <dickey@invisible-island.net>
Sun, 2 Oct 2011 00:58:34 +0000 (00:58 +0000)
committerThomas E. Dickey <dickey@invisible-island.net>
Sun, 2 Oct 2011 00:58:34 +0000 (00:58 +0000)
+ 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
dist.mk
man/tic.1m
ncurses/tinfo/comp_parse.c
ncurses/tinfo/db_iterator.c
ncurses/tinfo/lib_data.c
ncurses/tinfo/lib_termcap.c
ncurses/tinfo/read_entry.c
ncurses/tinfo/read_termcap.c
progs/tic.c

diff --git a/NEWS b/NEWS
index 0d066dd3e75b0044cde89ccf3a0ddbd32b1fd780..ad2572e84c34012a41f4db8add03d44319c4346a 100644 (file)
--- 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 76e8469f218b42a83b27df66bde864d194a45c5f..9ba5fab1437b7ce1e5d7fb6fc99a7f91d342c96e 100644 (file)
--- 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)
index 38cb19c0562ce0bd19a4f67f00050f1a7f0bd4b5..36b5431471b056e5db7d25d766dde1c67a72cc4d 100644 (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>
index 95a71ed05774a5dec75c3af7264ef29478cfee33..a1f9f4a877fb634cec5bc3a04fe48a9b97e7ce43 100644 (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);
index eec2d4f8abe012cd4ba23f70528cb80648cb2e43..f7e4d6064bf30f020e79cee27fc1a3a1bf6324d5 100644 (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            *
 
 #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,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;
 }
index 195ddf978ab6383e7df16649d2c6216f4d6dadb4..9b816b5a6408061e5aebab389f5cb0cc3f20ade5 100644 (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 */
index f5ebb373e0fde1f842951c836f6b5e0c8ee0b320..0349c9408a8eb04b05616d265d27df6534d9dc98 100644 (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
index a46917d8c23765837dc6d975dab236feacfe67a7..a237d60dbfbfbe6fbbccba0f85bfac84a6ea0197 100644 (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();
index d4d1869f24efcceabb3ff043b0d95a4da241a08c..29a9800b188e748f49d1a89575aca0fa5df1ec90 100644 (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]);
index 1b0e8683e04bb01691afe62048907aa6a4d4e027..d40dde021bb0ed59e0953ae394999a7459f279c4 100644 (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;