ncurses 4.2
[ncurses.git] / test / hashtest.c
1 /*
2  * hashtest.c -- test hash mapping
3  *
4  * Generate timing statistics for vertical-motion optimization.
5  *
6  * $Id: hashtest.c,v 1.12 1997/08/09 14:25:18 tom Exp $
7  */
8
9 #define NCURSES_TRACE
10
11 #ifdef TRACE
12 #define Trace(p) _tracef p
13 #define USE_TRACE 1
14 #else
15 #define Trace(p) /* nothing */
16 #define TRACE 0
17 #endif
18
19 #include <test.priv.h>
20
21 #include <string.h>
22 #include <ctype.h>
23 #include <signal.h>
24
25 #define LO_CHAR ' '
26 #define HI_CHAR '~'
27
28 static bool continuous = FALSE;
29 static bool reverse_loops = FALSE;
30 static bool single_step = FALSE;
31 static bool extend_corner = FALSE;
32 static int foot_lines = 0;
33 static int head_lines = 0;
34
35 static void cleanup(void)
36 {
37         move(LINES-1,0);
38         clrtoeol();
39         refresh();
40         endwin();
41 }
42
43 static RETSIGTYPE finish(int sig GCC_UNUSED)
44 {
45         cleanup();
46         exit(EXIT_FAILURE);
47 }
48
49 static void genlines(int base)
50 {
51         int i, j;
52
53 #if USE_TRACE
54         if (base == 'a')
55                 Trace(("Resetting screen"));
56         else
57                 Trace(("Painting `%c' screen", base));
58 #endif
59
60         /* Do this so writes to lower-right corner don't cause a spurious
61          * scrolling operation.  This _shouldn't_ break the scrolling
62          * optimization, since that's computed in the refresh() call.
63          */
64         scrollok(stdscr, FALSE);
65
66         move(0,0);
67         for (i = 0; i < head_lines; i++)
68                 for (j = 0; j < COLS; j++)
69                         addch((j % 8 == 0) ? ('A' + j/8) : '-');
70
71         move(head_lines, 0);
72         for (i = head_lines; i < LINES - foot_lines; i++) {
73                 int c = (base - LO_CHAR + i) % (HI_CHAR - LO_CHAR + 1) + LO_CHAR;
74                 int hi = (extend_corner || (i < LINES - 1)) ? COLS : COLS - 1;
75                 for (j = 0; j < hi; j++)
76                         addch(c);
77         }
78
79         for (i = LINES - foot_lines; i < LINES; i++) {
80                 move(i, 0);
81                 for (j = 0; j < (extend_corner ? COLS : COLS - 1); j++)
82                         addch((j % 8 == 0) ? ('A' + j/8) : '-');
83         }
84
85         scrollok(stdscr, TRUE);
86         if (single_step) {
87                 move(LINES-1, 0);
88                 getch();
89         } else
90                 refresh();
91 }
92
93 static void one_cycle(int ch)
94 {
95         if (continuous) {
96                 genlines(ch);
97         } else if (ch != 'a') {
98                 genlines('a');
99                 genlines(ch);
100         }
101 }
102
103 static void run_test(bool optimized)
104 {
105         char    ch;
106         int     lo = continuous ? LO_CHAR : 'a' - LINES;
107         int     hi = continuous ? HI_CHAR : 'a' + LINES;
108
109 #ifdef NCURSES_VERSION
110         if (optimized) {
111                 Trace(("With hash mapping"));
112                 _nc_optimize_enable |= OPTIMIZE_HASHMAP;
113         } else {
114                 Trace(("Without hash mapping"));
115                 _nc_optimize_enable &= ~OPTIMIZE_HASHMAP;
116         }
117 #endif
118
119         if (reverse_loops)
120                 for (ch = hi; ch >= lo; ch--)
121                         one_cycle(ch);
122         else
123                 for (ch = lo; ch <= hi; ch++)
124                         one_cycle(ch);
125 }
126
127 static void usage(void)
128 {
129         static const char *const tbl[] = {
130                  "Usage: hashtest [options]"
131                 ,""
132                 ,"Options:"
133                 ,"  -c      continuous (don't reset between refresh's)"
134                 ,"  -f num  leave 'num' lines constant for footer"
135                 ,"  -h num  leave 'num' lines constant for header"
136                 ,"  -l num  repeat test 'num' times"
137                 ,"  -n      test the normal optimizer"
138                 ,"  -o      test the hashed optimizer"
139                 ,"  -r      reverse the loops"
140                 ,"  -s      single-step"
141                 ,"  -x      assume lower-right corner extension"
142         };
143         size_t n;
144
145         for (n = 0; n < sizeof(tbl)/sizeof(tbl[0]); n++)
146                 fprintf(stderr, "%s\n", tbl[n]);
147         exit(EXIT_FAILURE);
148 }
149
150 int main(int argc, char *argv[])
151 {
152         int c;
153         int test_loops = 1;
154         int test_normal = FALSE;
155         int test_optimize = FALSE;
156
157         while ((c = getopt(argc, argv, "cf:h:l:norsx")) != EOF) {
158                 switch (c) {
159                 case 'c':
160                         continuous = TRUE;
161                         break;
162                 case 'f':
163                         foot_lines = atoi(optarg);
164                         break;
165                 case 'h':
166                         head_lines = atoi(optarg);
167                         break;
168                 case 'l':
169                         test_loops = atoi(optarg);
170                         break;
171                 case 'n':
172                         test_normal = TRUE;
173                         break;
174                 case 'o':
175                         test_optimize = TRUE;
176                         break;
177                 case 'r':
178                         reverse_loops = TRUE;
179                         break;
180                 case 's':
181                         single_step = TRUE;
182                         break;
183                 case 'x':
184                         extend_corner = TRUE;
185                         break;
186                 default:
187                         usage();
188                 }
189         }
190         if (!test_normal && !test_optimize) {
191                 test_normal = TRUE;
192                 test_optimize = TRUE;
193         }
194 #if USE_TRACE
195         trace(TRACE_TIMES);
196 #endif
197
198         (void) signal(SIGINT, finish);  /* arrange interrupts to terminate */
199
200         (void) initscr();      /* initialize the curses library */
201         keypad(stdscr, TRUE);  /* enable keyboard mapping */
202         (void) nonl();         /* tell curses not to do NL->CR/NL on output */
203         (void) cbreak();       /* take input chars one at a time, no wait for \n */
204         (void) noecho();       /* don't echo input */
205         scrollok(stdscr, TRUE);
206
207         while (test_loops-- > 0) {
208                 if (test_normal)
209                         run_test(FALSE);
210                 if (test_optimize)
211                         run_test(TRUE);
212         }
213
214         cleanup();               /* we're done */
215         return(EXIT_SUCCESS);
216 }
217 /* hashtest.c ends here */