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