ncurses 6.0 - patch 20171021
authorThomas E. Dickey <dickey@invisible-island.net>
Sun, 22 Oct 2017 01:55:30 +0000 (01:55 +0000)
committerThomas E. Dickey <dickey@invisible-island.net>
Sun, 22 Oct 2017 01:55:30 +0000 (01:55 +0000)
+ modify test/view.c to expand tabs using the ncurses library rather
  than in the test-program.
+ remove very old SIGWINCH example in test/view.c, just use KEY_RESIZE.
+ add -T, -e, -f -m options to "dots" test-programs.
+ fix a few typos in usage-messages for test-programs.

27 files changed:
MANIFEST
NEWS
VERSION
dist.mk
ncurses/trace/lib_traceatr.c
ncurses/trace/visbuf.c
package/debian-mingw/changelog
package/debian-mingw64/changelog
package/debian/changelog
package/mingw-ncurses.nsi
package/mingw-ncurses.spec
package/ncurses.spec
test/bs.c
test/bulgarian-utf8-tabs.txt [new file with mode: 0644]
test/cardfile.c
test/ditto.c
test/dots.c
test/dots_curses.c
test/dots_mvcur.c
test/dots_termcap.c
test/dots_xcurses.c
test/echochar.c
test/ins_wide.c
test/ncurses.c
test/savescreen.c
test/view.c
test/widechars-utf8-tabs.txt [new file with mode: 0644]

index eb0593caa7c6203c4cd70d7042fdeb287547949a..86d38eb4e72f2caf1a8db58f66d0ee89e1446a1f 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
 ./test/blue.c
 ./test/bs.6
 ./test/bs.c
+./test/bulgarian-utf8-tabs.txt
 ./test/bulgarian-utf8.txt
 ./test/cardfile.c
 ./test/cardfile.dat
 ./test/tput-initc
 ./test/tracemunch
 ./test/view.c
+./test/widechars-utf8-tabs.txt
 ./test/widechars-utf8.txt
 ./test/widechars.h
 ./test/worm.c
diff --git a/NEWS b/NEWS
index 64be9a918ae29a92e864ab1aecc8bbb57f3f1d1d..b023262db99191b27b634f111bcb5c66f1e3d014 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.2975 2017/10/14 23:49:52 tom Exp $
+-- $Id: NEWS,v 1.2979 2017/10/21 20:29:16 tom Exp $
 -------------------------------------------------------------------------------
 
 This is a log of changes that ncurses has gone through since Zeyd started
@@ -45,6 +45,13 @@ 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.
 
+20171021
+       + modify test/view.c to expand tabs using the ncurses library rather
+         than in the test-program.
+       + remove very old SIGWINCH example in test/view.c, just use KEY_RESIZE.
+       + add -T, -e, -f -m options to "dots" test-programs.
+       + fix a few typos in usage-messages for test-programs.
+
 20171014
        + minor cleanup to test/view.c:
          + eliminate "-n" option by simply reading the whole file.
diff --git a/VERSION b/VERSION
index a09a8abcde01c809e4ac8737e45dda19865ed4b0..3161a8d1f8dd59a403d558cce596d6a72e8b2016 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5:0:9  6.0     20171014
+5:0:9  6.0     20171021
diff --git a/dist.mk b/dist.mk
index 04f266b3e2b0debf871f36f43587c693d8f98678..71921f343b69aaa3a096b11cb464eef4bfc26ffe 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.1187 2017/10/08 23:38:02 tom Exp $
+# $Id: dist.mk,v 1.1188 2017/10/15 14:51:52 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 = 20171014
+NCURSES_PATCH = 20171021
 
 # We don't append the patch to the version, since this only applies to releases
 VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
index 1476b8458c3d260c61e8ab1d66645f5591f6bf89..1ed5a5ecae3d692a7b5c044e6dde0049e1596510 100644 (file)
@@ -43,7 +43,7 @@
 #define CUR SP_TERMTYPE
 #endif
 
-MODULE_ID("$Id: lib_traceatr.c,v 1.88 2017/03/01 00:04:04 tom Exp $")
+MODULE_ID("$Id: lib_traceatr.c,v 1.89 2017/10/21 23:12:09 tom Exp $")
 
 #define COLOR_OF(c) ((c < 0) ? "default" : (c > 7 ? color_of(c) : colors[c].name))
 
@@ -362,9 +362,9 @@ _tracecchar_t2(int bufnum, const cchar_t *ch)
                    } else if (ch->chars[PUTC_i] > 255) {
                        char temp[80];
                        _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
-                                   "{%d:\\u%x}",
+                                   "{%d:\\u%lx}",
                                    wcwidth(ch->chars[PUTC_i]),
-                                   ch->chars[PUTC_i]);
+                                   (unsigned long) ch->chars[PUTC_i]);
                        (void) _nc_trace_bufcat(bufnum, temp);
                        break;
                    }
index 13023aaa1a82426e9f2c45e1a730299d7ff623e3..581bfbd259bd5a76862dd09616fdbcc8acb40f82 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2001-2014,2016 Free Software Foundation, Inc.              *
+ * Copyright (c) 2001-2016,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            *
@@ -42,7 +42,7 @@
 #include <tic.h>
 #include <ctype.h>
 
-MODULE_ID("$Id: visbuf.c,v 1.48 2016/09/05 00:43:08 tom Exp $")
+MODULE_ID("$Id: visbuf.c,v 1.49 2017/10/21 23:34:20 tom Exp $")
 
 #define NUM_VISBUFS 4
 
@@ -334,9 +334,9 @@ _nc_viscbuf2(int bufnum, const NCURSES_CH_T * buf, int len)
                                               buf[j].chars[PUTC_i], &PUT_st);
                        if (PUTC_n <= 0 || buf[j].chars[PUTC_i] > 255) {
                            _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
-                                       "{%d:\\u%x}",
+                                       "{%d:\\u%lx}",
                                        wcwidth(buf[j].chars[PUTC_i]),
-                                       buf[j].chars[PUTC_i]);
+                                       (unsigned long) buf[j].chars[PUTC_i]);
                            (void) _nc_trace_bufcat(bufnum, temp);
                            break;
                        }
index 65545df2bd5bcfe50f7860bd739e24d17db96bc6..79dd880f1080d02bdc4ebf9d11ba8781c01ff636 100644 (file)
@@ -1,8 +1,8 @@
-ncurses6 (6.0+20171014) unstable; urgency=low
+ncurses6 (6.0+20171021) unstable; urgency=low
 
   * latest weekly patch
 
- -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 08 Oct 2017 19:38:02 -0400
+ -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 15 Oct 2017 10:51:52 -0400
 
 ncurses6 (5.9-20131005) unstable; urgency=low
 
index 65545df2bd5bcfe50f7860bd739e24d17db96bc6..79dd880f1080d02bdc4ebf9d11ba8781c01ff636 100644 (file)
@@ -1,8 +1,8 @@
-ncurses6 (6.0+20171014) unstable; urgency=low
+ncurses6 (6.0+20171021) unstable; urgency=low
 
   * latest weekly patch
 
- -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 08 Oct 2017 19:38:02 -0400
+ -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 15 Oct 2017 10:51:52 -0400
 
 ncurses6 (5.9-20131005) unstable; urgency=low
 
