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