ncurses 6.2 - patch 20200718
[ncurses.git] / test / worm.c
index 92bdb254986719d46a2fb42c53a70a11ea14a260..6304e4b06a88e750d006bc68a6c52276de1fb968 100644 (file)
@@ -1,5 +1,6 @@
 /****************************************************************************
 /****************************************************************************
- * Copyright (c) 1998-2013,2016 Free Software Foundation, Inc.              *
+ * Copyright 2018-2019,2020 Thomas E. Dickey                                *
+ * Copyright 1998-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            *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
 
                July 1995 (esr): worms is now in living color! :-)
 
 
                July 1995 (esr): worms is now in living color! :-)
 
-Options:
-       -f                      fill screen with copies of 'WORM' at start.
-       -l <n>                  set worm length
-       -n <n>                  set number of worms
-       -t                      make worms leave droppings
-       -T <start> <end>        set trace interval
-       -S                      set single-stepping during trace interval
-       -N                      suppress cursor-movement optimization
-
   This program makes a good torture-test for the ncurses cursor-optimization
   code.  You can use -T to set the worm move interval over which movement
   traces will be dumped.  The program stops and waits for one character of
   input at the beginning and end of the interval.
 
   This program makes a good torture-test for the ncurses cursor-optimization
   code.  You can use -T to set the worm move interval over which movement
   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.66 2016/09/17 21:12:30 tom Exp $
+  $Id: worm.c,v 1.82 2020/02/02 23:34:34 tom Exp $
 */
 
 #include <test.priv.h>
 
 */
 
 #include <test.priv.h>
 
+#ifndef NCURSES_VERSION
+#undef TRACE
+#endif
+
 #ifdef USE_PTHREADS
 #include <pthread.h>
 #endif
 #ifdef USE_PTHREADS
 #include <pthread.h>
 #endif
@@ -102,6 +98,7 @@ static unsigned long sequence = 0;
 static bool quitting = FALSE;
 
 static WORM worm[MAX_WORMS];
 static bool quitting = FALSE;
 
 static WORM worm[MAX_WORMS];
+static int max_refs;
 static int **refs;
 static int last_x, last_y;
 
 static int **refs;
 static int last_x, last_y;
 
@@ -201,20 +198,34 @@ static const struct options {
 };
 /* *INDENT-ON* */
 
 };
 /* *INDENT-ON* */
 
+#if HAVE_USE_WINDOW
+static int
+safe_wgetch(WINDOW *w, void *data GCC_UNUSED)
+{
+    return wgetch(w);
+}
+static int
+safe_wrefresh(WINDOW *w, void *data GCC_UNUSED)
+{
+    return wrefresh(w);
+}
+#endif
+
+#ifdef KEY_RESIZE
 static void
 failed(const char *s)
 {
     perror(s);
 static void
 failed(const char *s)
 {
     perror(s);
-    endwin();
+    stop_curses();
     ExitProgram(EXIT_FAILURE);
 }
     ExitProgram(EXIT_FAILURE);
 }
+#endif
 
 static void
 cleanup(void)
 {
 
 static void
 cleanup(void)
 {
-    USING_WINDOW(stdscr, wrefresh);
-    curs_set(1);
-    endwin();
+    USING_WINDOW1(stdscr, wrefresh, safe_wrefresh);
+    stop_curses();
 }
 
 static void
 }
 
 static void