index ceaef328c2f83e8fc12dd16f43a4398f21ba4aeb..975ce46d1d610edc94de8dce4dc7950b4854944e 100644 (file)
@@ -1,8 +1,8 @@
-ncurses6 (6.0+20171014) unstable; urgency=low
+ncurses6 (6.0+20171021) unstable; urgency=low
 
   * latest weekly patch
 
- -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 08 Oct 2017 19:38:02 -0400
+ -- Thomas E. Dickey <dickey@invisible-island.net>  Sun, 15 Oct 2017 10:51:52 -0400
 
 ncurses6 (5.9-20120608) unstable; urgency=low
 
index f300c595ce7f3ca5eeac01fdf07ef26dd6176600..e232786e0952ff3fe24859b44bd2bf506d5d3a16 100644 (file)
@@ -1,4 +1,4 @@
-; $Id: mingw-ncurses.nsi,v 1.235 2017/10/08 23:38:02 tom Exp $\r
+; $Id: mingw-ncurses.nsi,v 1.236 2017/10/15 14:51:52 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  "1014"\r
+!define VERSION_MMDD  "1021"\r
 !define VERSION_PATCH ${VERSION_YYYY}${VERSION_MMDD}\r
 \r
 !define MY_ABI   "5"\r
index 3ed343755be8e76b5f8853a0fe519a5ccf137a2a..e209ad3a0c09d324f42f70eb583235c5a68461f6 100644 (file)
@@ -3,7 +3,7 @@
 Summary: shared libraries for terminal handling
 Name: mingw32-ncurses6
 Version: 6.0
-Release: 20171014
+Release: 20171021
 License: X11
 Group: Development/Libraries
 Source: ncurses-%{version}-%{release}.tgz
index 4c1cd095d0af748a61518693e958b7729c7ab456..9f2de5110e745a86a8a0c2b34cf81c21bd00c6c9 100644 (file)
@@ -1,7 +1,7 @@
 Summary: shared libraries for terminal handling
 Name: ncurses6
 Version: 6.0
-Release: 20171014
+Release: 20171021
 License: X11
 Group: Development/Libraries
 Source: ncurses-%{version}-%{release}.tgz
index a954d2d2ade23630e2adcaec3ea3f4f5bdf9d77b..31f98bb8684dc3754d8976a0bd26ff85c00411da 100644 (file)
--- a/test/bs.c
+++ b/test/bs.c
@@ -34,7 +34,7 @@
  * v2.0 featuring strict ANSI/POSIX conformance, November 1993.
  * v2.1 with ncurses mouse support, September 1995
  *
- * $Id: bs.c,v 1.70 2017/09/30 15:40:39 tom Exp $
+ * $Id: bs.c,v 1.71 2017/10/18 23:03:07 tom Exp $
  */
 
 #include <test.priv.h>
@@ -1162,7 +1162,7 @@ do_options(int c, char *op[])
            switch (op[i][0]) {
            default:
            case '?':
-               (void) fprintf(stderr, "Usage: battle [-s | -b] [-c]\n");
+               (void) fprintf(stderr, "Usage: bs [-s | -b] [-c]\n");
                (void) fprintf(stderr, "\tWhere the options are:\n");
                (void) fprintf(stderr, "\t-s : play a salvo game\n");
                (void) fprintf(stderr, "\t-b : play a blitz game\n");
diff --git a/test/bulgarian-utf8-tabs.txt b/test/bulgarian-utf8-tabs.txt
new file mode 100644 (file)
index 0000000..65e42bb
--- /dev/null
@@ -0,0 +1,6 @@
+Показване Ð½Ð° Ð¿Ð¾Ð¼Ð¾Ñ‰Ð½Ð° Ð¸Ð½Ñ„ормация    -- 1
+Създаване Ð½Ð° Ð´ÑÐ»Ð¾Ð²Ðµ           -- 2
+Избор Ð½Ð° Ð´ÑÐ» Ð¸ Ñ„орматиране       -- 3
+Записване Ð² Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð´ÑÐ»  -- 4
+Инсталиране Ð½Ð° LILO               -- 5
+Изход Ð¾Ñ‚ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð°Ñ‚а           -- 6
index 15d532e800114322fbb76502d50a29614bb47cf8..ba9e8de53bae1f8b2eff2c0485247f9dc849e37c 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1999-2013,2016 Free Software Foundation, Inc.              *
+ * Copyright (c) 1999-2016,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            *
@@ -29,7 +29,7 @@
 /*
  * Author: Thomas E. Dickey
  *
- * $Id: cardfile.c,v 1.43 2016/09/10 21:36:46 tom Exp $
+ * $Id: cardfile.c,v 1.45 2017/10/19 21:14:25 tom Exp $
  *
  * File format: text beginning in column 1 is a title; other text is content.
  */
@@ -549,7 +549,7 @@ usage(void)
 {
     static const char *msg[] =
     {
-       "Usage: view [options] file"
+       "Usage: cardfile [options] file"
        ,""
        ,"Options:"
        ," -c       use color if terminal supports it"
index bf14946ff384a3450206bbd4ed426ec30cb87ad2..aff426f86795084a9625baf9c9ccfda75c7cc40f 100644 (file)
@@ -29,7 +29,7 @@
 /*
  * Author: Thomas E. Dickey (1998-on)
  *
- * $Id: ditto.c,v 1.46 2017/09/06 09:19:14 tom Exp $
+ * $Id: ditto.c,v 1.47 2017/10/18 23:04:42 tom Exp $
  *
  * The program illustrates how to set up multiple screens from a single
  * program.
@@ -114,7 +114,7 @@ failed(const char *s)
 static void
 usage(void)
 {
-    fprintf(stderr, "usage: ditto [terminal1 ...]\n");
+    fprintf(stderr, "Usage: ditto [terminal1 ...]\n");
     ExitProgram(EXIT_FAILURE);
 }
 
index a03148bdb57f4b9c136273b95a3709cb4fbec2d5..5490bcfba31ec79b41140fa913f9ea3519bed3de 100644 (file)
@@ -29,7 +29,7 @@
 /*
  * Author: Thomas E. Dickey <dickey@clark.net> 1999
  *
- * $Id: dots.c,v 1.28 2017/10/11 08:15:27 tom Exp $
+ * $Id: dots.c,v 1.31 2017/10/22 00:44:06 tom Exp $
  *
  * A simple demo of the terminfo interface.
  */
@@ -96,20 +96,84 @@ ranf(void)
     return ((double) r / 32768.);
 }
 
+static int
+get_number(const char *cap, int map)
+{
+    int result = map;
+    if (cap != 0) {
+       int check = tigetnum(cap);
+       if (check > 0)
+           result = check;
+    }
+    return result;
+}
+
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+       "Usage: dots [options]"
+       ,""
+       ,"Options:"
+       ," -T TERM  override $TERM"
+       ," -e       allow environment $LINES / $COLUMNS"
+       ," -f       use tigetnum rather than <term.h> mapping"
+       ," -m SIZE  set margin (default: 2)"
+       ," -s MSECS delay 1% of the time (default: 1 msecs)"
+    };
+    size_t n;
+
+    for (n = 0; n < SIZEOF(msg); n++)
+       fprintf(stderr, "%s\n", msg[n]);
+
+    ExitProgram(EXIT_FAILURE);
+}
+
 int
