From: Thomas E. Dickey Date: Sun, 3 Feb 2008 20:52:12 +0000 (+0000) Subject: ncurses 5.6 - patch 20080203 X-Git-Tag: v5.7~37 X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=commitdiff_plain;h=b779f5fb4516b3e6d1bc8880ea68923efb761e1d;ds=sidebyside ncurses 5.6 - patch 20080203 + modify _nc_setupscreen() to set the legacy-coding value the same for both narrow/wide models. It had been set only for wide model, but is needed to make unctrl() work with locale in the narrow model. + improve waddch() and winsch() handling of EILSEQ from mbrtowc() by using unctrl() to display illegal bytes rather than trying to append further bytes to make up a valid sequence (reported by Andrey A Chernov). + modify unctrl() to check codes in 128-255 range versus isprint(). If they are not printable, and locale was set, use a "M-" or "~" sequence. + improve threading in test/worm.c (wrap refresh calls, and KEY_RESIZE handling). Now it hangs in napms(), no matter whether nanosleep() or poll() or select() are used on Linux. --- diff --git a/NEWS b/NEWS index 8c771608..16c55d06 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.1199 2008/01/19 21:10:02 tom Exp $ +-- $Id: NEWS,v 1.1204 2008/02/03 20:34:02 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,23 @@ 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. +20080203 + + modify _nc_setupscreen() to set the legacy-coding value the same + for both narrow/wide models. It had been set only for wide model, + but is needed to make unctrl() work with locale in the narrow model. + + improve waddch() and winsch() handling of EILSEQ from mbrtowc() by + using unctrl() to display illegal bytes rather than trying to append + further bytes to make up a valid sequence (reported by Andrey A + Chernov). + + modify unctrl() to check codes in 128-255 range versus isprint(). + If they are not printable, and locale was set, use a "M-" or "~" + sequence. + +20080126 + + improve threading in test/worm.c (wrap refresh calls, and KEY_RESIZE + handling). Now it hangs in napms(), no matter whether nanosleep() + or poll() or select() are used on Linux. + 20080119 + fixes to build with --disable-ext-funcs + add manpage for use_window and use_screen. diff --git a/dist.mk b/dist.mk index 1dca2a73..6c2b86fa 100644 --- 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.625 2008/01/19 18:22:11 tom Exp $ +# $Id: dist.mk,v 1.628 2008/02/03 14:36:09 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -37,7 +37,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 5 NCURSES_MINOR = 6 -NCURSES_PATCH = 20080119 +NCURSES_PATCH = 20080203 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/ncurses/base/MKunctrl.awk b/ncurses/base/MKunctrl.awk index 5d187a8c..1ba511d7 100644 --- a/ncurses/base/MKunctrl.awk +++ b/ncurses/base/MKunctrl.awk @@ -1,6 +1,6 @@ -# $Id: MKunctrl.awk,v 1.14 2007/07/28 21:13:21 tom Exp $ +# $Id: MKunctrl.awk,v 1.21 2008/02/03 20:24:30 tom Exp $ ############################################################################## -# Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. # +# Copyright (c) 1998-2007,2008 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 "Software"), # @@ -27,13 +27,20 @@ # authorization. # ############################################################################## # -# Author: Thomas E. Dickey 1997 +# Author: Thomas E. Dickey (1997-on) # BEGIN { print "/* generated by MKunctrl.awk */" print "" print "#include " + print "#include " + print "" + print "#if USE_WIDEC_SUPPORT" + print "#if HAVE_WCTYPE_H" + print "#include " + print "#endif" + print "#endif" print "" print "#undef unctrl" print "" @@ -69,6 +76,12 @@ END { } else if (ch >= 128 && ch < 160) { part = sprintf("~\\%03o", ch - 64); offset = offset + 3; + } else if (ch == 255) { + part = "~?"; + offset = offset + 3; + } else if (ch >= 160) { + part = sprintf("M-\\%03o", ch - 128); + offset = offset + 4; } else { gap = gap " " part = sprintf("\\%03o", ch); @@ -88,14 +101,13 @@ END { blob = blob "\""; print "" - print "#if NCURSES_EXT_FUNCS" if (bigstrings) { - blob = blob "\n#if NCURSES_EXT_FUNCS" + blob = blob "\n/* printable values in 128-255 range */" printf "static const short unctrl_c1[] = {" } else { printf "static const char* const unctrl_c1[] = {" } - for ( ch = 128; ch < 160; ch++ ) { + for ( ch = 128; ch < 256; ch++ ) { gap = "," if ((ch % 8) == 0) { if (ch != 128) @@ -111,7 +123,7 @@ END { if (((ch + 1) % 8) != 0) gap = gap " " } else { - if (ch >= 128 && ch < 160) { + if (ch >= 128) { printf "\"\\%03o\"", ch gap = gap " " } @@ -123,8 +135,7 @@ END { } } print "};" - print "#endif /* NCURSES_EXT_FUNCS */" - blob = blob "\"\n#endif /* NCURSES_EXT_FUNCS */\n" + blob = blob "\"\n" print "" if (bigstrings) { @@ -134,22 +145,41 @@ END { } else { stringname = "unctrl" } - print "\tint check = ChCharOf(ch);" - print "\tconst char *result;" - print "" - print "\tif (check >= 0 && check < (int)SIZEOF(unctrl_table)) {" - print "#if NCURSES_EXT_FUNCS" - print "\t\tif ((SP != 0)" - print "\t\t && (SP->_legacy_coding > 1)" - print "\t\t && (check >= 128)" - print "\t\t && (check < 160))" + print "\tint check = ChCharOf(ch);" + print "\tconst char *result;" + print "" + print "\tif (check >= 0 && check < (int)SIZEOF(unctrl_table)) {" + print "#if NCURSES_EXT_FUNCS" + print "\t\tif ((SP != 0)" + print "\t\t && (SP->_legacy_coding > 1)" + print "\t\t && (check >= 128)" + print "\t\t && (check < 160))" + printf "\t\t\tresult = %s_c1[check - 128];\n", stringname; + print "\t\telse" + print "#if USE_WIDEC_SUPPORT" + print "\t\tif ((check >= 160)" + print "\t\t && (check < 256)" + print "\t\t && ((SP != 0)" + print "\t\t && ((SP->_legacy_coding > 0)" + print "\t\t || (SP->_legacy_coding == 0" + print "\t\t && (isprint(check) || iswprint(check))))))" + printf "\t\t\tresult = %s_c1[check - 128];\n", stringname; + print "\t\telse" + print "#else" + print "\t\tif ((check >= 160)" + print "\t\t && (check < 256)" + print "\t\t && ((SP != 0)" + print "\t\t && ((SP->_legacy_coding > 0)" + print "\t\t || (SP->_legacy_coding == 0" + print "\t\t && isprint(check)))))" printf "\t\t\tresult = %s_c1[check - 128];\n", stringname; - print "\t\telse" - print "#endif /* NCURSES_EXT_FUNCS */" + print "\t\telse" + print "#endif /* USE_WIDEC_SUPPORT */" + print "#endif /* NCURSES_EXT_FUNCS */" printf "\t\t\tresult = %s_table[check];\n", stringname; - print "\t} else {" - print "\t\tresult = 0;" - print "\t}" - print "\treturn (NCURSES_CONST char *)result;" - print "}" + print "\t} else {" + print "\t\tresult = 0;" + print "\t}" + print "\treturn (NCURSES_CONST char *)result;" + print "}" } diff --git a/ncurses/base/lib_addch.c b/ncurses/base/lib_addch.c index 9d73edfd..1ef6cc58 100644 --- a/ncurses/base/lib_addch.c +++ b/ncurses/base/lib_addch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. * + * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -36,7 +36,7 @@ #include #include -MODULE_ID("$Id: lib_addch.c,v 1.104 2006/10/14 20:31:19 tom Exp $") +MODULE_ID("$Id: lib_addch.c,v 1.108 2008/02/03 18:50:27 tom Exp $") static const NCURSES_CH_T blankchar = NewChar(BLANK_TEXT); @@ -219,17 +219,15 @@ _nc_build_wch(WINDOW *win, ARG_CH_T ch) attr_t attrs = AttrOf(CHDEREF(ch)); SetChar(CHDEREF(ch), result, attrs); WINDOW_EXT(win, addch_used) = 0; - } else { - if (len == -1) { - /* - * An error occurred. We could either discard everything, - * or assume that the error was in the previous input. - * Try the latter. - */ - TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error")); - buffer[0] = CharOf(CHDEREF(ch)); - WINDOW_EXT(win, addch_used) = 1; - } + } else if (len == -1) { + /* + * An error occurred. We could either discard everything, + * or assume that the error was in the previous input. + * Try the latter. + */ + TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error")); + /* handle this with unctrl() */ + WINDOW_EXT(win, addch_used) = 0; } return len; } @@ -264,13 +262,16 @@ waddch_literal(WINDOW *win, NCURSES_CH_T ch) if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) { int len = _nc_build_wch(win, CHREF(ch)); - if (len > 0) { + if (len >= -1) { + /* handle EILSEQ */ if (is8bits(CharOf(ch))) { const char *s = unctrl((chtype) CharOf(ch)); if (s[1] != 0) { return waddstr(win, s); } } + if (len == -1) + return waddch(win, ' '); } else { return OK; } diff --git a/ncurses/base/lib_insch.c b/ncurses/base/lib_insch.c index b8a856df..9166ea52 100644 --- a/ncurses/base/lib_insch.c +++ b/ncurses/base/lib_insch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. * + * Copyright (c) 1998-2005,2008 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 * @@ -43,7 +43,7 @@ #include #include -MODULE_ID("$Id: lib_insch.c,v 1.24 2005/02/26 19:27:28 tom Exp $") +MODULE_ID("$Id: lib_insch.c,v 1.25 2008/02/03 00:14:37 tom Exp $") /* * Insert the given character, updating the current location to simplify @@ -95,7 +95,8 @@ _nc_insert_ch(WINDOW *win, chtype ch) } else if (is8bits(ChCharOf(ch)) && iscntrl(ChCharOf(ch))) { s = unctrl(ChCharOf(ch)); while (*s != '\0') { - if ((code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s))) != OK) + code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s)); + if (code != OK) break; ++s; } @@ -107,8 +108,23 @@ _nc_insert_ch(WINDOW *win, chtype ch) */ SetChar2(wch, ch); wch = _nc_render(win, wch); - if (_nc_build_wch(win, &wch) >= 0) + count = _nc_build_wch(win, &wch); + if (count > 0) { code = wins_wch(win, &wch); + } else if (count == -1) { + /* handle EILSEQ */ + if (is8bits(ch)) { + s = unctrl(ChCharOf(ch)); + while (*s != '\0') { + code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s)); + if (code != OK) + break; + ++s; + } + } else { + code = ERR; + } + } } #endif break; diff --git a/ncurses/base/lib_set_term.c b/ncurses/base/lib_set_term.c index 8c15de8b..e44850c6 100644 --- a/ncurses/base/lib_set_term.c +++ b/ncurses/base/lib_set_term.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -44,7 +44,7 @@ #include /* cur_term */ #include -MODULE_ID("$Id: lib_set_term.c,v 1.102 2007/12/29 20:36:32 tom Exp $") +MODULE_ID("$Id: lib_set_term.c,v 1.103 2008/02/03 20:31:08 tom Exp $") NCURSES_EXPORT(SCREEN *) set_term(SCREEN *screenp) @@ -229,6 +229,7 @@ _nc_setupscreen(int slines GCC_UNUSED, bool filtered, int slk_format) { + char *env; int bottom_stolen = 0; bool support_cookies = USE_XMC_SUPPORT; ripoff_t *rop; @@ -501,13 +502,12 @@ _nc_setupscreen(int slines GCC_UNUSED, _nc_init_wacs(); SP->_screen_acs_fix = (_nc_unicode_locale() && _nc_locale_breaks_acs()); - { - char *env = _nc_get_locale(); - SP->_legacy_coding = ((env == 0) - || !strcmp(env, "C") - || !strcmp(env, "POSIX")); - } #endif + env = _nc_get_locale(); + SP->_legacy_coding = ((env == 0) + || !strcmp(env, "C") + || !strcmp(env, "POSIX")); + T(("legacy-coding %d", SP->_legacy_coding)); _nc_idcok = TRUE; _nc_idlok = FALSE; diff --git a/test/test.priv.h b/test/test.priv.h index 4f472d33..5447fa6e 100644 --- a/test/test.priv.h +++ b/test/test.priv.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 1996-on * ****************************************************************************/ -/* $Id: test.priv.h,v 1.68 2007/06/30 17:53:09 tom Exp $ */ +/* $Id: test.priv.h,v 1.69 2008/01/26 22:05:48 tom Exp $ */ #ifndef __TEST_PRIV_H #define __TEST_PRIV_H 1 @@ -459,4 +459,21 @@ extern int optind; signal(nsig, handler); \ } +/* + * Simplify setting up demo of threading with these macros. + */ +#if !defined(NCURSES_VERSION_PATCH) || (NCURSES_VERSION_PATCH < 20070915) || !NCURSES_EXT_FUNCS +#define WANT_USE_WINDOW() \ +static int \ +use_window(WINDOW *win, int (*func) (WINDOW *, void *), void *data) \ +{ \ + return func(win, data); \ +} +#define USING_WINDOW(w,func) use_window(w, (NCURSES_CALLBACK) func, w) +#else +#define WANT_USE_WINDOW() /* nothing */ +#define USING_WINDOW(w,func) func(w) +#endif + + #endif /* __TEST_PRIV_H */ diff --git a/test/worm.c b/test/worm.c index ea407a0c..23b0ef4a 100644 --- a/test/worm.c +++ b/test/worm.c @@ -61,7 +61,7 @@ Options: traces will be dumped. The program stops and waits for one character of input at the beginning and end of the interval. - $Id: worm.c,v 1.53 2008/01/19 20:56:38 tom Exp $ + $Id: worm.c,v 1.55 2008/01/26 22:07:57 tom Exp $ */ #include @@ -70,6 +70,11 @@ Options: #include #endif +WANT_USE_WINDOW(); + +#define MAX_WORMS 40 +#define MAX_LENGTH 1024 + static chtype flavor[] = { 'O', '*', '#', '$', '%', '0', '@', @@ -96,8 +101,9 @@ typedef struct worm { static unsigned long sequence = 0; static bool quitting = FALSE; -static WORM worm[40]; +static WORM worm[MAX_WORMS]; static short **refs; +static int last_x, last_y; static const char *field; static int length = 16, number = 3; @@ -197,8 +203,7 @@ static const struct options { static void cleanup(void) { - standend(); - refresh(); + USING_WINDOW(stdscr, wrefresh); curs_set(1); endwin(); } @@ -227,23 +232,20 @@ draw_worm(WINDOW *win, void *data) int y; int h; - int bottom = LINES - 1; - int last = COLS - 1; - bool done = FALSE; if ((x = w->xpos[h = w->head]) < 0) { - wmove(win, y = w->ypos[h] = bottom, x = w->xpos[h] = 0); + wmove(win, y = w->ypos[h] = last_y, x = w->xpos[h] = 0); waddch(win, w->attrs); refs[y][x]++; } else { y = w->ypos[h]; } - if (x > last) - x = last; - if (y > bottom) - y = bottom; + if (x > last_x) + x = last_x; + if (y > last_y) + y = last_y; if (++h == length) h = 0; @@ -263,18 +265,18 @@ draw_worm(WINDOW *win, void *data) op = &(x == 0 ? (y == 0 ? upleft - : (y == bottom + : (y == last_y ? lowleft : left)) - : (x == last + : (x == last_x ? (y == 0 ? upright - : (y == bottom + : (y == last_y ? lowright : right)) : (y == 0 ? upper - : (y == bottom + : (y == last_y ? lower : normal))))[w->orientation]; @@ -307,14 +309,6 @@ draw_worm(WINDOW *win, void *data) return done; } -#if !defined(NCURSES_VERSION_PATCH) || (NCURSES_VERSION_PATCH < 20070915) || !NCURSES_EXT_FUNCS -static int -use_window(WINDOW *win, int (*func) (WINDOW *, void *), void *data) -{ - return func(win, data); -} -#endif - #ifdef USE_PTHREADS static bool quit_worm(void) @@ -366,14 +360,40 @@ static int get_input(void) { int ch; -#ifdef USE_PTHREADS - ch = use_window(stdscr, (NCURSES_CALLBACK) wgetch, stdscr); -#else - ch = getch(); -#endif + ch = USING_WINDOW(stdscr, wgetch); return ch; } +#ifdef KEY_RESIZE +static int +update_refs(WINDOW *win) +{ + int x, y; + + (void) win; + if (last_x != COLS - 1) { + for (y = 0; y <= last_y; y++) { + refs[y] = typeRealloc(short, COLS, refs[y]); + for (x = last_x + 1; x < COLS; x++) + refs[y][x] = 0; + } + last_x = COLS - 1; + } + if (last_y != LINES - 1) { + for (y = LINES; y <= last_y; y++) + free(refs[y]); + refs = typeRealloc(short *, LINES, refs); + for (y = last_y + 1; y < LINES; y++) { + refs[y] = typeMalloc(short, COLS); + for (x = 0; x < COLS; x++) + refs[y][x] = 0; + } + last_y = LINES - 1; + } + return OK; +} +#endif + int main(int argc, char *argv[]) { @@ -381,7 +401,6 @@ main(int argc, char *argv[]) int n; struct worm *w; short *ip; - int last, bottom; bool done = FALSE; setlocale(LC_ALL, ""); @@ -398,7 +417,7 @@ main(int argc, char *argv[]) case 'l': if (++x == argc) goto usage; - if ((length = atoi(argv[x])) < 2 || length > 1024) { + if ((length = atoi(argv[x])) < 2 || length > MAX_LENGTH) { fprintf(stderr, "%s: Invalid length\n", *argv); ExitProgram(EXIT_FAILURE); } @@ -406,7 +425,7 @@ main(int argc, char *argv[]) case 'n': if (++x == argc) goto usage; - if ((number = atoi(argv[x])) < 1 || number > 40) { + if ((number = atoi(argv[x])) < 1 || number > MAX_WORMS) { fprintf(stderr, "%s: Invalid number of worms\n", *argv); ExitProgram(EXIT_FAILURE); } @@ -439,8 +458,8 @@ main(int argc, char *argv[]) curs_set(0); - bottom = LINES - 1; - last = COLS - 1; + last_y = LINES - 1; + last_x = COLS - 1; #ifdef A_COLOR if (has_colors()) { @@ -475,7 +494,7 @@ main(int argc, char *argv[]) #ifdef BADCORNER /* if addressing the lower right corner doesn't work in your curses */ - refs[bottom][last] = 1; + refs[last_y][last_x] = 1; #endif /* BADCORNER */ for (n = number, w = &worm[0]; --n >= 0; w++) { @@ -501,7 +520,7 @@ main(int argc, char *argv[]) if (field) { const char *p; p = field; - for (y = bottom; --y >= 0;) { + for (y = last_y; --y >= 0;) { for (x = COLS; --x >= 0;) { addch((chtype) (*p++)); if (!*p) @@ -509,7 +528,7 @@ main(int argc, char *argv[]) } } } - refresh(); + USING_WINDOW(stdscr, wrefresh); nodelay(stdscr, TRUE); while (!done) { @@ -530,29 +549,13 @@ main(int argc, char *argv[]) generation++; } #endif + #ifdef KEY_RESIZE if (ch == KEY_RESIZE) { - if (last != COLS - 1) { - for (y = 0; y <= bottom; y++) { - refs[y] = typeRealloc(short, COLS, refs[y]); - for (x = last + 1; x < COLS; x++) - refs[y][x] = 0; - } - last = COLS - 1; - } - if (bottom != LINES - 1) { - for (y = LINES; y <= bottom; y++) - free(refs[y]); - refs = typeRealloc(short *, LINES, refs); - for (y = bottom + 1; y < LINES; y++) { - refs[y] = typeMalloc(short, COLS); - for (x = 0; x < COLS; x++) - refs[y][x] = 0; - } - bottom = LINES - 1; - } + USING_WINDOW(stdscr, update_refs); } #endif + /* * Make it simple to put this into single-step mode, or resume * normal operation -T.Dickey @@ -570,7 +573,7 @@ main(int argc, char *argv[]) done = draw_all_worms(); napms(10); - refresh(); + USING_WINDOW(stdscr, wrefresh); } cleanup();