Skip to content

Commit

Permalink
Three new test program-lets, for focus events and the define_key() fu…
Browse files Browse the repository at this point in the history
…nction; make sure Ctrl-C stops the program in noraw() mode and doesn't in raw() mode; and test out various possible issues with deleting windows if they still have undeleted subwindows.
  • Loading branch information
Bill-Gray committed Mar 13, 2024
1 parent 720c219 commit 5cef1e3
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 0 deletions.
42 changes: 42 additions & 0 deletions tests/brk_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <stdlib.h>
#include <string.h>
#include <curses.h>

/* Example to test whether Ctrl-C actually stops the program. It should
do so when noraw( ) is on, and shouldn't when raw( ) is on. Compile with
gcc -Wall -Wextra -pedantic -o brk_test brk_test.c -lncurses
gcc -Wall -Wextra -pedantic -I.. -o brk_test brk_test.c libpdcurses.a
*/

int main( void)
{
int c;

initscr();
cbreak( );
noecho( );
clear( );
echo( );
keypad( stdscr, 1);

mvprintw( 1, 2, "%s - test of Ctrl-C stopping curses", longname( ));
mvaddstr( 3, 2, "raw( ) is on. Hit Ctrl-C and the code won't break.");
mvaddstr( 4, 2, "Hit Enter when you're done :");
move( 5, 2);
raw( );
c = 0;
while( c != 13 && c != 10)
c = getch( );

mvaddstr( 6, 2, "noraw( ) is on. Hit Ctrl-C and the code will now break.");
mvaddstr( 7, 2, "Hit Enter when you're done :");
move( 8, 2);
noraw( );
c = 0;
while( c != 13 && c != 10)
c = getch( );

endwin( );
return( 0);
}
70 changes: 70 additions & 0 deletions tests/del_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <curses.h>
#include <stdlib.h>

/* What happens when you call delwin( ) on a window that has a
subwindow? Or call delwin( ) twice? (tl;dr : don't do those
things; they will cause segfaults in many Curses variants.)
To test, compile with
gcc -Wall -Wextra -pedantic -o del_test del_test.c -lncurses
On ncurses-6.2, one gets the behavior listed below : failure,
success, success, failure. If instead windows were deleted
recursively, you'd expect a success (both windows freed) followed
by three failures (because the windows in question have both been
deleted).
Thomas Dickey notes, at
https://lists.gnu.org/archive/html/bug-ncurses/2022-08/msg00012.html
that "fwiw, NetBSD curses hangs (infinite loop) on the first delwin
in [this] example, while Solaris dumps core on the last delwin."
'Original' PDCurses deletes 'win' the first time (it can't tell that
it still has a subwindow and shouldn't be deleted), which causes it
to crash the second time 'win' is deleted.
We were not clear as to what is 'supposed' to be done here
according to the X/Open and SVr4 standards. But in actual practice,
it's clearly dangerous to do either of the things described in the
two questions above.
PDCursesMod will assert() if you delete a window with a parent.
(It maintains a list of active windows, and will also assert() if
you attempt to 're-delete' a window, or more generally, pass in
a pointer to delwin() that isn't actually a current window.) */

int main( void)
{
WINDOW *win, *sub;
SCREEN *screen = newterm( NULL, NULL, NULL);
char buff[90];

noecho();
win = newwin( 0, 0, 0, 0);
move( 1, 1);
snprintf( buff, sizeof( buff), "New window %p %s", (void *)win, longname( ));
addstr( buff);
move( 2, 1);
sub = subwin( win, 10, 10, 10, 10);
snprintf( buff, sizeof( buff), "Sub window %p %s", (void *)sub, curses_version( ));
mvaddstr( 2, 1, buff);
snprintf( buff, sizeof( buff), "Deleted win : %d (should fail, it still has a subwindow)", delwin( win));
mvaddstr( 4, 1, buff);
snprintf( buff, sizeof( buff), "Deleted sub : %d (should succeed)", delwin( sub));
mvaddstr( 5, 1, buff);
snprintf( buff, sizeof( buff), "Deleted win : %d (should succeed, it doesn't have a subwin now)", delwin( win));
mvaddstr( 6, 1, buff);
snprintf( buff, sizeof( buff), "Deleted win : %d (should fail, it'd be a re-deletion)", delwin( win));
mvaddstr( 7, 1, buff);

mvaddstr( 9, 1, "References :");
mvaddstr( 10, 1, "https://www.invisible-island.net/ncurses/man/curs_window.3x.html");
mvprintw( 11, 1, "https://lists.gnu.org/archive/html/bug-ncurses/2022-08/msg00006.html");
mvaddstr( 12, 1, "Hit the any key:");
getch( );
endwin( );
delscreen( screen);
return(0);
}
50 changes: 50 additions & 0 deletions tests/focus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <curses.h>

/* Test code for define_key(). At present, this function
does nothing in PDCurses*. It could be added to the VT platform,
if that proves desirable. More generally, though, I'm thinking
that the ability to get KEY_FOCUS_IN and KEY_FOCUS_OUT via getch(),
on all platforms, might be useful. At present, our programs
have no way of knowing if they've lost/regained focus.
If we did such a thing, the following bits would still be
needed for portable programs. That is to say, if you weren't
using PDCursesMod, you would need to #define KEY_FOCUS_*, make
the two calls to define_key(), and emit the control sequence
so that those events would be sent to the program. */

#ifdef NCURSES_VERSION
#define KEY_FOCUS_IN (KEY_MAX + 1)
#define KEY_FOCUS_OUT (KEY_MAX + 2)
#endif

int main( void)
{
int input;

initscr();
noecho();
cbreak();
keypad( stdscr, 1);
#ifdef NCURSES_VERSION
define_key( "\033[I", KEY_FOCUS_IN);
define_key( "\033[O", KEY_FOCUS_OUT);
printf( "\033[?1004h"); /* control sequence to turn focus events on */
#endif
addstr( longname());
printw( " Hit 'q' to quit.\n");
while( (input = getch()) != 'q')
#ifdef NCURSES_VERSION
if( input == KEY_FOCUS_IN)
addstr( "KEY_FOCUS_IN ");
else if( input == KEY_FOCUS_OUT)
addstr( "KEY_FOCUS_OUT ");
else
#endif
{
addstr( keyname( input));
addch( ' ');
}
endwin();
return( 0);
}

0 comments on commit 5cef1e3

Please sign in to comment.