-main(int argc GCC_UNUSED,
-     char *argv[]GCC_UNUSED)
+main(int argc,
+     char *argv[])
 {
     int x, y, z, p;
     double r;
     double c;
     int my_colors;
+    int f_option = 0;
+    int m_option = 2;
+    int s_option = 1;
+
+    while ((x = getopt(argc, argv, "T:efm:s:")) != -1) {
+       switch (x) {
+       case 'T':
+           putenv(strcat(strcpy(malloc(6 + strlen(optarg)), "TERM="), optarg));
+           break;
+       case 'e':
+           use_env(TRUE);
+           break;
+       case 'f':
+           f_option = 1;
+           break;
+       case 'm':
+           m_option = atoi(optarg);
+           break;
+       case 's':
+           s_option = atoi(optarg);
+           break;
+       default:
+           usage();
+           break;
+       }
+    }
 
-    srand((unsigned) time(0));
     InitAndCatch(setupterm((char *) 0, 1, (int *) 0), onsig);
+
+    srand((unsigned) time(0));
+
     outs(clear_screen);
     outs(cursor_invisible);
-    my_colors = max_colors;
+
+#define GetNumber(ln,sn) get_number(f_option ? #sn : 0, ln)
+    my_colors = GetNumber(max_colors, colors);
     if (my_colors > 1) {
        if (!VALID_STRING(set_a_foreground)
            || !VALID_STRING(set_a_background)
@@ -117,13 +181,13 @@ main(int argc GCC_UNUSED,
            my_colors = -1;
     }
 
-    r = (double) (lines - 4);
-    c = (double) (columns - 4);
+    r = (double) (GetNumber(lines, lines) - (m_option * 2));
+    c = (double) (GetNumber(columns, cols) - (m_option * 2));
     started = time((time_t *) 0);
 
     while (!interrupted) {
-       x = (int) (c * ranf()) + 2;
-       y = (int) (r * ranf()) + 2;
+       x = (int) (c * ranf()) + m_option;
+       y = (int) (r * ranf()) + m_option;
        p = (ranf() > 0.9) ? '*' : ' ';
 
        tputs(tparm3(cursor_address, y, x), 1, outc);
@@ -133,7 +197,7 @@ main(int argc GCC_UNUSED,
                tputs(tparm2(set_a_foreground, z), 1, outc);
            } else {
                tputs(tparm2(set_a_background, z), 1, outc);
-               napms(1);
+               napms(s_option);
            }
        } else if (VALID_STRING(exit_attribute_mode)
                   && VALID_STRING(enter_reverse_mode)) {
@@ -141,7 +205,7 @@ main(int argc GCC_UNUSED,
                outs((ranf() > 0.6)
                     ? enter_reverse_mode
                     : exit_attribute_mode);
-               napms(1);
+               napms(s_option);
            }
        }
        outc(p);
index 477c4a14ef116b60854324901ce83b86c725d7be..b0adfe186e9e3b92cfc92dfb27f5ba43149e85b4 100644 (file)
@@ -29,7 +29,7 @@
 /*
  * Author: Thomas E. Dickey
  *
- * $Id: dots_curses.c,v 1.7 2017/10/11 08:16:33 tom Exp $
+ * $Id: dots_curses.c,v 1.9 2017/10/22 00:44:39 tom Exp $
  *
  * A simple demo of the curses interface used for comparison with termcap.
  */
@@ -84,20 +84,77 @@ set_colors(int fg, int bg)
     }
 }
 
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+       "Usage: dots_curses [options]"
+       ,""
+       ,"Options:"
+       ," -T TERM  override $TERM"
+#if HAVE_USE_DEFAULT_COLORS
+       ," -d       invoke use_default_colors()"
+#endif
+       ," -e       allow environment $LINES / $COLUMNS"
+       ," -m SIZE  set margin (default: 2)"
+       ," -s MSECS delay 1% of the time (default: 1 msecs)"
+    };
+    size_t n;
+
+    for (n = 0; n < SIZEOF(msg); n++)
+       fprintf(stderr, "%s\n", msg[n]);
+
+    ExitProgram(EXIT_FAILURE);
+}
+
 int
-main(int argc GCC_UNUSED,
-     char *argv[]GCC_UNUSED)
+main(int argc, char *argv[])
 {
     int x, y, z, p;
     int fg, bg;
     double r;
     double c;
+#if HAVE_USE_DEFAULT_COLORS
+    bool d_option = FALSE;
+#endif
+    int m_option = 2;
+    int s_option = 1;
+
+    while ((x = getopt(argc, argv, "T:dem:s:")) != -1) {
+       switch (x) {
+       case 'T':
+           putenv(strcat(strcpy(malloc(6 + strlen(optarg)), "TERM="), optarg));
+           break;
+#if HAVE_USE_DEFAULT_COLORS
+       case 'd':
+           d_option = TRUE;
+           break;
+#endif
+       case 'e':
+           use_env(TRUE);
+           break;
+       case 'm':
+           m_option = atoi(optarg);
+           break;
+       case 's':
+           s_option = atoi(optarg);
+           break;
+       default:
+           usage();
+           break;
+       }
+    }
 
     srand((unsigned) time(0));
 
     InitAndCatch(initscr(), onsig);
     if (has_colors()) {
        start_color();
+#if HAVE_USE_DEFAULT_COLORS
+       if (d_option)
+           use_default_colors();
+#endif
        for (fg = 0; fg < COLORS; fg++) {
            for (bg = 0; bg < COLORS; bg++) {
                int pair = mypair(fg, bg);
@@ -107,15 +164,15 @@ main(int argc GCC_UNUSED,
        }
     }
 
-    r = (double) (LINES - 4);
-    c = (double) (COLS - 4);
+    r = (double) (LINES - (m_option * 2));
+    c = (double) (COLS - (m_option * 2));
     started = time((time_t *) 0);
 
     fg = COLOR_WHITE;
     bg = COLOR_BLACK;
     while (!interrupted) {
-       x = (int) (c * ranf()) + 2;
-       y = (int) (r * ranf()) + 2;
+       x = (int) (c * ranf()) + m_option;
+       y = (int) (r * ranf()) + m_option;
        p = (ranf() > 0.9) ? '*' : ' ';
 
        move(y, x);
@@ -126,7 +183,7 @@ main(int argc GCC_UNUSED,
                attron(COLOR_PAIR(mypair(fg, bg)));
            } else {
                set_colors(fg, bg = z);
-               napms(1);
+               napms(s_option);
            }
        } else {
            if (ranf() <= 0.01) {
@@ -135,7 +192,7 @@ main(int argc GCC_UNUSED,
                } else {
                    attroff(A_REVERSE);
                }
-               napms(1);
+               napms(s_option);
            }
        }
        AddCh(p);
index d6ce9329014a5a761fc6650800d6da4e3ad09321..2a2cdf5429be709d449ce9a621670c329c18f334 100644 (file)
@@ -29,7 +29,7 @@
 /*
  * Author: Thomas E. Dickey - 2007
  *
- * $Id: dots_mvcur.c,v 1.15 2017/10/11 08:15:46 tom Exp $
+ * $Id: dots_mvcur.c,v 1.17 2017/10/22 00:44:39 tom Exp $
  *
  * A simple demo of the terminfo interface, and mvcur.
  */
@@ -97,6 +97,40 @@ ranf(void)
     return ((double) r / 32768.);
 }
 
+static int
+get_number(const char *cap, int map)
+{
+    int result = map;
+    if (cap != 0) {
+       int check = tigetnum(cap);
+       if (check > 0)
+           result = check;
+    }
+    return result;
+}
+
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+       "Usage: dots_termcap [options]"
+       ,""
+       ,"Options:"
+       ," -T TERM  override $TERM"
+       ," -e       allow environment $LINES / $COLUMNS"
+       ," -f       use tigetnum rather than <term.h> mapping"
+       ," -m SIZE  set margin (default: 2)"
+       ," -s MSECS delay 1% of the time (default: 1 msecs)"
+    };
+    size_t n;
+
+    for (n = 0; n < SIZEOF(msg); n++)
+       fprintf(stderr, "%s\n", msg[n]);
+
+    ExitProgram(EXIT_FAILURE);
+}
+
 int
 main(int argc GCC_UNUSED,
      char *argv[]GCC_UNUSED)
