ncurses 6.1 - patch 20181229
[ncurses.git] / test / pair_content.c
1 /****************************************************************************
2  * Copyright (c) 2018 Free Software Foundation, Inc.                        *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28 /*
29  * $Id: pair_content.c,v 1.2 2018/12/30 00:54:48 tom Exp $
30  */
31
32 #define NEED_TIME_H
33 #include <test.priv.h>
34
35 typedef struct {
36     NCURSES_COLOR_T fg;
37     NCURSES_COLOR_T bg;
38 } MYPAIR;
39
40 static int i_opt;
41 static int l_opt;
42 static int n_opt;
43 static int r_opt;
44 static int s_opt;
45
46 static MYPAIR *expected;
47
48 #if HAVE_GETTIMEOFDAY
49 static struct timeval initial_time;
50 static struct timeval finish_time;
51 #endif
52
53 static void
54 failed(const char *msg)
55 {
56     printw("%s", msg);
57     getch();
58     endwin();
59     ExitProgram(EXIT_FAILURE);
60 }
61
62 static NCURSES_COLOR_T
63 random_color(void)
64 {
65     return (NCURSES_COLOR_T) (rand() % COLORS);
66 }
67
68 static void
69 setup_test(void)
70 {
71     initscr();
72     cbreak();
73     noecho();
74     scrollok(stdscr, TRUE);
75     if (has_colors()) {
76         start_color();
77
78         if (!l_opt)
79             l_opt = COLOR_PAIRS;
80         if (l_opt <= 1)
81             failed("color-pair limit must be greater than one");
82
83         if (!n_opt) {
84             NCURSES_PAIRS_T pair;
85
86             expected = typeCalloc(MYPAIR, l_opt);
87             if (s_opt) {
88                 NCURSES_COLOR_T fg;
89                 NCURSES_COLOR_T bg;
90                 pair = 1;
91                 for (fg = 0; fg < COLORS; ++fg) {
92                     for (bg = 0; bg < COLORS; ++bg) {
93                         if (pair < l_opt) {
94                             init_pair(pair, fg, bg);
95                             expected[pair].fg = fg;
96                             expected[pair].bg = bg;
97                             ++pair;
98                         } else {
99                             break;
100                         }
101                     }
102                 }
103             } else {
104                 for (pair = 1; (int) pair < l_opt; ++pair) {
105                     expected[pair].fg = random_color();
106                     expected[pair].bg = random_color();
107                     init_pair(pair, expected[pair].fg, expected[pair].bg);
108                 }
109             }
110         }
111     } else {
112         failed("This demo requires a color terminal");
113     }
114 #if HAVE_GETTIMEOFDAY
115     gettimeofday(&initial_time, 0);
116 #endif
117 }
118
119 static void
120 run_test(void)
121 {
122     NCURSES_PAIRS_T pair;
123     bool success = TRUE;
124     for (pair = 1; (int) pair < l_opt; ++pair) {
125         NCURSES_COLOR_T fg;
126         NCURSES_COLOR_T bg;
127         if (pair_content(pair, &fg, &bg) == OK) {
128             if (expected != 0) {
129                 if (fg != expected[pair].fg)
130                     success = FALSE;
131                 if (bg != expected[pair].bg)
132                     success = FALSE;
133             }
134         }
135     }
136     if (i_opt) {
137         addch(success ? '.' : '?');
138         refresh();
139     }
140 }
141
142 static void
143 finish_test(void)
144 {
145     getch();
146     endwin();
147 }
148
149 #if HAVE_GETTIMEOFDAY
150 static double
151 seconds(struct timeval *mark)
152 {
153     double result = (double) mark->tv_sec;
154     result += ((double) mark->tv_usec / 1e6);
155     return result;
156 }
157 #endif
158
159 static void
160 usage(void)
161 {
162     static const char *msg[] =
163     {
164         "Usage: pair_content [options]"
165         ,""
166         ,"Options:"
167         ," -i       interactive, showing test-progress"
168         ," -l NUM   test NUM color pairs, rather than terminal description"
169         ," -n       do not initialize color pairs"
170         ," -r COUNT repeat for given count"
171         ," -s       initialize pairs sequentially rather than random"
172     };
173     size_t n;
174     for (n = 0; n < SIZEOF(msg); n++)
175         fprintf(stderr, "%s\n", msg[n]);
176     ExitProgram(EXIT_FAILURE);
177 }
178
179 int
180 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
181 {
182     int i;
183     int repeat;
184
185     while ((i = getopt(argc, argv, "il:nr:s")) != -1) {
186         switch (i) {
187         case 'i':
188             i_opt = 1;
189             break;
190         case 'l':
191             if ((l_opt = atoi(optarg)) <= 0)
192                 usage();
193             break;
194         case 'n':
195             n_opt = 1;
196             break;
197         case 'r':
198             if ((r_opt = atoi(optarg)) <= 0)
199                 usage();
200             break;
201         case 's':
202             s_opt = 1;
203             break;
204         default:
205             usage();
206         }
207     }
208     if (optind < argc)
209         usage();
210     if (r_opt <= 0)
211         r_opt = 1;
212
213     setup_test();
214
215     for (repeat = 0; repeat < r_opt; ++repeat) {
216         run_test();
217         if (i_opt) {
218             addch('.');
219             refresh();
220         }
221     }
222
223     if (i_opt) {
224         addch('\n');
225     }
226     printw("DONE: ");
227 #if HAVE_GETTIMEOFDAY
228     gettimeofday(&finish_time, 0);
229     printw("%.03f seconds",
230            seconds(&finish_time)
231            - seconds(&initial_time));
232 #endif
233     finish_test();
234
235     ExitProgram(EXIT_SUCCESS);
236 }