@@ -294,6 +305,7 @@ draw_worm(WINDOW *win, void *data)
     switch (op->nopts) {
     case 0:
        done = TRUE;
     switch (op->nopts) {
     case 0:
        done = TRUE;
+       Trace(("done - draw_worm"));
        break;
     case 1:
        w->orientation = op->opts[0];
        break;
     case 1:
        w->orientation = op->opts[0];
@@ -384,17 +396,18 @@ static int
 get_input(void)
 {
     int ch;
 get_input(void)
 {
     int ch;
-    ch = USING_WINDOW(stdscr, wgetch);
+    ch = USING_WINDOW1(stdscr, wgetch, safe_wgetch);
     return ch;
 }
 
 #ifdef KEY_RESIZE
 static int
     return ch;
 }
 
 #ifdef KEY_RESIZE
 static int
-update_refs(WINDOW *win)
+update_refs(WINDOW *win, void *data)
 {
     int x, y;
 
     (void) win;
 {
     int x, y;
 
     (void) win;
+    (void) data;
     if (last_x != COLS - 1) {
        for (y = 0; y <= last_y; y++) {
            refs[y] = typeRealloc(int, (size_t) COLS, refs[y]);
     if (last_x != COLS - 1) {
        for (y = 0; y <= last_y; y++) {
            refs[y] = typeRealloc(int, (size_t) COLS, refs[y]);
@@ -408,6 +421,7 @@ update_refs(WINDOW *win)
     if (last_y != LINES - 1) {
        for (y = LINES; y <= last_y; y++)
            free(refs[y]);
     if (last_y != LINES - 1) {
        for (y = LINES; y <= last_y; y++)
            free(refs[y]);
+       max_refs = LINES;
        refs = typeRealloc(int *, (size_t) LINES, refs);
        for (y = last_y + 1; y < LINES; y++) {
            refs[y] = typeMalloc(int, (size_t) COLS);
        refs = typeRealloc(int *, (size_t) LINES, refs);
        for (y = last_y + 1; y < LINES; y++) {
            refs[y] = typeMalloc(int, (size_t) COLS);
@@ -422,41 +436,69 @@ update_refs(WINDOW *win)
 }
 #endif
 
 }
 #endif
 
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+       "Usage: worm [options]"
+       ,""
+       ,"Options:"
+#if HAVE_USE_DEFAULT_COLORS
+       ," -d       invoke use_default_colors"
+#endif
+       ," -f       fill screen with copies of \"WORM\" at start"
+       ," -l <n>   set length of worms"
+       ," -n <n>   set number of worms"
+       ," -t       leave trail of \".\""
+#ifdef TRACE
+       ," -T <start>,<end> set trace interval"
+       ," -N       suppress cursor-movement optimization"
+#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[])
 {
 int
 main(int argc, char *argv[])
 {
+    int ch;
     int x, y;
     int n;
     struct worm *w;
     int *ip;
     bool done = FALSE;
     int x, y;
     int n;
     struct worm *w;
     int *ip;
     bool done = FALSE;
-    int max_refs;
+#if HAVE_USE_DEFAULT_COLORS
+    bool opt_d = FALSE;
+#endif
 
     setlocale(LC_ALL, "");
 
 
     setlocale(LC_ALL, "");
 
-    for (x = 1; x < argc; x++) {
-       char *p;
-       p = argv[x];
-       if (*p == '-')
-           p++;
-       switch (*p) {
+    while ((ch = getopt(argc, argv, "dfl:n:tT:N")) != -1) {
+       switch (ch) {
+#if HAVE_USE_DEFAULT_COLORS
+       case 'd':
+           opt_d = TRUE;
+           break;
+#endif
        case 'f':
            field = "WORM";
            break;
        case 'l':
        case 'f':
            field = "WORM";
            break;
        case 'l':
-           if (++x == argc)
-               goto usage;
-           if ((length = atoi(argv[x])) < 2 || length > MAX_LENGTH) {
+           if ((length = atoi(optarg)) < 2 || length > MAX_LENGTH) {
                fprintf(stderr, "%s: Invalid length\n", *argv);
                fprintf(stderr, "%s: Invalid length\n", *argv);
-               ExitProgram(EXIT_FAILURE);
+               usage();
            }
            break;
        case 'n':
            }
            break;
        case 'n':
-           if (++x == argc)
-               goto usage;
-           if ((number = atoi(argv[x])) < 1 || number > MAX_WORMS) {
+           if ((number = atoi(optarg)) < 1 || number > MAX_WORMS) {
                fprintf(stderr, "%s: Invalid number of worms\n", *argv);
                fprintf(stderr, "%s: Invalid number of worms\n", *argv);
-               ExitProgram(EXIT_FAILURE);
+               usage();
            }
            break;
        case 't':
            }
            break;
        case 't':
@@ -464,20 +506,20 @@ main(int argc, char *argv[])
            break;
 #ifdef TRACE
        case 'T':
            break;
 #ifdef TRACE
        case 'T':
-           trace_start = atoi(argv[++x]);
-           trace_end = atoi(argv[++x]);
+           if (sscanf(optarg, "%d,%d", &trace_start, &trace_end) != 2)
+               usage();
            break;
        case 'N':
            _nc_optimize_enable ^= OPTIMIZE_ALL;        /* declared by ncurses */
            break;
 #endif /* TRACE */
        default:
            break;
        case 'N':
            _nc_optimize_enable ^= OPTIMIZE_ALL;        /* declared by ncurses */
            break;
 #endif /* TRACE */
        default:
-         usage:
-           fprintf(stderr,
-                   "usage: %s [-field] [-length #] [-number #] [-trail]\n", *argv);
-           ExitProgram(EXIT_FAILURE);
+           usage();
+           /* NOTREACHED */
        }
     }
        }
     }
+    if (optind < argc)
+       usage();
 
     signal(SIGINT, onsig);
     initscr();
 
     signal(SIGINT, onsig);
     initscr();
@@ -495,7 +537,7 @@ main(int argc, char *argv[])
        int bg = COLOR_BLACK;
        start_color();
 #if HAVE_USE_DEFAULT_COLORS
        int bg = COLOR_BLACK;
        start_color();
 #if HAVE_USE_DEFAULT_COLORS
-       if (use_default_colors() == OK)
+       if (opt_d && (use_default_colors() == OK))
            bg = -1;
 #endif
 
            bg = -1;
 #endif
 
@@ -558,21 +600,19 @@ main(int argc, char *argv[])
            }
        }
     }
            }
        }
     }
-    USING_WINDOW(stdscr, wrefresh);
+    USING_WINDOW1(stdscr, wrefresh, safe_wrefresh);
     nodelay(stdscr, TRUE);
 
     while (!done) {
     nodelay(stdscr, TRUE);
 
     while (!done) {
-       int ch;
-
        ++sequence;
        if ((ch = get_input()) > 0) {
 #ifdef TRACE
            if (trace_start || trace_end) {
                if (generation == trace_start) {
        ++sequence;
        if ((ch = get_input()) > 0) {
 #ifdef TRACE
            if (trace_start || trace_end) {
                if (generation == trace_start) {
-                   trace(TRACE_CALLS);
+                   curses_trace(TRACE_CALLS);
                    get_input();
                } else if (generation == trace_end) {
                    get_input();
                } else if (generation == trace_end) {
-                   trace(0);
+                   curses_trace(0);
                    get_input();
                }
 
                    get_input();
                }
 
@@ -593,6 +633,7 @@ main(int argc, char *argv[])
            if (ch == 'q') {
                quitting = TRUE;
                done = TRUE;
            if (ch == 'q') {
                quitting = TRUE;
                done = TRUE;
+               Trace(("done - quitting"));
                continue;
            } else if (ch == 's') {
                nodelay(stdscr, FALSE);
                continue;
            } else if (ch == 's') {
                nodelay(stdscr, FALSE);
@@ -603,12 +644,12 @@ main(int argc, char *argv[])
 
        done = draw_all_worms();
        napms(10);
 
        done = draw_all_worms();
        napms(10);
-       USING_WINDOW(stdscr, wrefresh);
+       USING_WINDOW1(stdscr, wrefresh, safe_wrefresh);
     }
 
     Trace(("Cleanup"));
     cleanup();
     }
 
     Trace(("Cleanup"));
     cleanup();
-#ifdef NO_LEAKS
+#if NO_LEAKS
     for (y = 0; y < max_refs; y++) {
        free(refs[y]);
     }
     for (y = 0; y < max_refs; y++) {
        free(refs[y]);
     }