@@ -107,6 +141,32 @@ main(int argc GCC_UNUSED,
     double c;
     SCREEN *sp;
     int my_colors;
+    int f_option = 0;
+    int m_option = 2;
+    int s_option = 1;
+
+    while ((x = getopt(argc, argv, "T:efm:s:")) != -1) {
+       switch (x) {
+       case 'T':
+           putenv(strcat(strcpy(malloc(6 + strlen(optarg)), "TERM="), optarg));
+           break;
+       case 'e':
+           use_env(TRUE);
+           break;
+       case 'f':
+           f_option = 1;
+           break;
+       case 'm':
+           m_option = atoi(optarg);
+           break;
+       case 's':
+           s_option = atoi(optarg);
+           break;
+       default:
+           usage();
+           break;
+       }
+    }
 
     InitAndCatch((sp = newterm((char *) 0, stdout, stdin)), onsig);
     refresh();                 /* needed with Solaris curses to cancel endwin */
@@ -121,7 +181,9 @@ main(int argc GCC_UNUSED,
     outs(clear_screen);
     outs(cursor_home);
     outs(cursor_invisible);
-    my_colors = max_colors;
+
+#define GetNumber(ln,sn) get_number(f_option ? #sn : 0, ln)
+    my_colors = GetNumber(max_colors, colors);
     if (my_colors > 1) {
        if (!VALID_STRING(set_a_foreground)
            || !VALID_STRING(set_a_background)
@@ -129,13 +191,13 @@ main(int argc GCC_UNUSED,
            my_colors = -1;
     }
 
-    r = (double) (lines - 4);
-    c = (double) (columns - 4);
+    r = (double) (GetNumber(lines, lines) - (m_option * 2));
+    c = (double) (GetNumber(columns, cols) - (m_option * 2));
     started = time((time_t *) 0);
 
     while (!interrupted) {
-       x = (int) (c * ranf()) + 2;
-       y = (int) (r * ranf()) + 2;
+       x = (int) (c * ranf()) + m_option;
+       y = (int) (r * ranf()) + m_option;
        p = (ranf() > 0.9) ? '*' : ' ';
 
        if (mvcur(y0, x0, y, x) != ERR) {
@@ -149,7 +211,7 @@ main(int argc GCC_UNUSED,
                tputs(tparm2(set_a_foreground, z), 1, outc);
            } else {
                tputs(tparm2(set_a_background, z), 1, outc);
-               napms(1);
+               napms(s_option);
            }
        } else if (VALID_STRING(exit_attribute_mode)
                   && VALID_STRING(enter_reverse_mode)) {
@@ -157,7 +219,7 @@ main(int argc GCC_UNUSED,
                outs((ranf() > 0.6)
                     ? enter_reverse_mode
                     : exit_attribute_mode);
-               napms(1);
+               napms(s_option);
            }
        }
        outc(p);
index c3eef5cf43087ac1c28a5b6cb1eef6ec98cbfb4a..e9c34bace2da51e42cc374509aa2c40c267877ef 100644 (file)
@@ -29,7 +29,7 @@
 /*
  * Author: Thomas E. Dickey
  *
- * $Id: dots_termcap.c,v 1.12 2017/10/11 08:15:07 tom Exp $
+ * $Id: dots_termcap.c,v 1.15 2017/10/22 00:49:45 tom Exp $
  *
  * A simple demo of the termcap interface.
  */
@@ -151,36 +151,96 @@ ranf(void)
 static void
 my_napms(int ms)
 {
+    if (ms > 0) {
 #if defined(__MINGW32__) || !HAVE_GETTIMEOFDAY
-    Sleep((DWORD) ms);
+       Sleep((DWORD) ms);
 #else
-    struct timeval data;
-    data.tv_sec = 0;
-    data.tv_usec = ms * 1000;
-    select(0, NULL, NULL, NULL, &data);
+       struct timeval data;
+       data.tv_sec = 0;
+       data.tv_usec = ms * 1000;
+       select(0, NULL, NULL, NULL, &data);
 #endif
+    }
+}
+
+static int
+get_number(const char *cap, const char *env)
+{
+    int result = tgetnum(cap);
+    char *value = env ? getenv(env) : 0;
+    if (value != 0 && *value != 0) {
+       char *next = 0;
+       long check = strtol(value, &next, 10);
+       if (check > 0 && *next == '\0')
+           result = (int) check;
+    }
+    return result;
+}
+
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+       "Usage: dots_termcap [options]"
+       ,""
+       ,"Options:"
+       ," -T TERM  override $TERM"
+       ," -e       allow environment $LINES / $COLUMNS"
+       ," -m SIZE  set margin (default: 2)"
+       ," -s MSECS delay 1% of the time (default: 1 msecs)"
+    };
+    size_t n;
+
+    for (n = 0; n < SIZEOF(msg); n++)
+       fprintf(stderr, "%s\n", msg[n]);
+
+    ExitProgram(EXIT_FAILURE);
 }
 
 int
-main(int argc GCC_UNUSED,
-     char *argv[]GCC_UNUSED)
+main(int argc, char *argv[])
 {
     int x, y, z, p;
     int num_colors;
     int num_lines;
     int num_columns;
+    int e_option = 0;
+    int m_option = 2;
+    int s_option = 1;
     double r;
     double c;
     char buffer[1024];
     char area[1024];
     char *name;
 
-    srand((unsigned) time(0));
+    while ((x = getopt(argc, argv, "T:em:s:")) != -1) {
+       switch (x) {
+       case 'T':
+           putenv(strcat(strcpy(malloc(6 + strlen(optarg)), "TERM="), optarg));
+           break;
+       case 'e':
+           e_option = 1;
+           break;
+       case 'm':
+           m_option = atoi(optarg);
+           break;
+       case 's':
+           s_option = atoi(optarg);
+           break;
+       default:
+           usage();
+           break;
+       }
+    }
 
     if ((name = getenv("TERM")) == 0) {
        fprintf(stderr, "TERM is not set\n");
        ExitProgram(EXIT_FAILURE);
     }
+
+    srand((unsigned) time(0));
+
     InitAndCatch(z = tgetent(buffer, name), onsig);
     if (z < 0) {
        fprintf(stderr, "terminal description not found\n");
@@ -195,8 +255,9 @@ main(int argc GCC_UNUSED,
     }
 
     num_colors = tgetnum("Co");
-    num_lines = tgetnum("li");
-    num_columns = tgetnum("co");
+#define GetNumber(cap,env) get_number(cap, e_option ? env : 0)
+    num_lines = GetNumber("li", "LINES");
+    num_columns = GetNumber("co", "COLUMNS");
 
     outs(t_cl);
     outs(t_vi);
@@ -207,13 +268,13 @@ main(int argc GCC_UNUSED,
            num_colors = -1;
     }
 
-    r = (double) (num_lines - 4);
-    c = (double) (num_columns - 4);
+    r = (double) (num_lines - (2 * m_option));
+    c = (double) (num_columns - (2 * m_option));
     started = time((time_t *) 0);
 
     while (!interrupted) {
-       x = (int) (c * ranf()) + 2;
-       y = (int) (r * ranf()) + 2;
+       x = (int) (c * ranf()) + m_option;
+       y = (int) (r * ranf()) + m_option;
        p = (ranf() > 0.9) ? '*' : ' ';
 
        tputs(tgoto(t_cm, x, y), 1, outc);
@@ -223,7 +284,7 @@ main(int argc GCC_UNUSED,
                tputs(tgoto(t_AF, 0, z), 1, outc);
            } else {
                tputs(tgoto(t_AB, 0, z), 1, outc);
-               my_napms(1);
+               my_napms(s_option);
            }
        } else if (VALID_STRING(t_me)
                   && VALID_STRING(t_mr)) {
@@ -231,7 +292,7 @@ main(int argc GCC_UNUSED,
                outs((ranf() > 0.6)
                     ? t_mr
                     : t_me);
-               my_napms(1);
+               my_napms(s_option);
            }
        }
        outc(p);
index abf0a00ae030b4dfc03b3522290f0f1162f34c7a..3fddd63016b2e395dccd057889eb0b88b16a4aa4 100644 (file)
@@ -29,7 +29,7 @@
 /*
  * Author: Thomas E. Dickey
  *
- * $Id: dots_xcurses.c,v 1.8 2017/10/12 00:20:41 tom Exp $
+ * $Id: dots_xcurses.c,v 1.11 2017/10/22 00:44:39 tom Exp $
  *
  * A simple demo of the wide-curses interface used for comparison with termcap.
  */
@@ -55,8 +55,7 @@ static bool interrupted = FALSE;
 static long total_chars = 0;
 static time_t started;
 
-#ifdef NCURSES_VERSION
-static bool d_option = FALSE;
+#if HAVE_ALLOC_PAIR
 static bool x_option = FALSE;
 #endif
 
@@ -108,18 +107,21 @@ set_colors(int fg, int bg)
     }
 }
 
-#if defined(NCURSES_VERSION)
 static void
 usage(void)
 {
     static const char *msg[] =
     {
-       "Usage: firework [options]"
+       "Usage: dots_xcurses [options]"
        ,""
        ,"Options:"
+       ," -T TERM  override $TERM"
 #if HAVE_USE_DEFAULT_COLORS
        ," -d       invoke use_default_colors()"
 #endif
+       ," -e       allow environment $LINES / $COLUMNS"
+       ," -m SIZE  set margin (default: 2)"
+       ," -s MSECS delay 1% of the time (default: 1 msecs)"
 #if HAVE_ALLOC_PAIR
        ," -x       use alloc_pair() rather than init_pair()"
 #endif
@@ -131,26 +133,41 @@ usage(void)
 
     ExitProgram(EXIT_FAILURE);
 }
-#endif
 
 int
-main(int argc GCC_UNUSED,
-     char *argv[]GCC_UNUSED)
+main(int argc, char *argv[])
 {
-    int margin = 2;
     int x, y, z, p;
     int fg, bg, ch;
     wchar_t wch[2];
     int pair;
     double r;
     double c;
+#if HAVE_USE_DEFAULT_COLORS
+    bool d_option = FALSE;
+#endif
+    int m_option = 2;
+    int s_option = 1;
 
-#if defined(NCURSES_VERSION)
-    while ((ch = getopt(argc, argv, "dx")) != -1) {
+    while ((ch = getopt(argc, argv, "T:dem:s:x")) != -1) {
        switch (ch) {
+       case 'T':
+           putenv(strcat(strcpy(malloc(6 + strlen(optarg)), "TERM="), optarg));
+           break;
+#if HAVE_USE_DEFAULT_COLORS
        case 'd':
            d_option = TRUE;
            break;
+#endif
+       case 'e':
+           use_env(TRUE);
+           break;
+       case 'm':
+           m_option = atoi(optarg);
+           break;
+       case 's':
+           s_option = atoi(optarg);
+           break;
 #if HAVE_ALLOC_PAIR
        case 'x':
            x_option = TRUE;
@@ -161,7 +178,6 @@ main(int argc GCC_UNUSED,
            break;
        }
     }
-#endif
 
     srand((unsigned) time(0));
 
@@ -172,9 +188,12 @@ main(int argc GCC_UNUSED,
        if (d_option)
            use_default_colors();
 #endif
+#if HAVE_ALLOC_PAIR
        if (x_option) {
            ;                   /* nothing */
-       } else {
+       } else
+#endif
+       {
            for (fg = 0; fg < COLORS; fg++) {
                for (bg = 0; bg < COLORS; bg++) {
                    pair = mypair(fg, bg);
@@ -186,8 +205,8 @@ main(int argc GCC_UNUSED,
        }
     }
 
-    r = (double) (LINES - (2 * margin));
-    c = (double) (COLS - (2 * margin));
+    r = (double) (LINES - (2 * m_option));
+    c = (double) (COLS - (2 * m_option));
     started = time((time_t *) 0);
 
     fg = COLOR_WHITE;
@@ -195,8 +214,8 @@ main(int argc GCC_UNUSED,
     pair = 0;
     wch[1] = 0;
     while (!interrupted) {
-       x = (int) (c * ranf()) + margin;
-       y = (int) (r * ranf()) + margin;
+       x = (int) (c * ranf()) + m_option;
+       y = (int) (r * ranf()) + m_option;
        p = (ranf() > 0.9) ? '*' : ' ';
 
        move(y, x);
@@ -206,7 +225,7 @@ main(int argc GCC_UNUSED,
                set_colors(fg = z, bg);
            } else {
                set_colors(fg, bg = z);
-               napms(1);
+               napms(s_option);
            }
        } else {
            if (ranf() <= 0.01) {
@@ -215,7 +234,7 @@ main(int argc GCC_UNUSED,
                } else {
                    attr_off(WA_REVERSE, NULL);
                }
-               napms(1);
+               napms(s_option);
            }
        }
        wch[0] = p;
index be8e68fc6fa404f1b2cefffadea3b78cf94d37ae..19ba9acd07e34a20f710d5dd034945af506810ff 100644 (file)
@@ -26,7 +26,7 @@
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: echochar.c,v 1.17 2017/10/11 08:16:12 tom Exp $
+ * $Id: echochar.c,v 1.18 2017/10/18 23:04:52 tom Exp $
  *
  * Demonstrate the echochar function (compare to dots.c).
  * Thomas Dickey - 2006/11/4
@@ -96,7 +96,7 @@ main(int argc GCC_UNUSED,
            opt_r = TRUE;
            break;
        default:
-           fprintf(stderr, "usage: echochar [-r]\n");
+           fprintf(stderr, "Usage: echochar [-r]\n");
            ExitProgram(EXIT_FAILURE);
        }
     }
index 1bff3a284081c05aff6c644a5994b15bda644ce3..72047a20cc97da653c315d80d9abac08bca48d9b 100644 (file)
@@ -26,7 +26,7 @@
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: ins_wide.c,v 1.23 2017/04/08 22:14:03 tom Exp $
+ * $Id: ins_wide.c,v 1.24 2017/10/18 23:03:57 tom Exp $
  *
  * Demonstrate the wins_wstr() and wins_wch functions.
  * Thomas Dickey - 2002/11/23
@@ -458,7 +458,7 @@ usage(void)
 {
     static const char *tbl[] =
     {
-       "Usage: inserts [options]"
+       "Usage: ins_wide [options]"
        ,""
        ,"Options:"
        ,"  -f FILE read data from given file"
index c1ed6ca736be86783687ae141c22e4d9196223ba..12717880514a48691192270ee46aeceb1b5962e8 100644 (file)
@@ -40,7 +40,7 @@ AUTHOR
    Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993
            Thomas E. Dickey (beginning revision 1.27 in 1996).
 
-$Id: ncurses.c,v 1.469 2017/10/01 18:22:48 tom Exp $
+$Id: ncurses.c,v 1.470 2017/10/20 21:20:47 tom Exp $
 
 ***************************************************************************/
 
@@ -1840,7 +1840,7 @@ get_wide_background(void)
     attr_t attr;
     cchar_t ch;
     NCURSES_PAIRS_T pair;
-    wchar_t wch[10];
+    wchar_t wch[CCHARW_MAX];
 
     memset(&ch, 0, sizeof(ch));
     if (getbkgrnd(&ch) != ERR) {
index 6cd4c60811f5fc3630cbbe2f88bd3f1ee66da3b8..4be1bef5eaab462f941b3ec9e3e3e7ffbcd2ecec 100644 (file)
@@ -26,7 +26,7 @@
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: savescreen.c,v 1.35 2017/09/29 23:42:22 tom Exp $
+ * $Id: savescreen.c,v 1.36 2017/10/20 21:20:34 tom Exp $
  *
  * Demonstrate save/restore functions from the curses library.
  * Thomas Dickey - 2007/7/14
@@ -65,7 +65,7 @@ static bool keep_dumps = FALSE;
 static wchar_t
 BaseChar(cchar_t data)
 {
-    wchar_t my_wchar[sizeof(cchar_t)];
+    wchar_t my_wchar[CCHARW_MAX];
     attr_t my_attr;
     short my_pair;
     getcchar(&data, my_wchar, &my_attr, &my_pair, NULL);
index 00062e8edb138e196e4cb8f341554c10131fe72f..aa06a3e8d6bd3e3bd1747806acef62d3d9db79bb 100644 (file)
@@ -33,7 +33,8 @@
  *
  * modified by Thomas Dickey <dickey@clark.net> July 1995 to demonstrate
  * the use of 'resizeterm()', and May 2000 to illustrate wide-character
- * handling.
+ * handling.  This program intentionally does not use pads, to allow testing
+ * with less-capable implementations of curses.
  *
  * Takes a filename argument.  It's a simple file-viewer with various
  * scroll-up and scroll-down commands.
@@ -50,7 +51,7 @@
  * scroll operation worked, and the refresh() code only had to do a
  * partial repaint.
  *
- * $Id: view.c,v 1.111 2017/10/15 00:56:58 tom Exp $
+ * $Id: view.c,v 1.129 2017/10/22 00:49:23 tom Exp $
  */
 
 #include <test.priv.h>
 
 static void finish(int sig) GCC_NORETURN;
 
-#if HAVE_TERMIOS_H
-# include <termios.h>
-#else
-#if !defined(__MINGW32__)
-# include <sgtty.h>
-#endif
-#endif
-
-#if !defined(sun) || !HAVE_TERMIOS_H
-# if HAVE_SYS_IOCTL_H
-#  include <sys/ioctl.h>
-# endif
-#endif
-
 #define my_pair 1
 
-/* This is needed to compile 'struct winsize' */
-#if NEED_PTEM_H
-#include <sys/stream.h>
-#include <sys/ptem.h>
-#endif
-
 #undef CTRL
 #define CTRL(x)        ((x) & 0x1f)
 
-#if defined(SIGWINCH) && defined(TIOCGWINSZ) && HAVE_RESIZE_TERM
-#define CAN_RESIZE 1
-#else
-#define CAN_RESIZE 0
-#endif
-
-#if CAN_RESIZE
-static int interrupted;
-static bool waiting = FALSE;
-#endif
-
 static int shift = 0;
 static bool try_color = FALSE;
 
@@ -108,40 +78,20 @@ static NCURSES_CH_T **vec_lines;
 static NCURSES_CH_T **lptr;
 static int num_lines;
 
+#if USE_WIDEC_SUPPORT
+static bool n_option = FALSE;
+#endif
+
 static void usage(void) GCC_NORETURN;
 
 static void
 failed(const char *msg)
 {
+    endwin();
     fprintf(stderr, "%s\n", msg);
     ExitProgram(EXIT_FAILURE);
 }
 
-static void
-usage(void)
-{
-    static const char *msg[] =
-    {
-       "Usage: view [options] file"
-       ,""
-       ,"Options:"
-       ," -c       use color if terminal supports it"
-       ," -i       ignore INT, QUIT, TERM signals"
-#if defined(KEY_RESIZE)
-       ," -r       use old-style sigwinch handler rather than KEY_RESIZE"
-#endif
-       ," -s       start in single-step mode, waiting for input"
-#ifdef TRACE
-       ," -t       trace screen updates"
-       ," -T NUM   specify trace mask"
-#endif
-    };
-    size_t n;
-    for (n = 0; n < SIZEOF(msg); n++)
-       fprintf(stderr, "%s\n", msg[n]);
-    ExitProgram(EXIT_FAILURE);
-}
-
 static int
 ch_len(NCURSES_CH_T * src)
 {
@@ -153,7 +103,8 @@ ch_len(NCURSES_CH_T * src)
 #if USE_WIDEC_SUPPORT
     for (;;) {
        TEST_CCHAR(src, count, {
-           ++result;
+           int len = wcwidth(test_wch[0]);
+           result += (len > 0) ? len : 1;
            ++src;
        }
        , {
@@ -167,69 +118,6 @@ ch_len(NCURSES_CH_T * src)
     return result;
 }
 
-/*
- * Allocate a string into an array of chtype's.  If UTF-8 mode is
- * active, translate the string accordingly.
- */
-static NCURSES_CH_T *
-ch_dup(char *src)
-{
-    unsigned len = (unsigned) strlen(src);
-    NCURSES_CH_T *dst = typeMalloc(NCURSES_CH_T, len + 1);
-    size_t j, k;
-#if USE_WIDEC_SUPPORT
-    wchar_t wstr[CCHARW_MAX + 1];
-    wchar_t wch;
-    int l = 0;
-    size_t rc;
-    int width;
-#ifndef state_unused
-    mbstate_t state;
-#endif
-#endif /* USE_WIDEC_SUPPORT */
-
-#if USE_WIDEC_SUPPORT
-    reset_mbytes(state);
-#endif
-    for (j = k = 0; j < len; j++) {
-#if USE_WIDEC_SUPPORT
-       rc = (size_t) check_mbytes(wch, src + j, len - j, state);
-       if (rc == (size_t) -1 || rc == (size_t) -2) {
-           break;
-       }
-       j += rc - 1;
-       width = wcwidth(wch);
-       if (width == 0) {
-           if (l == 0) {
-               wstr[l++] = L' ';
-           }
-       } else if ((l > 0) || (l == CCHARW_MAX)) {
-           wstr[l] = L'\0';
-           l = 0;
-           if (setcchar(dst + k, wstr, 0, 0, NULL) != OK) {
-               break;
-           }
-           ++k;
-       }
-       wstr[l++] = wch;
-#else
-       dst[k++] = (chtype) UChar(src[j]);
-#endif
-    }
-#if USE_WIDEC_SUPPORT
-    if (l > 0) {
-       wstr[l] = L'\0';
-       if (setcchar(dst + k, wstr, 0, 0, NULL) == OK)
-           ++k;
-    }
-    wstr[0] = L'\0';
-    setcchar(dst + k, wstr, 0, 0, NULL);
-#else
-    dst[k] = 0;
-#endif
-    return dst;
-}
-
 static void
 finish(int sig)
 {
@@ -254,21 +142,11 @@ show_all(const char *tag)
     NCURSES_CH_T *s;
     time_t this_time;
 
-#if CAN_RESIZE
     _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
-               "%.20s (%3dx%3d) col %d ", tag, LINES, COLS, shift);
+               "view %.*s", (int) strlen(tag), tag);
     i = (int) strlen(temp);
-    if ((i + 7) < (int) sizeof(temp)) {
-       _nc_SPRINTF(temp + i, _nc_SLIMIT(sizeof(temp) - (size_t) i)
-                   "view %.*s",
-                   (int) (sizeof(temp) - 7 - (size_t) i),
-                   fname);
-    }
-#else
-    (void) tag;
-    _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
-               "view %.*s", (int) sizeof(temp) - 7, fname);
-#endif
+    _nc_SPRINTF(temp + i, _nc_SLIMIT(sizeof(temp) - i)
+               " %.*s", (int) sizeof(temp) - i - 2, fname);
     move(0, 0);
     printw("%.*s", COLS, temp);
     clrtoeol();
@@ -284,8 +162,14 @@ show_all(const char *tag)
     for (i = 1; i < LINES; i++) {
        int len;
        int actual = (int) (lptr + i - vec_lines);
-       if (actual >= num_lines) {
-           clrtobot();
+       if (actual > num_lines) {
+           if (i < LINES - 1) {
+               int y, x;
+               getyx(stdscr, y, x);
+               move(i, 0);
+               clrtobot();
+               move(y, x);
+           }
            break;
        }
        move(i, 0);
@@ -297,7 +181,35 @@ show_all(const char *tag)
        len = ch_len(s);
        if (len > shift) {
 #if USE_WIDEC_SUPPORT
-           add_wchstr(s + shift);
+           /*
+            * An index into an array of cchar_t's is not necessarily the same
+            * as the column-offset.  A pad would do this directly.  Here we
+            * must translate (or compute a table of offsets).
+            */
+           {
+               int j;
+               int width = 1, count;
+               for (j = actual = 0; j < shift; ++j) {
+                   TEST_CCHAR(s + j, count, {
+                       width = wcwidth(test_wch[0]);
+                   }
+                   , {
+                       width = 1;
+                   });
+                   actual += width;
+                   if (actual > shift) {
+                       break;
+                   } else if (actual == shift) {
+                       ++j;
+                       break;
+                   }
+               }
+               if (actual < len) {
+                   if (actual > shift)
+                       addch('<');
+                   add_wchstr(s + j + (actual > shift));
+               }
+           }
 #else
            addchstr(s + shift);
 #endif
@@ -312,47 +224,19 @@ show_all(const char *tag)
     refresh();
 }
 
-#if CAN_RESIZE
-/*
- * This uses functions that are "unsafe", but it seems to work on SunOS. 
- * Usually: the "unsafe" refers to the functions that POSIX lists which may be
- * called from a signal handler.  Those do not include buffered I/O, which is
- * used for instance in wrefresh().  To be really portable, you should use the
- * KEY_RESIZE return (which relies on ncurses' sigwinch handler).
- *
- * The 'wrefresh(curscr)' is needed to force the refresh to start from the top
- * of the screen -- some xterms mangle the bitmap while resizing.
- */
-static void
-adjust(int sig)
-{
-    if (waiting || sig == 0) {
-       struct winsize size;
-
-       if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
-           resize_term(size.ws_row, size.ws_col);
-           wrefresh(curscr);
-           show_all(sig ? "SIGWINCH" : "interrupt");
-       }
-       interrupted = FALSE;
-    } else {
-       interrupted = TRUE;
-    }
-    (void) signal(SIGWINCH, adjust);   /* some systems need this */
-}
-#endif /* CAN_RESIZE */
-
 static void
 read_file(const char *filename)
 {
     FILE *fp;
     int pass;
     int k;
+    int width;
     size_t j;
     size_t len;
     struct stat sb;
     char *my_blob;
     char **my_vec = 0;
+    WINDOW *my_win;
 
     if (stat(filename, &sb) != 0
        || (sb.st_mode & S_IFMT) != S_IFREG) {
@@ -396,67 +280,112 @@ read_file(const char *filename)
            failed("cannot allocate line-vector #1");
        }
     }
+
+#if USE_WIDEC_SUPPORT
+    if (!memcmp("", my_blob, 3)) {
+       char *s = my_blob + 3;
+       char *d = my_blob;
+       Trace(("trim BOM"));
+       do {
+       } while ((*d++ = *s++) != '\0');
+    }
+#endif
+
+    width = (int) strlen(my_vec[0]);
+    for (k = 1; my_vec[k]; ++k) {
+       int check = (int) (my_vec[k] - my_vec[k - 1]);
+       if (width < check)
+           width = check;
+    }
+    width = (width + 1) * 5;
+    my_win = newwin(2, width, 0, 0);
+    if (my_win == 0)
+       failed("cannot allocate temporary window");
+
     if ((vec_lines = typeCalloc(NCURSES_CH_T *, (size_t) num_lines + 2)) == 0)
        failed("cannot allocate line-vector #2");
 
+    /*
+     * Use the curses library for rendering, including tab-conversion.  This
+     * will not make the resulting array's indices correspond to column for
+     * lines containing double-width cells because the "in_wch" functions will
+     * ignore the skipped cells.  Use pads for that sort of thing.
+     */
     Trace(("slurp the file"));
-    for (k = 0; k < num_lines; ++k) {
-       char *buf = my_vec[k];
-       char temp[BUFSIZ], *s, *d;
-       int col;
-
-       lptr = &vec_lines[k];
-
+    for (k = 0; my_vec[k]; ++k) {
+       char *s;
+       int y, x;
 #if USE_WIDEC_SUPPORT
-       if (lptr == vec_lines) {
-           if (!memcmp("", buf, 3)) {
-               Trace(("trim BOM"));
-               s = buf + 3;
-               d = buf;
-               do {
-               } while ((*d++ = *s++) != '\0');
-           }
-       }
+       char *last = my_vec[k] + (int) strlen(my_vec[k]);
+       wchar_t wch[2];
+       size_t rc;
+#ifndef state_unused
+       mbstate_t state;
 #endif
+#endif /* USE_WIDEC_SUPPORT */
 
-       /* convert tabs and nonprinting chars so that shift will work properly */
-       for (s = buf, d = temp, col = 0; (*d = *s) != '\0'; s++) {
-           if (*d == '\r') {
-               if (s[1] == '\n') {
-                   continue;
-               } else {
+       werase(my_win);
+       wmove(my_win, 0, 0);
+#if USE_WIDEC_SUPPORT
+       wch[1] = 0;
+       reset_mbytes(state);
+#endif
+       for (s = my_vec[k]; *s != '\0'; ++s) {
+#if USE_WIDEC_SUPPORT
+           if (!n_option) {
+               rc = (size_t) check_mbytes(wch[0], s, (size_t) (last - s), state);
+               if ((long) rc == -1 || (long) rc == -2) {
                    break;
                }
-           }
-           if (*d == '\n') {
-               *d = '\0';
-               break;
-           } else if (*d == '\t') {
-               col = (col | 7) + 1;
-               while ((d - temp) != col)
-                   *d++ = ' ';
+               s += rc - 1;
+               waddwstr(my_win, wch);
            } else
+#endif
+               waddch(my_win, *s & 0xff);
+       }
+       getyx(my_win, y, x);
+       if (y)
+           x = width - 1;
+       wmove(my_win, 0, 0);
+       if ((vec_lines[k] = typeCalloc(NCURSES_CH_T, (size_t) x + 1)) == 0)
+           failed("cannot allocate line-vector #3");
 #if USE_WIDEC_SUPPORT
-               col++, d++;
+       win_wchnstr(my_win, vec_lines[k], x);
 #else
-           if (isprint(UChar(*d))) {
-               col++;
-               d++;
-           } else {
-               _nc_SPRINTF(d, _nc_SLIMIT(sizeof(temp) - (d - buf))
-                           "\\%03o", UChar(*s));
-               d += strlen(d);
-               col = (int) (d - temp);
-           }
+       winchnstr(my_win, vec_lines[k], x);
 #endif
-       }
-       *lptr = ch_dup(temp);
     }
 
+    delwin(my_win);
     free(my_vec);
     free(my_blob);
 }
 
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+       "Usage: view [options] file"
+       ,""
+       ,"Options:"
+       ," -c       use color if terminal supports it"
+       ," -i       ignore INT, QUIT, TERM signals"
+#if USE_WIDEC_SUPPORT
+       ," -n       use waddch (bytes) rather then wadd_wch (wide-chars)"
+#endif
+       ," -s       start in single-step mode, waiting for input"
+#ifdef TRACE
+       ," -t       trace screen updates"
+       ," -T NUM   specify trace mask"
+#endif
+    };
+    size_t n;
+    for (n = 0; n < SIZEOF(msg); n++)
+       fprintf(stderr, "%s\n", msg[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -492,9 +421,6 @@ main(int argc, char *argv[])
     bool got_number = FALSE;
     bool ignore_sigs = FALSE;
     bool single_step = FALSE;
-#if CAN_RESIZE
-    bool nonposix_resize = FALSE;
-#endif
     const char *my_label = "Input";
 
     setlocale(LC_ALL, "");
@@ -507,11 +433,6 @@ main(int argc, char *argv[])
        case 'i':
            ignore_sigs = TRUE;
            break;
-#if CAN_RESIZE
-       case 'r':
-           nonposix_resize = TRUE;
-           break;
-#endif
        case 's':
            single_step = TRUE;
            break;
@@ -536,13 +457,6 @@ main(int argc, char *argv[])
     if (optind + 1 != argc)
        usage();
 
-    read_file(fname = argv[optind]);
-
-#if CAN_RESIZE
-    if (nonposix_resize)
-       (void) signal(SIGWINCH, adjust);        /* arrange interrupts to resize */
-#endif
-
     InitAndCatch(initscr(), ignore_sigs ? SIG_IGN : finish);
     keypad(stdscr, TRUE);      /* enable keyboard mapping */
     (void) nonl();             /* tell curses not to do NL->CR/NL on output */
@@ -552,6 +466,8 @@ main(int argc, char *argv[])
        nodelay(stdscr, TRUE);
     idlok(stdscr, TRUE);       /* allow use of insert/delete line */
 
+    read_file(fname = argv[optind]);
+
     if (try_color) {
        if (has_colors()) {
            start_color();
@@ -570,17 +486,7 @@ main(int argc, char *argv[])
            show_all(my_label);
 
        for (;;) {
-#if CAN_RESIZE
-           if (interrupted) {
-               adjust(0);
-               my_label = "interrupt";
-           }
-           waiting = TRUE;
            c = getch();
-           waiting = FALSE;
-#else
-           c = getch();
-#endif
            if ((c < 127) && isdigit(c)) {
                if (!got_number) {
                    MvPrintw(0, 0, "Count: ");
@@ -647,19 +553,23 @@ main(int argc, char *argv[])
        case CTRL('F'):
            /* FALLTHRU */
        case KEY_NPAGE:
-           if ((lptr - vec_lines) < (num_lines - 5))
-               lptr += (LINES - 1);
-           else
-               lptr = (vec_lines + num_lines - 2);
+           for (i = 0; i < n; i++) {
+               if ((lptr - vec_lines) < (num_lines - 5))
+                   lptr += (LINES - 1);
+               else
+                   lptr = (vec_lines + num_lines - 2);
+           }
            break;
 
        case CTRL('B'):
            /* FALLTHRU */
        case KEY_PPAGE:
-           if ((lptr - vec_lines) >= LINES)
-               lptr -= (LINES - 1);
-           else
-               lptr = vec_lines;
+           for (i = 0; i < n; i++) {
+               if ((lptr - vec_lines) >= LINES)
+                   lptr -= (LINES - 1);
+               else
+                   lptr = vec_lines;
+           }
            break;
 
        case 'r':
diff --git a/test/widechars-utf8-tabs.txt b/test/widechars-utf8-tabs.txt
new file mode 100644 (file)
index 0000000..ca605a1
--- /dev/null
@@ -0,0 +1,15 @@
+APPLE        -- It's an ï¼¡ï¼°ï¼°ï¼¬ï¼¥.
+DOG              -- No, that's not my ï¼¤ï¼¯ï¼§.
+ORANGE     -- Yeah, that's ï¼ªï¼µï¼©ï¼£ï¼¹.
+CHICKEN  -- Normally not a ï¼°ï¼¥ï¼´.
+CAT              -- No, never put a ï¼¤ï¼¯ï¼§ and a ï¼£ï¼¡ï¼´ together!
+FISH   -- Cats like ï¼¦ï¼©ï¼³ï¼¨.
+LEMON        -- You ï¼«ï¼®ï¼¯ï¼· how it ï¼´ï¼¡ï¼³ï¼´ï¼¥ï¼³.
+----+----1----+----2----+----3----+----4
+APPLE        -- It's an ï¼¡ï¼°ï¼°ï¼¬ï¼¥.
+ ï¼¡ï¼°ï¼°ï¼¬ï¼¥       -- It's an ï¼¡ï¼°ï¼°ï¼¬ï¼¥.
+  ï¼¡ï¼°ï¼°ï¼¬ï¼¥      -- It's an ï¼¡ï¼°ï¼°ï¼¬ï¼¥.
+   ï¼¡ï¼°ï¼°ï¼¬ï¼¥     -- It's an ï¼¡ï¼°ï¼°ï¼¬ï¼¥.
+    ï¼¡ï¼°ï¼°ï¼¬ï¼¥    -- It's an ï¼¡ï¼°ï¼°ï¼¬ï¼¥.
+     ï¼¡ï¼°ï¼°ï¼¬ï¼¥   -- It's an ï¼¡ï¼°ï¼°ï¼¬ï¼¥.
+----+----1----+----2----+----3----+----4