ncurses 6.0 - patch 20170701
authorThomas E. Dickey <dickey@invisible-island.net>
Sun, 2 Jul 2017 01:01:29 +0000 (01:01 +0000)
committerThomas E. Dickey <dickey@invisible-island.net>
Sun, 2 Jul 2017 01:01:29 +0000 (01:01 +0000)
+ modify update_getenv() in db_iterator.c to ensure that environment
  variables which are not initially set will be checked later if an
  application happens to set them (patch by Guillaume Maudoux).
+ remove initialization-check for calling napms() in the term-driver
  configuration; none is needed.
+ add help-screen to test/test_getstr.c and test/test_get_wstr.c
+ improve compatibility between different configurations of new_prescr,
  fixing a case with threaded code and term-driver where c++/demo did
  not work (cf: 20160213).
+ the fixes for Redhat #1464685 obscured a problem subsequently
  reported in Redhat #1464687; the given test-case was no longer
  reproducible.  Testing without the fixes for the earlier reports
  showed a problem with buffer overflow in dump_entry.c, which is
  addressed by reducing the use of a fixed-size buffer.
+ add/improve checks in tic's parser to address invalid input
  (Redhat #1464684, #1464685, #1464686, #1464691).
  + alloc_entry.c, add a check for a null-pointer.
  + parse_entry.c, add several checks for valid pointers as well as
    one check to ensure that a single character on a line is not
    treated as the 2-character termcap short-name.
+ fix a memory leak in delscreen() (report by Bai Junq).
+ improve tracemunch, showing thread identifiers as names.
+ fix a use-after-free in NCursesMenu::~NCursesMenu()
+ further amend incorrect calls for memory-leaks from 20170617 changes
  (report by Allen Hewes).

33 files changed:
NEWS
VERSION
c++/cursesm.cc
dist.mk
ncurses/base/lib_newterm.c
ncurses/base/lib_set_term.c
ncurses/base/lib_slkinit.c
ncurses/curses.priv.h
ncurses/tinfo/alloc_entry.c
ncurses/tinfo/db_iterator.c
ncurses/tinfo/entries.c
ncurses/tinfo/lib_data.c
ncurses/tinfo/lib_napms.c
ncurses/tinfo/lib_setup.c
ncurses/tinfo/parse_entry.c
ncurses/tinfo/tinfo_driver.c
ncurses/tty/tty_update.c
package/debian-mingw/changelog
package/debian-mingw64/changelog
package/debian/changelog
package/mingw-ncurses.nsi
package/mingw-ncurses.spec
package/ncurses.spec
package/ncursest.map
package/ncursest.sym
package/ncursestw.map
package/ncursestw.sym
progs/dump_entry.c
test/demo_new_pair.c
test/programs
test/test_get_wstr.c
test/test_getstr.c
test/tracemunch

diff --git a/NEWS b/NEWS
index 55a109d755783f2b162764d25add49f48debbb5b..ff89818495e2a0dddc3660e8540ea302ced0cda5 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.2866 2017/06/24 22:16:43 tom Exp $
+-- $Id: NEWS,v 1.2878 2017/07/01 22:57:06 tom Exp $
 -------------------------------------------------------------------------------
 
 This is a log of changes that ncurses has gone through since Zeyd started
@@ -45,6 +45,33 @@ 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.
 
+20170701
+       + modify update_getenv() in db_iterator.c to ensure that environment
+         variables which are not initially set will be checked later if an
+         application happens to set them (patch by Guillaume Maudoux).
+       + remove initialization-check for calling napms() in the term-driver
+         configuration; none is needed.
+       + add help-screen to test/test_getstr.c and test/test_get_wstr.c
+       + improve compatibility between different configurations of new_prescr,
+         fixing a case with threaded code and term-driver where c++/demo did
+         not work (cf: 20160213).
+       + the fixes for Redhat #1464685 obscured a problem subsequently
+         reported in Redhat #1464687; the given test-case was no longer
+         reproducible.  Testing without the fixes for the earlier reports
+         showed a problem with buffer overflow in dump_entry.c, which is
+         addressed by reducing the use of a fixed-size buffer.
+       + add/improve checks in tic's parser to address invalid input
+         (Redhat #1464684, #1464685, #1464686, #1464691).
+         + alloc_entry.c, add a check for a null-pointer.
+         + parse_entry.c, add several checks for valid pointers as well as
+           one check to ensure that a single character on a line is not
+           treated as the 2-character termcap short-name.
+       + fix a memory leak in delscreen() (report by Bai Junq).
+       + improve tracemunch, showing thread identifiers as names.
+       + fix a use-after-free in NCursesMenu::~NCursesMenu()
+       + further amend incorrect calls for memory-leaks from 20170617 changes
+         (report by Allen Hewes).
+
 20170624
        + modify c++/etip.h.in to accommodate deprecation of throw() and
          throws() in c++17 (prompted by patch by Romain Geissler).
diff --git a/VERSION b/VERSION
index 7bc6915759945f8bef391b61a374afabdd733356..201bd96267490caf09a5f6cda163f2a33aa064ab 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5:0:9  6.0     20170624
+5:0:9  6.0     20170701
index 222de46cd22edc8a930f26a96abaa62632bc5905..6ab0940dadaa20aae86eb97cb5c5c4f6011e818e 100644 (file)
@@ -1,6 +1,6 @@
 // * this is for making emacs happy: -*-Mode: C++;-*-
 /****************************************************************************
- * Copyright (c) 1998-2005,2011 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2017 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            *
@@ -35,7 +35,7 @@
 #include "cursesm.h"
 #include "cursesapp.h"
 
-MODULE_ID("$Id: cursesm.cc,v 1.23 2011/09/17 22:11:32 tom Exp $")
+MODULE_ID("$Id: cursesm.cc,v 1.24 2017/06/26 08:32:53 tom Exp $")
 
 NCursesMenuItem::~NCursesMenuItem()
 {
@@ -180,8 +180,8 @@ NCursesMenu::~NCursesMenu()
   UserHook* hook = reinterpret_cast<UserHook*>(::menu_userptr(menu));
   delete hook;
   if (b_sub_owner) {
-    delete sub;
     ::set_menu_sub(menu, static_cast<WINDOW *>(0));
+    delete sub;
   }
   if (menu) {
     ITEM** itms = ::menu_items(menu);
diff --git a/dist.mk b/dist.mk
index 433072e68b396eafb6e83d494d717ef24bd3759f..e94aae520f087d9ea2ae4870c903167619e27d70 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.1169 2017/06/18 23:13:28 tom Exp $
+# $Id: dist.mk,v 1.1170 2017/06/25 16:16:02 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 = 6
 NCURSES_MINOR = 0
-NCURSES_PATCH = 20170624
+NCURSES_PATCH = 20170701
 
 # We don't append the patch to the version, since this only applies to releases
 VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
index 24426f6b093518dd9b3c5cc537bdce24ec76b56f..b8c8ab8bc4bdd9f049d55233f4c4786b2aeca550 100644 (file)
@@ -48,7 +48,7 @@
 
 #include <tic.h>
 
-MODULE_ID("$Id: lib_newterm.c,v 1.96 2017/04/02 14:26:18 tom Exp $")
+MODULE_ID("$Id: lib_newterm.c,v 1.99 2017/07/01 18:14:07 tom Exp $")
 
 #ifdef USE_TERM_DRIVER
 #define NumLabels      InfoOf(SP_PARM).numlabels
@@ -349,6 +349,12 @@ NCURSES_SP_NAME(newterm) (NCURSES_SP_DCLx
 NCURSES_EXPORT(SCREEN *)
 newterm(NCURSES_CONST char *name, FILE *ofp, FILE *ifp)
 {
-    return NCURSES_SP_NAME(newterm) (CURRENT_SCREEN_PRE, name, ofp, ifp);
+    SCREEN *rc;
+    _nc_lock_global(prescreen);
+    START_TRACE();
+    rc = NCURSES_SP_NAME(newterm) (CURRENT_SCREEN_PRE, name, ofp, ifp);
+    _nc_forget_prescr();
+    _nc_unlock_global(prescreen);
+    return rc;
 }
 #endif
index 6cbf36ec60687f67d2fa0deac4a7ff229d9a466e..05fb445fd52e15226c0c5f6138b1cde6197c45c8 100644 (file)
@@ -46,7 +46,7 @@
 #undef CUR
 #define CUR SP_TERMTYPE
 
-MODULE_ID("$Id: lib_set_term.c,v 1.162 2017/04/15 21:44:03 tom Exp $")
+MODULE_ID("$Id: lib_set_term.c,v 1.166 2017/07/01 16:37:24 tom Exp $")
 
 #ifdef USE_TERM_DRIVER
 #define MaxColors      InfoOf(sp).maxcolors
@@ -182,6 +182,7 @@ delscreen(SCREEN *sp)
        FreeIfNeeded(sp->_color_table);
        FreeIfNeeded(sp->_color_pairs);
 
+       FreeIfNeeded(sp->_oldnum_list);
        FreeIfNeeded(sp->oldhash);
        FreeIfNeeded(sp->newhash);
        FreeIfNeeded(sp->hashtab);
@@ -192,8 +193,9 @@ delscreen(SCREEN *sp)
        NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
        NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx sp->_term);
        FreeIfNeeded(sp->out_buffer);
-       if (_nc_prescreen.allocated == sp)
-           _nc_prescreen.allocated = 0;
+       if (_nc_find_prescr() == sp) {
+           _nc_forget_prescr();
+       }
        free(sp);
 
        /*
@@ -753,12 +755,15 @@ NCURSES_SP_NAME(_nc_ripoffline) (NCURSES_SP_DCLx
        if (line == 0) {
            code = OK;
        } else {
-           if (safe_ripoff_sp == 0)
+           if (safe_ripoff_sp == 0) {
                safe_ripoff_sp = safe_ripoff_stack;
+           }
            if (safe_ripoff_sp < safe_ripoff_stack + N_RIPS) {
                safe_ripoff_sp->line = line;
                safe_ripoff_sp->hook = init;
                (safe_ripoff_sp)++;
+               T(("ripped-off %d:%d chunks",
+                  (int) (safe_ripoff_sp - safe_ripoff_stack), N_RIPS));
                code = OK;
            }
        }
@@ -771,7 +776,12 @@ NCURSES_SP_NAME(_nc_ripoffline) (NCURSES_SP_DCLx
 NCURSES_EXPORT(int)
 _nc_ripoffline(int line, int (*init) (WINDOW *, int))
 {
-    return NCURSES_SP_NAME(_nc_ripoffline) (CURRENT_SCREEN_PRE, line, init);
+    int rc;
+    _nc_lock_global(prescreen);
+    START_TRACE();
+    rc = NCURSES_SP_NAME(_nc_ripoffline) (CURRENT_SCREEN_PRE, line, init);
+    _nc_unlock_global(prescreen);
+    return rc;
 }
 #endif
 
@@ -790,6 +800,11 @@ NCURSES_SP_NAME(ripoffline) (NCURSES_SP_DCLx
 NCURSES_EXPORT(int)
 ripoffline(int line, int (*init) (WINDOW *, int))
 {
-    return NCURSES_SP_NAME(ripoffline) (CURRENT_SCREEN_PRE, line, init);
+    int rc;
+    _nc_lock_global(prescreen);
+    START_TRACE();
+    rc = NCURSES_SP_NAME(ripoffline) (CURRENT_SCREEN_PRE, line, init);
+    _nc_unlock_global(prescreen);
+    return rc;
 }
 #endif
index 9cbdfea98430b8cec66695699f060b78ed836450..11bbdef6ccf7c83225c0c087e0fcb22d518d1328 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2009,2017 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            *
@@ -40,7 +40,7 @@
  */
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_slkinit.c,v 1.13 2009/10/31 00:10:46 tom Exp $")
+MODULE_ID("$Id: lib_slkinit.c,v 1.14 2017/06/30 11:47:34 tom Exp $")
 
 #ifdef USE_SP_RIPOFF
 #define SoftkeyFormat SP_PARM->slk_format
@@ -75,6 +75,11 @@ NCURSES_SP_NAME(slk_init) (NCURSES_SP_DCLx int format)
 NCURSES_EXPORT(int)
 slk_init(int format)
 {
-    return NCURSES_SP_NAME(slk_init) (CURRENT_SCREEN_PRE, format);
+    int rc;
+    _nc_lock_global(prescreen);
+    START_TRACE();
+    rc = NCURSES_SP_NAME(slk_init) (CURRENT_SCREEN_PRE, format);
+    _nc_unlock_global(prescreen);
+    return rc;
 }
 #endif
index 3ad46ab55d8e2cdbbf871c31b2b0d77f09f66d55..3a3b74469b723720aa0ca89a80eb07ad632ed9fe 100644 (file)
@@ -34,7 +34,7 @@
  ****************************************************************************/
 
 /*
- * $Id: curses.priv.h,v 1.576 2017/06/24 15:08:46 tom Exp $
+ * $Id: curses.priv.h,v 1.580 2017/07/01 17:56:12 tom Exp $
  *
  *     curses.priv.h
  *
@@ -966,6 +966,9 @@ typedef struct {
 
 #ifdef USE_PTHREADS
        pthread_mutex_t mutex_curses;
+       pthread_mutex_t mutex_prescreen;
+       pthread_mutex_t mutex_screen;
+       pthread_mutex_t mutex_update;
        pthread_mutex_t mutex_tst_tracef;
        pthread_mutex_t mutex_tracef;
        int             nested_tracef;
@@ -984,12 +987,24 @@ extern NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals;
 
 #define N_RIPS 5
 
+#ifdef USE_PTHREADS
+typedef struct _prescreen_list {
+       struct _prescreen_list *next;
+       pthread_t id;
+       struct screen *sp;
+} PRESCREEN_LIST;
+#endif
+
 /*
  * Global data which can be swept up into a SCREEN when one is created.
  * It may be modified before the next SCREEN is created.
  */
 typedef struct {
+#ifdef USE_PTHREADS
+       PRESCREEN_LIST *allocated;
+#else
        struct screen * allocated;
+#endif
        bool            use_env;
        bool            filter_mode;
        attr_t          previous_attr;
@@ -2019,6 +2034,14 @@ extern NCURSES_EXPORT(int)    _nc_locale_breaks_acs(TERMINAL *);
 extern NCURSES_EXPORT(int)    _nc_setupterm(NCURSES_CONST char *, int, int *, int);
 extern NCURSES_EXPORT(void)   _nc_tinfo_cmdch(TERMINAL *, int);
 
+#ifdef USE_PTHREADS
+extern NCURSES_EXPORT(SCREEN *) _nc_find_prescr(void);
+extern NCURSES_EXPORT(void)   _nc_forget_prescr(void);
+#else
+#define _nc_find_prescr()     _nc_prescreen.allocated
+#define _nc_forget_prescr()   _nc_prescreen.allocated = 0
+#endif
+
 /* lib_set_term.c */
 extern NCURSES_EXPORT(int)    _nc_ripoffline(int, int(*)(WINDOW*, int));
 
index 13bb3a020161498f00c3e6dd2b0765cbc01724b8..5de09f1e4b9ff2cdbaacf21b1b43d319ed012907 100644 (file)
@@ -47,7 +47,7 @@
 
 #include <tic.h>
 
-MODULE_ID("$Id: alloc_entry.c,v 1.59 2017/04/09 23:33:51 tom Exp $")
+MODULE_ID("$Id: alloc_entry.c,v 1.60 2017/06/27 23:48:55 tom Exp $")
 
 #define ABSENT_OFFSET    -1
 #define CANCELLED_OFFSET -2
@@ -96,7 +96,11 @@ _nc_save_str(const char *const string)
 {
     char *result = 0;
     size_t old_next_free = next_free;
-    size_t len = strlen(string) + 1;
+    size_t len;
+
+    if (string == 0)
+       return _nc_save_str("");
+    len = strlen(string) + 1;
 
     if (len == 1 && next_free != 0) {
        /*
index 17f160631df79e4c07f5fab8f853bd7023ee2bcf..7fd791825c931ea897a92a080eb18013eba4c58c 100644 (file)
@@ -43,7 +43,7 @@
 #include <hashed_db.h>
 #endif
 
-MODULE_ID("$Id: db_iterator.c,v 1.44 2017/02/04 23:27:01 tom Exp $")
+MODULE_ID("$Id: db_iterator.c,v 1.46 2017/07/01 22:54:42 tom Exp $")
 
 #define HaveTicDirectory _nc_globals.have_tic_directory
 #define KeepTicDirectory _nc_globals.keep_tic_directory
@@ -123,19 +123,21 @@ update_getenv(const char *name, DBDIRS which)
 
     if (which < dbdLAST) {
        char *value;
+       char *cached_value = my_vars[which].value;
+       bool same_value;
 
-       if ((value = getenv(name)) == 0 || (value = strdup(value)) == 0) {
-           ;
-       } else 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)) {
+       if ((value = getenv(name)) != 0) {
+           value = strdup(value);
+       }
+       same_value = ((value == 0 && cached_value == 0) ||
+                     (value != 0 &&
+                      cached_value != 0 &&
+                      strcmp(value, cached_value) == 0));
+
+       /* Set variable name to enable checks in cache_expired(). */
+       my_vars[which].name = name;
+
+       if (!same_value) {
            FreeIfNeeded(my_vars[which].value);
            my_vars[which].value = value;
            result = TRUE;
index 12674591bdd6d163771c9527dca28c796f3f62b0..dd791b65e47e76699fa91de5eb7ba63fddc1e8b5 100644 (file)
@@ -37,7 +37,7 @@
 
 #include <tic.h>
 
-MODULE_ID("$Id: entries.c,v 1.23 2017/04/13 22:39:57 tom Exp $")
+MODULE_ID("$Id: entries.c,v 1.25 2017/07/01 16:58:42 tom Exp $")
 
 /****************************************************************************
  *
@@ -126,7 +126,7 @@ _nc_leaks_tinfo(void)
     if (TerminalOf(CURRENT_SCREEN) != 0) {
        del_curterm(TerminalOf(CURRENT_SCREEN));
     }
-    free(_nc_prescreen.allocated);
+    _nc_forget_prescr();
 
     _nc_comp_captab_leaks();
     _nc_free_entries(_nc_head);
index c1e2911af91996f7d38ea57e772ebff86f8ee93b..856a812edd3d5d63336c6917a75d3d24e50af69c 100644 (file)
@@ -42,7 +42,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_data.c,v 1.72 2017/04/10 08:34:31 tom Exp $")
+MODULE_ID("$Id: lib_data.c,v 1.74 2017/06/30 11:36:55 tom Exp $")
 
 /*
  * OS/2's native linker complains if we don't initialize public data when
@@ -199,6 +199,9 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
 #endif /* TRACE */
 #ifdef USE_PTHREADS
     PTHREAD_MUTEX_INITIALIZER, /* mutex_curses */
+    PTHREAD_MUTEX_INITIALIZER, /* mutex_prescreen */
+    PTHREAD_MUTEX_INITIALIZER, /* mutex_screen */
+    PTHREAD_MUTEX_INITIALIZER, /* mutex_update */
     PTHREAD_MUTEX_INITIALIZER, /* mutex_tst_tracef */
     PTHREAD_MUTEX_INITIALIZER, /* mutex_tracef */
     0,                         /* nested_tracef */
@@ -294,6 +297,9 @@ init_global_mutexes(void)
     if (!initialized) {
        initialized = TRUE;
        _nc_mutex_init(&_nc_globals.mutex_curses);
+       _nc_mutex_init(&_nc_globals.mutex_prescreen);
+       _nc_mutex_init(&_nc_globals.mutex_screen);
+       _nc_mutex_init(&_nc_globals.mutex_update);
        _nc_mutex_init(&_nc_globals.mutex_tst_tracef);
        _nc_mutex_init(&_nc_globals.mutex_tracef);
     }
index df17363dd42f65efd31f69fa3ff997d2ce756f91..e1a0587028ed75e78b8f47542d42840299fe6d42 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2012,2014 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2014,2017 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            *
@@ -51,7 +51,7 @@
 #endif
 #endif
 
-MODULE_ID("$Id: lib_napms.c,v 1.24 2014/03/08 20:32:59 tom Exp $")
+MODULE_ID("$Id: lib_napms.c,v 1.25 2017/07/01 21:05:56 tom Exp $")
 
 NCURSES_EXPORT(int)
 NCURSES_SP_NAME(napms) (NCURSES_SP_DCLx int ms)
@@ -59,9 +59,7 @@ NCURSES_SP_NAME(napms) (NCURSES_SP_DCLx int ms)
     T((T_CALLED("napms(%d)"), ms));
 
 #ifdef USE_TERM_DRIVER
-    if (HasTerminal(SP_PARM)) {
-       CallDriver_1(SP_PARM, td_nap, ms);
-    }
+    CallDriver_1(SP_PARM, td_nap, ms);
 #else /* !USE_TERM_DRIVER */
 #if NCURSES_SP_FUNCS
     (void) sp;
index b5e2899327d791cc314c90912c9dfe04bcdc39f0..33cf2f96195f3ee06010e66b7abbadcf7d4a6346 100644 (file)
@@ -48,7 +48,7 @@
 #include <locale.h>
 #endif
 
-MODULE_ID("$Id: lib_setup.c,v 1.183 2017/06/24 19:10:43 tom Exp $")
+MODULE_ID("$Id: lib_setup.c,v 1.188 2017/07/01 18:24:50 tom Exp $")
 
 /****************************************************************************
  *
@@ -702,8 +702,9 @@ TINFO_SETUP_TERM(TERMINAL **tp,
     } else {
 #ifdef USE_TERM_DRIVER
        TERMINAL_CONTROL_BLOCK *my_tcb;
-       my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1);
-       termp = &(my_tcb->term);
+       termp = 0;
+       if ((my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1)) != 0)
+           termp = &(my_tcb->term);
 #else
        int status;
 
@@ -818,6 +819,48 @@ TINFO_SETUP_TERM(TERMINAL **tp,
     returnCode(code);
 }
 
+#ifdef USE_PTHREADS
+/*
+ * Returns a non-null pointer unless a new screen should be allocated because
+ * no match was found in the pre-screen cache.
+ */
+NCURSES_EXPORT(SCREEN *)
+_nc_find_prescr(void)
+{
+    SCREEN *result = 0;
+    PRESCREEN_LIST *p;
+    for (p = _nc_prescreen.allocated; p != 0; p = p->next) {
+       if (p->id == pthread_self()) {
+           result = p->sp;
+           break;
+       }
+    }
+    return result;
+}
+
+/*
+ * Tells ncurses to forget that this thread was associated with the pre-screen
+ * cache.  It does not modify the pre-screen cache itself, since that is used
+ * for creating new screens.
+ */
+NCURSES_EXPORT(void)
+_nc_forget_prescr(void)
+{
+    PRESCREEN_LIST *p, *q;
+    for (p = _nc_prescreen.allocated, q = 0; p != 0; q = p, p = p->next) {
+       if (p->id == pthread_self()) {
+           if (q) {
+               q->next = p->next;
+           } else {
+               _nc_prescreen.allocated = p->next;
+           }
+           free(p);
+           break;
+       }
+    }
+}
+#endif /* USE_PTHREADS */
+
 #if NCURSES_SP_FUNCS
 /*
  * In case of handling multiple screens, we need to have a screen before
@@ -833,25 +876,41 @@ new_prescr(void)
     START_TRACE();
     T((T_CALLED("new_prescr()")));
 
-    sp = _nc_alloc_screen_sp();
-    T(("_nc_alloc_screen_sp %p", (void *) sp));
-    if (sp != 0) {
-       _nc_prescreen.allocated = sp;
-       sp->rsp = sp->rippedoff;
-       sp->_filtered = _nc_prescreen.filter_mode;
-       sp->_use_env = _nc_prescreen.use_env;
+    _nc_lock_global(screen);
+    if ((sp = _nc_find_prescr()) == 0) {
+       sp = _nc_alloc_screen_sp();
+       T(("_nc_alloc_screen_sp %p", (void *) sp));
+       if (sp != 0) {
+#ifdef USE_PTHREADS
+           PRESCREEN_LIST *p = typeCalloc(PRESCREEN_LIST, 1);
+           if (p != 0) {
+               p->id = pthread_self();
+               p->sp = sp;
+               p->next = _nc_prescreen.allocated;
+               _nc_prescreen.allocated = p;
+           }
+#else
+           _nc_prescreen.allocated = sp;
+#endif
+           sp->rsp = sp->rippedoff;
+           sp->_filtered = _nc_prescreen.filter_mode;
+           sp->_use_env = _nc_prescreen.use_env;
 #if NCURSES_NO_PADDING
-       sp->_no_padding = _nc_prescreen._no_padding;
+           sp->_no_padding = _nc_prescreen._no_padding;
 #endif
-       sp->slk_format = 0;
-       sp->_slk = 0;
-       sp->_prescreen = TRUE;
-       SP_PRE_INIT(sp);
+           sp->slk_format = 0;
+           sp->_slk = 0;
+           sp->_prescreen = TRUE;
+           SP_PRE_INIT(sp);
 #if USE_REENTRANT
-       sp->_TABSIZE = _nc_prescreen._TABSIZE;
-       sp->_ESCDELAY = _nc_prescreen._ESCDELAY;
+           sp->_TABSIZE = _nc_prescreen._TABSIZE;
+           sp->_ESCDELAY = _nc_prescreen._ESCDELAY;
 #endif
+       }
+    } else {
+       T(("_nc_alloc_screen_sp %p (reuse)", (void *) sp));
     }
+    _nc_unlock_global(screen);
     returnSP(sp);
 }
 #endif
@@ -867,12 +926,19 @@ _nc_setupterm(NCURSES_CONST char *tname,
              int *errret,
              int reuse)
 {
-    int res;
+    int rc = ERR;
     TERMINAL *termp = 0;
-    res = TINFO_SETUP_TERM(&termp, tname, Filedes, errret, reuse);
-    if (ERR != res)
-       NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN_PRE, termp);
-    return res;
+
+    _nc_lock_global(prescreen);
+    START_TRACE();
+    if (TINFO_SETUP_TERM(&termp, tname, Filedes, errret, reuse) == OK) {
+       _nc_forget_prescr();
+       if (NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN_PRE, termp) != 0) {
+           rc = OK;
+       }
+    }
+    _nc_unlock_global(prescreen);
+    return rc;
 }
 #endif
 
index 86a03b37244e78ec22a3694b8e9c3de831f39a23..3fa2f254cb91dd650137efe1f3ed20e690f21adb 100644 (file)
@@ -47,7 +47,7 @@
 #include <ctype.h>
 #include <tic.h>
 
-MODULE_ID("$Id: parse_entry.c,v 1.85 2017/06/24 22:59:46 tom Exp $")
+MODULE_ID("$Id: parse_entry.c,v 1.86 2017/06/28 00:53:12 tom Exp $")
 
 #ifdef LINT
 static short const parametrized[] =
@@ -236,13 +236,14 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent)
      * implemented it.  Note that the resulting terminal type was never the
      * 2-character name, but was instead the first alias after that.
      */
+#define ok_TC2(s) (isgraph(UChar(s)) && (s) != '|')
     ptr = _nc_curr_token.tk_name;
     if (_nc_syntax == SYN_TERMCAP
 #if NCURSES_XNAMES
        && !_nc_user_definable
 #endif
        ) {
-       if (ptr[2] == '|') {
+       if (ok_TC2(ptr[0]) && ok_TC2(ptr[1]) && (ptr[2] == '|')) {
            ptr += 3;
            _nc_curr_token.tk_name[2] = '\0';
        }
@@ -284,9 +285,11 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent)
        if (is_use || is_tc) {
            entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring);
            entryp->uses[entryp->nuses].line = _nc_curr_line;
-           entryp->nuses++;
-           if (entryp->nuses > 1 && is_tc) {
-               BAD_TC_USAGE
+           if (VALID_STRING(entryp->uses[entryp->nuses].name)) {
+               entryp->nuses++;
+               if (entryp->nuses > 1 && is_tc) {
+                   BAD_TC_USAGE
+               }
            }
        } else {
            /* normal token lookup */
@@ -588,7 +591,7 @@ append_acs0(string_desc * dst, int code, int src)
 static void
 append_acs(string_desc * dst, int code, char *src)
 {
-    if (src != 0 && strlen(src) == 1) {
+    if (VALID_STRING(src) && strlen(src) == 1) {
        append_acs0(dst, code, *src);
     }
 }
@@ -849,15 +852,14 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base)
            }
 
            if (tp->Strings[to_ptr->nte_index]) {
+               const char *s = tp->Strings[from_ptr->nte_index];
+               const char *t = tp->Strings[to_ptr->nte_index];
                /* There's no point in warning about it if it's the same
                 * string; that's just an inefficiency.
                 */
-               if (strcmp(
-                             tp->Strings[from_ptr->nte_index],
-                             tp->Strings[to_ptr->nte_index]) != 0)
+               if (VALID_STRING(s) && VALID_STRING(t) && strcmp(s, t) != 0)
                    _nc_warning("%s (%s) already has an explicit value %s, ignoring ko",
-                               ap->to, ap->from,
-                               _nc_visbuf(tp->Strings[to_ptr->nte_index]));
+                               ap->to, ap->from, t);
                continue;
            }
 
index 8b986aa23ae2fff5296ea6fd24dfd29ae23af4b9..605f2d3db3a2053279016683c7fc0492539dd933 100644 (file)
@@ -51,7 +51,7 @@
 # endif
 #endif
 
-MODULE_ID("$Id: tinfo_driver.c,v 1.56 2017/06/24 19:54:16 tom Exp $")
+MODULE_ID("$Id: tinfo_driver.c,v 1.58 2017/06/26 00:43:07 tom Exp $")
 
 /*
  * SCO defines TIOCGSIZE and the corresponding struct.  Other systems (SunOS,
@@ -204,8 +204,16 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
     if (sp == 0 && NC_ISATTY(termp->Filedes)) {
        get_baudrate(termp);
     }
+#if NCURSES_EXT_NUMBERS
+#define cleanup_termtype() \
+    _nc_free_termtype2(&TerminalType(termp)); \
+    _nc_free_termtype(&termp->type)
+#else
+#define cleanup_termtype() \
+    _nc_free_termtype2(&TerminalType(termp))
+#endif
 
-    if (generic_type) {
+       if (generic_type) {
        /*
         * BSD 4.3's termcap contains mis-typed "gn" for wy99.  Do a sanity
         * check before giving up.
@@ -213,18 +221,15 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
        if ((VALID_STRING(cursor_address)
             || (VALID_STRING(cursor_down) && VALID_STRING(cursor_home)))
            && VALID_STRING(clear_screen)) {
-           _nc_free_termtype2(&TerminalType(termp));
-           free(TCB);
+           cleanup_termtype();
            ret_error1(TGETENT_YES, "terminal is not really generic.\n", tname);
        } else {
-           _nc_free_termtype2(&TerminalType(termp));
-           free(TCB);
+           cleanup_termtype();
            ret_error1(TGETENT_NO, "I need something more specific.\n", tname);
        }
     }
     if (hard_copy) {
-       _nc_free_termtype2(&TerminalType(termp));
-       free(TCB);
+       cleanup_termtype();
        ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname);
     }
 
index 46a4786db9d4328d21b585a121e95e0b66e27772..482d66daab7669038431fa52ff34ac467046966e 100644 (file)
@@ -84,7 +84,7 @@
 
 #include <ctype.h>
 
-MODULE_ID("$Id: tty_update.c,v 1.288 2017/03/16 08:24:12 tom Exp $")
+MODULE_ID("$Id: tty_update.c,v 1.289 2017/06/30 11:47:01 tom Exp $")
 
 /*
  * This define controls the line-breakout optimization.  Every once in a
@@ -769,9 +769,12 @@ TINFO_DOUPDATE(NCURSES_SP_DCL0)
 
     T((T_CALLED("_nc_tinfo:doupdate(%p)"), (void *) SP_PARM));
 
-    if (SP_PARM == 0)
-       returnCode(ERR);
+    _nc_lock_global(update);
 
+    if (SP_PARM == 0) {
+       _nc_unlock_global(update);
+       returnCode(ERR);
+    }
 #if !USE_REENTRANT
     /*
      * It is "legal" but unlikely that an application could assign a new
@@ -792,9 +795,10 @@ TINFO_DOUPDATE(NCURSES_SP_DCL0)
 
     if (CurScreen(SP_PARM) == 0
        || NewScreen(SP_PARM) == 0
-       || StdScreen(SP_PARM) == 0)
+       || StdScreen(SP_PARM) == 0) {
+       _nc_unlock_global(update);
        returnCode(ERR);
-
+    }
 #ifdef TRACE
     if (USE_TRACEF(TRACE_UPDATE)) {
        if (CurScreen(SP_PARM)->_clear)
@@ -1102,6 +1106,7 @@ TINFO_DOUPDATE(NCURSES_SP_DCL0)
 
     _nc_signal_handler(TRUE);
 
+    _nc_unlock_global(update);
     returnCode(OK);
 }
 
index 6030834a2c58f1797d396d470696c141e5ebf7e7..ff06b3831b9c530ce235028cea99380d666a7aa2 100644 (file)
@@ -1,8 +1,8 @@
-ncurses6 (6.0+20170624) unstable; urgency=low
+ncurses6 (6.0+20170701) unstable; urgency=low
 
   * latest weekly patch
 
- -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 18 Jun 2017 19:13:28 -0400
+ -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 25 Jun 2017 12:16:02 -0400
 
 ncurses6 (5.9-20131005) unstable; urgency=low
 
index 6030834a2c58f1797d396d470696c141e5ebf7e7..ff06b3831b9c530ce235028cea99380d666a7aa2 100644 (file)
@@ -1,8 +1,8 @@
-ncurses6 (6.0+20170624) unstable; urgency=low
+ncurses6 (6.0+20170701) unstable; urgency=low
 
   * latest weekly patch
 
- -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 18 Jun 2017 19:13:28 -0400
+ -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 25 Jun 2017 12:16:02 -0400
 
 ncurses6 (5.9-20131005) unstable; urgency=low
 
index fb442afef4b4c9a2b7be842d1ce64c9e20cad070..562ae4082f9f9932cd7b3551992f4aea5ababd11 100644 (file)
@@ -1,8 +1,8 @@
-ncurses6 (6.0+20170624) unstable; urgency=low
+ncurses6 (6.0+20170701) unstable; urgency=low
 
   * latest weekly patch
 
- -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 18 Jun 2017 19:13:28 -0400
+ -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 25 Jun 2017 12:16:02 -0400
 
 ncurses6 (5.9-20120608) unstable; urgency=low
 
index 0c7bfb4eff56533988fd52173be999e1086599c3..82c5949637a047ccb675b8a56f059ef867c1e5aa 100644 (file)
@@ -1,4 +1,4 @@
-; $Id: mingw-ncurses.nsi,v 1.217 2017/06/18 23:13:28 tom Exp $\r
+; $Id: mingw-ncurses.nsi,v 1.218 2017/06/25 16:16:02 tom Exp $\r
 \r
 ; TODO add examples\r
 ; TODO bump ABI to 6\r
@@ -10,7 +10,7 @@
 !define VERSION_MAJOR "6"\r
 !define VERSION_MINOR "0"\r
 !define VERSION_YYYY  "2017"\r
-!define VERSION_MMDD  "0624"\r
+!define VERSION_MMDD  "0701"\r
 !define VERSION_PATCH ${VERSION_YYYY}${VERSION_MMDD}\r
 \r
 !define MY_ABI   "5"\r
index 9fae19f02e3c421cc6dbeead5b11c4bec90f56a2..803511d6c76218bcce62745be88f7ba79d39654e 100644 (file)
@@ -3,7 +3,7 @@
 Summary: shared libraries for terminal handling
 Name: mingw32-ncurses6
 Version: 6.0
-Release: 20170624
+Release: 20170701
 License: X11
 Group: Development/Libraries
 Source: ncurses-%{version}-%{release}.tgz
index c6faa83153c308c9020bc8e5c64f889717ac3f2c..2516e3c565b5d2d44201d8140df82428bbd6a9e1 100644 (file)
@@ -1,7 +1,7 @@
 Summary: shared libraries for terminal handling
 Name: ncurses6
 Version: 6.0
-Release: 20170624
+Release: 20170701
 License: X11
 Group: Development/Libraries
 Source: ncurses-%{version}-%{release}.tgz
index 644d6f6f4938409bc4e4259b8c60886fca3c7e0c..d465482c31cf94cb3ebf56d315f3f2118a5cebff 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: ncursest.map,v 1.38 2017/04/12 00:11:27 tom Exp $
+# $Id: ncursest.map,v 1.39 2017/07/01 17:37:54 tom Exp $
 # script for shared library symbol-versioning using ld
 #
 # This file was generated by ncu-mapsyms
@@ -471,6 +471,8 @@ NCURSES_TINFO_6.0.current {
                _nc_copy_termtype2;
                _nc_export_termtype2;
                _nc_fallback2;
+               _nc_find_prescr;
+               _nc_forget_prescr;
                _nc_free_termtype2;
        local:
                _*;
index 9d0e0e3266571842b6b1dce8019a2225e711331e..6ddc31021a9172d6f2473d145f23487fa0a198d4 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: ncursest.sym,v 1.32 2017/04/11 09:24:03 tom Exp $
+# $Id: ncursest.sym,v 1.33 2017/07/01 17:39:07 tom Exp $
 # script for shared library symbol-visibility using libtool
 #
 # This file was generated by ncu-mapsyms
@@ -100,11 +100,13 @@ _nc_export_termtype2
 _nc_fallback
 _nc_fallback2
 _nc_find_entry
+_nc_find_prescr
 _nc_find_type_entry
 _nc_first_db
 _nc_first_name
 _nc_flush
 _nc_flush_sp
+_nc_forget_prescr
 _nc_free_and_exit
 _nc_free_entries
 _nc_free_termtype
index 1ac236d50d8ae06a4b96c0afb9e777ddd96275b8..719fe7fe3a89e8ebf0a8464c69d7070c7dd72dd5 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: ncursestw.map,v 1.39 2017/04/12 00:12:38 tom Exp $
+# $Id: ncursestw.map,v 1.40 2017/07/01 17:38:13 tom Exp $
 # script for shared library symbol-versioning using ld
 #
 # This file was generated by ncu-mapsyms
@@ -477,6 +477,8 @@ NCURSES_TINFO_6.0.current {
                _nc_copy_termtype2;
                _nc_export_termtype2;
                _nc_fallback2;
+               _nc_find_prescr;
+               _nc_forget_prescr;
                _nc_free_termtype2;
        local:
                _*;
index 863294cf42e37c13bb311fdf293509cc3791b6f9..e6232fc957a955a6fbaa685fea1382de535fe8a4 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: ncursestw.sym,v 1.30 2017/04/11 09:24:03 tom Exp $
+# $Id: ncursestw.sym,v 1.31 2017/07/01 17:39:20 tom Exp $
 # script for shared library symbol-visibility using libtool
 #
 # This file was generated by ncu-mapsyms
@@ -100,11 +100,13 @@ _nc_export_termtype2
 _nc_fallback
 _nc_fallback2
 _nc_find_entry
+_nc_find_prescr
 _nc_find_type_entry
 _nc_first_db
 _nc_first_name
 _nc_flush
 _nc_flush_sp
+_nc_forget_prescr
 _nc_free_and_exit
 _nc_free_entries
 _nc_free_termtype
index 0fd9a4dcde00aadef66152d8c558fd4d4f7b44be..600fda9aed810539047e00628a7f43d16d58a3c1 100644 (file)
@@ -39,7 +39,7 @@
 #include "termsort.c"          /* this C file is generated */
 #include <parametrized.h>      /* so is this */
 
-MODULE_ID("$Id: dump_entry.c,v 1.153 2017/06/23 22:47:43 Emanuele.Giaquinta Exp $")
+MODULE_ID("$Id: dump_entry.c,v 1.154 2017/07/01 11:27:29 tom Exp $")
 
 #define DISCARD(string) string = ABSENT_STRING
 #define PRINTF (void) printf
@@ -841,9 +841,10 @@ fmt_entry(TERMTYPE2 *tterm,
     PredIdx num_strings = 0;
     bool outcount = 0;
 
-#define WRAP_CONCAT    \
-       wrap_concat(buffer); \
-       outcount = TRUE
+#define WRAP_CONCAT1(s)                wrap_concat(s); outcount = TRUE
+#define WRAP_CONCAT2(a,b)      wrap_concat(a); WRAP_CONCAT1(b)
+#define WRAP_CONCAT3(a,b,c)    wrap_concat(a); WRAP_CONCAT2(b,c)
+#define WRAP_CONCAT            WRAP_CONCAT1(buffer)
 
     len = 12;                  /* terminfo file-header */
 
@@ -1007,9 +1008,9 @@ fmt_entry(TERMTYPE2 *tterm,
                    set_attributes = save_sgr;
 
                    trimmed_sgr0 = _nc_trim_sgr0(tterm);
-                   if (strcmp(capability, trimmed_sgr0))
+                   if (strcmp(capability, trimmed_sgr0)) {
                        capability = trimmed_sgr0;
-                   else {
+                   else {
                        if (trimmed_sgr0 != exit_attribute_mode)
                            free(trimmed_sgr0);
                    }
@@ -1046,13 +1047,21 @@ fmt_entry(TERMTYPE2 *tterm,
                        _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                                    "%s=!!! %s WILL NOT CONVERT !!!",
                                    name, srccap);
+                       WRAP_CONCAT;
                    } else if (suppress_untranslatable) {
                        continue;
                    } else {
                        char *s = srccap, *d = buffer;
-                       _nc_SPRINTF(d, _nc_SLIMIT(sizeof(buffer)) "..%s=", name);
-                       d += strlen(d);
+                       WRAP_CONCAT3("..", name, "=");
                        while ((*d = *s++) != 0) {
+                           if ((d - buffer - 1) >= (int) sizeof(buffer)) {
+                               fprintf(stderr,
+                                       "%s: value for %s is too long\n",
+                                       _nc_progname,
+                                       name);
+                               *d = '\0';
+                               break;
+                           }
                            if (*d == ':') {
                                *d++ = '\\';
                                *d = ':';
@@ -1061,13 +1070,12 @@ fmt_entry(TERMTYPE2 *tterm,
                            }
                            d++;
                        }
+                       WRAP_CONCAT;
                    }
                } else {
-                   _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
-                               "%s=%s", name, cv);
+                   WRAP_CONCAT3(name, "=", cv);
                }
                len += (int) strlen(capability) + 1;
-               WRAP_CONCAT;
            } else {
                char *src = _nc_tic_expand(capability,
                                           outform == F_TERMINFO, numbers);
@@ -1083,8 +1091,7 @@ fmt_entry(TERMTYPE2 *tterm,
                    strcpy_DYN(&tmpbuf, src);
                }
                len += (int) strlen(capability) + 1;
-               wrap_concat(tmpbuf.text);
-               outcount = TRUE;
+               WRAP_CONCAT1(tmpbuf.text);
            }
        }
        /* e.g., trimmed_sgr0 */
@@ -1526,7 +1533,8 @@ dump_entry(TERMTYPE2 *tterm,
                }
                if (len > critlen) {
                    (void) fprintf(stderr,
-                                  "warning: %s entry is %d bytes long\n",
+                                  "%s: %s entry is %d bytes long\n",
+                                  _nc_progname,
                                   _nc_first_name(tterm->term_names),
                                   len);
                    SHOW_WHY("# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n",
index 8c29870b81290d25626603f9f44cf5e67ca90afa..26256a80af161d1998a1400b2a056d5066cb21ec 100644 (file)
@@ -26,7 +26,7 @@
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: demo_new_pair.c,v 1.14 2017/06/17 19:48:45 tom Exp $
+ * $Id: demo_new_pair.c,v 1.15 2017/06/26 00:20:23 tom Exp $
  *
  * Demonstrate the alloc_pair() function.
  */
@@ -231,6 +231,7 @@ main(int argc, char *argv[])
     }
     if (newterm(NULL, output, stdin) == 0) {
        fprintf(stderr, "Cannot initialize terminal\n");
+       fclose(output);
        ExitProgram(EXIT_FAILURE);
     }
     (void) cbreak();           /* read chars without wait for \n */
index 76215651bf15f31802e6bcb8949c4d71ecda4d0a..6a3a710fc3a5a3fac4c15c60e3ffe3621e2d9fba 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: programs,v 1.38 2017/06/24 20:22:44 tom Exp $
+# $Id: programs,v 1.39 2017/07/01 20:14:35 tom Exp $
 ##############################################################################
 # Copyright (c) 2006-2016,2017 Free Software Foundation, Inc.                #
 #                                                                            #
@@ -86,8 +86,8 @@ test_addchstr $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_addchstr
 test_addstr    $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_addstr
 test_addwstr   $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_addwstr
 test_arrays    $(LDFLAGS_TINFO)        $(LOCAL_LIBS)   test_arrays
-test_get_wstr  $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_get_wstr
-test_getstr    $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_getstr
+test_get_wstr  $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_get_wstr popup_msg
+test_getstr    $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_getstr popup_msg
 test_instr     $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_instr
 test_inwstr    $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_inwstr
 test_opaque    $(LDFLAGS_CURSES)       $(LOCAL_LIBS)   test_opaque
index a3037b1bf61d331136d48ef972019c9675ce0579..5d560bb6dad652da81afe0083055b283ad8e0bcb 100644 (file)
@@ -26,7 +26,7 @@
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: test_get_wstr.c,v 1.9 2017/04/15 14:14:25 tom Exp $
+ * $Id: test_get_wstr.c,v 1.10 2017/07/01 20:41:03 tom Exp $
  *
  * Author: Thomas E Dickey
  *
@@ -43,6 +43,7 @@
  */
 
 #include <test.priv.h>
+#include <popup_msg.h>
 
 #if HAVE_CHGAT
 /* NetBSD curses wchgat */
@@ -136,6 +137,28 @@ ShowFlavor(WINDOW *strwin, WINDOW *txtwin, int flavor, int limit)
 static int
 recursive_test(int level, char **argv, WINDOW *strwin)
 {
+    static const char *help[] =
+    {
+       "Commands:",
+       "  q,^Q,ESC       - quit this program",
+       "  ^Q,ESC         - quit help-screen",
+       "",
+       "  p,<Up>         - move beginning of prompt one up row",
+       "  j,<Down>       - move beginning of prompt one down row",
+       "  h,<Left>       - move beginning of prompt one left column",
+       "  l,<Right>      - move beginning of prompt one right column",
+       "",
+       "  -              - reduce getnstr buffer-size one column",
+       "  +              - increase getnstr buffer-size one column",
+       "  :              - prompt for input-text",
+       "",
+       "  <              - scroll \"left\" through getstr-functions",
+       "  >              - scroll \"right\" through getstr-functions",
+       "",
+       "  w              - recur to subwindow",
+       "  ?,<F1>         - show help-screen",
+       0
+    };
     WINDOW *txtbox = 0;
     WINDOW *txtwin = 0;
     FILE *fp;
@@ -311,10 +334,13 @@ recursive_test(int level, char **argv, WINDOW *strwin)
            }
            noecho();
            (void) wattrset(txtwin, A_NORMAL);
-           wprintw(strwin, "%d", rc);
+           wprintw(strwin, "%s:", (rc == OK) ? "OK" : "ERR");
            (void) waddwstr(strwin, (wchar_t *) buffer);
            wnoutrefresh(strwin);
            break;
+       case HELP_KEY_1:
+           popup_msg(stdscr, help);
+           break;
        default:
            beep();
            break;
index 4c243092b75460ec9c2d63ba4e12d060548752c8..bb1c12656fcbbebda53fa0a5e840337d076bd23c 100644 (file)
@@ -26,7 +26,7 @@
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: test_getstr.c,v 1.11 2017/04/15 14:14:37 tom Exp $
+ * $Id: test_getstr.c,v 1.12 2017/07/01 20:34:55 tom Exp $
  *
  * Author: Thomas E Dickey
  *
@@ -43,6 +43,7 @@
  */
 
 #include <test.priv.h>
+#include <popup_msg.h>
 
 #if HAVE_CHGAT
 /* Solaris SVr4 curses lacks wchgat, mvgetnstr, mvwgetnstr */
@@ -143,6 +144,28 @@ ShowFlavor(WINDOW *strwin, WINDOW *txtwin, int flavor, int limit)
 static int
 recursive_test(int level, char **argv, WINDOW *strwin)
 {
+    static const char *help[] =
+    {
+       "Commands:",
+       "  q,^Q,ESC       - quit this program",
+       "  ^Q,ESC         - quit help-screen",
+       "",
+       "  p,<Up>         - move beginning of prompt one up row",
+       "  j,<Down>       - move beginning of prompt one down row",
+       "  h,<Left>       - move beginning of prompt one left column",
+       "  l,<Right>      - move beginning of prompt one right column",
+       "",
+       "  -              - reduce getnstr buffer-size one column",
+       "  +              - increase getnstr buffer-size one column",
+       "  :              - prompt for input-text",
+       "",
+       "  <              - scroll \"left\" through getstr-functions",
+       "  >              - scroll \"right\" through getstr-functions",
+       "",
+       "  w              - recur to subwindow",
+       "  ?,<F1>         - show help-screen",
+       0
+    };
     WINDOW *txtbox = 0;
     WINDOW *txtwin = 0;
     FILE *fp;
@@ -322,6 +345,9 @@ recursive_test(int level, char **argv, WINDOW *strwin)
            wprintw(strwin, "%s:%s", ok_keyname(rc), buffer);
            wnoutrefresh(strwin);
            break;
+       case HELP_KEY_1:
+           popup_msg(stdscr, help);
+           break;
        default:
            beep();
            break;
index a56c44ad9f4537ff50bb648e687175f101c9517b..10ed5317e1b71617a5b7cce2dcea08d715a47ce3 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# $Id: tracemunch,v 1.9 2017/05/07 19:59:08 tom Exp $
+# $Id: tracemunch,v 1.12 2017/06/29 09:23:58 tom Exp $
 ##############################################################################
 # Copyright (c) 1998-2005,2017 Free Software Foundation, Inc.                #
 #                                                                            #
@@ -42,12 +42,14 @@ our $waddnstr =
   "waddnstr\\(0x([[:xdigit:]]+),\"([^\"]+)\",[0-9]+\\) called {A_NORMAL}";
 
 our $scr_nums = 0;
+our $thr_nums = 0;
 our $try_nums = 0;
 our $win_nums = 0;
 our $curscr   = "";
 our $newscr   = "";
 our $stdscr   = "";
 our %scr_addr;
+our %thr_addr;
 our %try_addr;
 our %win_addr;
 
@@ -62,6 +64,10 @@ sub transaddr {
         $n = $scr_addr{$addr};
         $arg =~ s/\b$addr\b/screen$n/g;
     }
+    foreach my $addr ( keys %thr_addr ) {
+        $n = $thr_addr{$addr};
+        $arg =~ s/\b$addr\b/thread$n/g;
+    }
     foreach my $addr ( keys %try_addr ) {
         $n = $try_addr{$addr};
         $arg =~ s/\b$addr\b/tries_$n/g;
@@ -81,6 +87,13 @@ while (<STDIN>) {
 
   CLASSIFY: {
 
+        my $thread = "";
+        if ( $_ =~ /^(0x[[:xdigit:]]+):/ ) {
+            $thr_addr{$1} = ++$thr_nums unless defined $thr_addr{$1};
+            $thread = "thread" . $thr_addr{$1} . ":";
+            $_ =~ s/^[^:]*://;
+        }
+
         # Transform window pointer addresses so it's easier to compare logs
         $awaiting = "curscr" if ( $_ =~ /creating curscr/ );
         $awaiting = "newscr" if ( $_ =~ /creating newscr/ );
@@ -105,10 +118,15 @@ while (<STDIN>) {
         elsif ( $_ =~ /^(\+ )*called {_nc_add_to_try\((0x[[:xdigit:]]+),/ ) {
             $try_addr{$2} = ++$try_nums unless defined $try_addr{$2};
         }
+        elsif ( $_ =~ /^(\+ )*_nc_alloc_screen_sp 0x([[:xdigit:]]+)/ ) {
+            $addr = "0x$2";
+            $scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
+            $awaiting = "";
+        }
         elsif ( $_ =~ /^(\+ )*return }0x([[:xdigit:]]+)/ ) {
             $addr = "0x$2";
             if ( $awaiting eq "screen" ) {
-                $scr_addr{$addr} = ++$scr_nums;
+                $scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
             }
         }
         elsif ( $_ =~ /^\.\.\.deleted win=0x([[:xdigit:]]+)/ ) {
@@ -180,7 +198,7 @@ while (<STDIN>) {
             print "${repeatcount} REPEATS OF $anyline";
         }
         else {
-            print $anyline;
+            print $thread . $anyline;
         }
         redo CLASSIFY if $_;