]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/worm.c
ncurses 6.0 - patch 20160220
[ncurses.git] / test / worm.c
index 23b0ef4ae85c70792dae3b0ee12d7298942bbba5..c3fc0da822ef2619246c5ed831c0d9eb9bee48af 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -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.55 2008/01/26 22:07:57 tom Exp $
+  $Id: worm.c,v 1.65 2013/06/22 20:01:41 tom Exp $
 */
 
 #include <test.priv.h>
@@ -79,7 +79,7 @@ static chtype flavor[] =
 {
     'O', '*', '#', '$', '%', '0', '@',
 };
-static const short xinc[] =
+static const int xinc[] =
 {
     1, 1, 1, 0, -1, -1, -1, 0
 }, yinc[] =
@@ -90,8 +90,8 @@ static const short xinc[] =
 typedef struct worm {
     int orientation;
     int head;
-    short *xpos;
-    short *ypos;
+    int *xpos;
+    int *ypos;
     chtype attrs;
 #ifdef USE_PTHREADS
     pthread_t thread;
@@ -102,13 +102,14 @@ static unsigned long sequence = 0;
 static bool quitting = FALSE;
 
 static WORM worm[MAX_WORMS];
-static short **refs;
+static int **refs;
 static int last_x, last_y;
 
 static const char *field;
 static int length = 16, number = 3;
 static chtype trail = ' ';
 
+static unsigned pending;
 #ifdef TRACE
 static int generation, trace_start, trace_end;
 #endif /* TRACE */
@@ -200,6 +201,14 @@ static const struct options {
 };
 /* *INDENT-ON* */
 
+static void
+failed(const char *s)
+{
+    perror(s);
+    endwin();
+    ExitProgram(EXIT_FAILURE);
+}
+
 static void
 cleanup(void)
 {
@@ -208,18 +217,18 @@ cleanup(void)
     endwin();
 }
 
-static RETSIGTYPE
+static void
 onsig(int sig GCC_UNUSED)
 {
     cleanup();
     ExitProgram(EXIT_FAILURE);
 }
 
-static float
+static double
 ranf(void)
 {
     long r = (rand() & 077777);
-    return ((float) r / 32768.);
+    return ((double) r / 32768.);
 }
 
 static int
@@ -227,6 +236,8 @@ draw_worm(WINDOW *win, void *data)
 {
     WORM *w = (WORM *) data;
     const struct options *op;
+    unsigned mask = (unsigned) (~(1 << (w - worm)));
+    chtype attrs = w->attrs | ((mask & pending) ? A_REVERSE : 0);
 
     int x;
     int y;
@@ -236,7 +247,7 @@ draw_worm(WINDOW *win, void *data)
 
     if ((x = w->xpos[h = w->head]) < 0) {
        wmove(win, y = w->ypos[h] = last_y, x = w->xpos[h] = 0);
-       waddch(win, w->attrs);
+       waddch(win, attrs);
        refs[y][x]++;
     } else {
        y = w->ypos[h];
@@ -288,7 +299,7 @@ draw_worm(WINDOW *win, void *data)
        w->orientation = op->opts[0];
        break;
     default:
-       w->orientation = op->opts[(int) (ranf() * (float) op->nopts)];
+       w->orientation = op->opts[(int) (ranf() * (double) op->nopts)];
        break;
     }
 
@@ -299,7 +310,7 @@ draw_worm(WINDOW *win, void *data)
 
        if (y < 0)
            y = 0;
-       waddch(win, w->attrs);
+       waddch(win, attrs);
 
        w->ypos[h] = y;
        w->xpos[h] = x;
@@ -311,9 +322,11 @@ draw_worm(WINDOW *win, void *data)
 
 #ifdef USE_PTHREADS
 static bool
-quit_worm(void)
+quit_worm(int bitnum)
 {
+    pending |= (1 << bitnum);
     napms(10);                 /* let the other thread(s) have a chance */
+    pending &= ~(1 << bitnum);
     return quitting;
 }
 
@@ -321,12 +334,18 @@ static void *
 start_worm(void *arg)
 {
     unsigned long compare = 0;
-    while (!quit_worm()) {
+    Trace(("start_worm"));
+    while (!quit_worm(((struct worm *) arg) - worm)) {
        while (compare < sequence) {
            ++compare;
+#if HAVE_USE_WINDOW
            use_window(stdscr, draw_worm, arg);
+#else
+           draw_worm(stdscr, arg);
+#endif
        }
     }
+    Trace(("...start_worm (done)"));
     return NULL;
 }
 #endif
@@ -343,13 +362,18 @@ draw_all_worms(void)
     if (first) {
        first = FALSE;
        for (n = 0, w = &worm[0]; n < number; n++, w++) {
-           int rc;
-           rc = pthread_create(&(w->thread), NULL, start_worm, w);
+           (void) pthread_create(&(w->thread), NULL, start_worm, w);
        }
     }
 #else
     for (n = 0, w = &worm[0]; n < number; n++, w++) {
-       if (use_window(stdscr, draw_worm, w))
+       if (
+#if HAVE_USE_WINDOW
+              USING_WINDOW2(stdscr, draw_worm, w)
+#else
+              draw_worm(stdscr, w)
+#endif
+           )
            done = TRUE;
     }
 #endif
@@ -373,7 +397,9 @@ update_refs(WINDOW *win)
     (void) win;
     if (last_x != COLS - 1) {
        for (y = 0; y <= last_y; y++) {
-           refs[y] = typeRealloc(short, COLS, refs[y]);
+           refs[y] = typeRealloc(int, (size_t) COLS, refs[y]);
+           if (!refs[y])
+               failed("update_refs");
            for (x = last_x + 1; x < COLS; x++)
                refs[y][x] = 0;
        }
@@ -382,9 +408,11 @@ update_refs(WINDOW *win)
     if (last_y != LINES - 1) {
        for (y = LINES; y <= last_y; y++)
            free(refs[y]);
-       refs = typeRealloc(short *, LINES, refs);
+       refs = typeRealloc(int *, (size_t) LINES, refs);
        for (y = last_y + 1; y < LINES; y++) {
-           refs[y] = typeMalloc(short, COLS);
+           refs[y] = typeMalloc(int, (size_t) COLS);
+           if (!refs[y])
+               failed("update_refs");
            for (x = 0; x < COLS; x++)
                refs[y][x] = 0;
        }
@@ -400,8 +428,9 @@ main(int argc, char *argv[])
     int x, y;
     int n;
     struct worm *w;
-    short *ip;
+    int *ip;
     bool done = FALSE;
+    int max_refs;
 
     setlocale(LC_ALL, "");
 
@@ -471,8 +500,8 @@ main(int argc, char *argv[])
 #endif
 
 #define SET_COLOR(num, fg) \
-           init_pair(num+1, fg, bg); \
-           flavor[num] |= COLOR_PAIR(num+1) | A_BOLD
+           init_pair(num+1, (short) fg, (short) bg); \
+           flavor[num] |= (chtype) COLOR_PAIR(num+1) | A_BOLD
 
        SET_COLOR(0, COLOR_GREEN);
        SET_COLOR(1, COLOR_RED);
@@ -484,9 +513,10 @@ main(int argc, char *argv[])
     }
 #endif /* A_COLOR */
 
-    refs = typeMalloc(short *, LINES);
-    for (y = 0; y < LINES; y++) {
-       refs[y] = typeMalloc(short, COLS);
+    max_refs = LINES;
+    refs = typeMalloc(int *, (size_t) max_refs);
+    for (y = 0; y < max_refs; y++) {
+       refs[y] = typeMalloc(int, (size_t) COLS);
        for (x = 0; x < COLS; x++) {
            refs[y][x] = 0;
        }
@@ -498,18 +528,18 @@ main(int argc, char *argv[])
 #endif /* BADCORNER */
 
     for (n = number, w = &worm[0]; --n >= 0; w++) {
-       w->attrs = flavor[n % SIZEOF(flavor)];
+       w->attrs = flavor[(unsigned) n % SIZEOF(flavor)];
        w->orientation = 0;
        w->head = 0;
 
-       if (!(ip = typeMalloc(short, (length + 1)))) {
+       if (!(ip = typeMalloc(int, (size_t) (length + 1)))) {
            fprintf(stderr, "%s: out of memory\n", *argv);
            ExitProgram(EXIT_FAILURE);
        }
        w->xpos = ip;
        for (x = length; --x >= 0;)
            *ip++ = -1;
-       if (!(ip = typeMalloc(short, (length + 1)))) {
+       if (!(ip = typeMalloc(int, (size_t) (length + 1)))) {
            fprintf(stderr, "%s: out of memory\n", *argv);
            ExitProgram(EXIT_FAILURE);
        }
@@ -576,9 +606,10 @@ main(int argc, char *argv[])
        USING_WINDOW(stdscr, wrefresh);
     }
 
+    Trace(("Cleanup"));
     cleanup();
 #ifdef NO_LEAKS
-    for (y = 0; y < LINES; y++) {
+    for (y = 0; y < max_refs; y++) {
        free(refs[y]);
     }
     free(refs);
@@ -591,6 +622,7 @@ main(int argc, char *argv[])
     /*
      * Do this just in case one of the threads did not really exit.
      */
+    Trace(("join all threads"));
     for (n = 0; n < number; n++) {
        pthread_join(worm[n].thread, NULL);
     }