]> ncurses.scripts.mit.edu Git - ncurses.git/blob - test/pair_content.c
ncurses 6.3 - patch 20220529
[ncurses.git] / test / pair_content.c
1 /****************************************************************************
2  * Copyright 2018-2020,2022 Thomas E. Dickey                                *
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.17 2022/05/28 20:15:06 tom Exp $
30  */
31
32 #define NEED_TIME_H
33 #include <test.priv.h>
34
35 #if USE_EXTENDED_COLOR
36 typedef int my_color_t;
37 #else
38 typedef NCURSES_COLOR_T my_color_t;
39 #endif
40
41 typedef struct {
42     my_color_t fg;
43     my_color_t bg;
44 } MYPAIR;
45
46 static int f_opt;
47 static int i_opt;
48 static int l_opt;
49 static int n_opt;
50 static int p_opt;
51 static int r_opt;
52 static int s_opt;
53
54 #if USE_EXTENDED_COLOR
55 static int x_opt;
56 #endif
57
58 static MYPAIR *expected;
59
60 #if HAVE_GETTIMEOFDAY
61 static struct timeval initial_time;
62 static struct timeval finish_time;
63 #endif
64
65 static GCC_NORETURN void
66 finish(int code)
67 {
68     free(expected);
69     ExitProgram(code);
70 }
71
72 static void
73 failed(const char *msg)
74 {
75     printw("%s", msg);
76     getch();
77     endwin();
78     finish(EXIT_FAILURE);
79 }
80
81 #if USE_EXTENDED_COLOR
82 static int
83 InitPair(int pair, int fg, int bg)
84 {
85     int rc;
86     if (x_opt) {
87         rc = init_extended_pair(pair, fg, bg);
88     } else {
89         rc = init_pair((NCURSES_PAIRS_T) pair,
90                        (NCURSES_COLOR_T) fg,
91                        (NCURSES_COLOR_T) bg);
92     }
93     return rc;
94 }
95
96 static int
97 PairContent(int pair, int *fgp, int *bgp)
98 {
99     int rc;
100     if (x_opt) {
101         rc = extended_pair_content(pair, fgp, bgp);
102     } else {
103         short fg, bg;
104         if ((rc = pair_content((short) pair, &fg, &bg)) == OK) {
105             *fgp = fg;
106             *bgp = bg;
107         }
108     }
109     return rc;
110 }
111 #else
112 #define InitPair(pair,fg,bg)      init_pair((NCURSES_COLOR_T)pair,(NCURSES_COLOR_T)fg,(NCURSES_COLOR_T)bg)
113 #define PairContent(pair,fgp,bgp) pair_content((NCURSES_PAIRS_T)pair,fgp,bgp)
114 #endif
115
116 static my_color_t
117 random_color(void)
118 {
119     return (my_color_t) (rand() % COLORS);
120 }
121
122 static void
123 setup_test(void)
124 {
125     setlocale(LC_ALL, "");
126     initscr();
127     cbreak();
128     noecho();
129     scrollok(stdscr, TRUE);
130     if (has_colors()) {
131         start_color();
132
133         if (!f_opt)
134             f_opt = 1;
135         if (!l_opt)
136             l_opt = COLOR_PAIRS;
137         if (l_opt <= 1)
138             failed("color-pair limit must be greater than one");
139
140         if (!n_opt) {
141             int pair;
142             size_t need = (size_t) ((l_opt > COLOR_PAIRS)
143                                     ? l_opt
144                                     : COLOR_PAIRS) + 1;
145
146             expected = typeCalloc(MYPAIR, need);
147             if (s_opt) {
148                 my_color_t fg;
149                 my_color_t bg;
150                 pair = f_opt;
151                 for (fg = 0; fg < COLORS; ++fg) {
152                     for (bg = 0; bg < COLORS; ++bg) {
153                         if (pair < l_opt) {
154                             InitPair(pair, fg, bg);
155                             expected[pair].fg = (my_color_t) fg;
156                             expected[pair].bg = (my_color_t) bg;
157                             ++pair;
158                         } else {
159                             break;
160                         }
161                     }
162                 }
163             } else {
164                 for (pair = f_opt; pair < l_opt; ++pair) {
165                     expected[pair].fg = random_color();
166                     expected[pair].bg = random_color();
167                     InitPair(pair, expected[pair].fg, expected[pair].bg);
168                 }
169             }
170         }
171     } else {
172         failed("This demo requires a color terminal");
173     }
174 #if HAVE_GETTIMEOFDAY
175     gettimeofday(&initial_time, 0);
176 #endif
177 }
178
179 static void
180 run_test(void)
181 {
182     int pair;
183     bool success = TRUE;
184     for (pair = 1; pair < l_opt; ++pair) {
185         my_color_t fg;
186         my_color_t bg;
187         if (PairContent(pair, &fg, &bg) == OK) {
188             if (expected != 0) {
189                 if (fg != expected[pair].fg)
190                     success = FALSE;
191                 if (bg != expected[pair].bg)
192                     success = FALSE;
193             }
194         }
195     }
196     if (i_opt) {
197         addch(success ? '.' : '?');
198         refresh();
199     }
200 }
201
202 static void
203 finish_test(void)
204 {
205     getch();
206     endwin();
207 }
208
209 #if HAVE_GETTIMEOFDAY
210 static double
211 seconds(struct timeval *mark)
212 {
213     double result = (double) mark->tv_sec;
214     result += ((double) mark->tv_usec / 1e6);
215     return result;
216 }
217 #endif
218
219 static void
220 usage(void)
221 {
222     static const char *msg[] =
223     {
224         "Usage: pair_content [options]"
225         ,""
226         ,"Options:"
227         ," -f PAIR  first color pair to test (default: 1)"
228         ," -i       interactive, showing test-progress"
229         ," -l PAIR  last color pair to test (default: max_pairs-1)"
230         ," -n       do not initialize color pairs"
231         ," -p       print data for color pairs instead of testing"
232         ," -r COUNT repeat for given count"
233         ," -s       initialize pairs sequentially rather than random"
234 #if USE_EXTENDED_COLOR
235         ," -x       use extended color pairs/values"
236 #endif
237     };
238     size_t n;
239     for (n = 0; n < SIZEOF(msg); n++)
240         fprintf(stderr, "%s\n", msg[n]);
241     finish(EXIT_FAILURE);
242 }
243
244 int
245 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
246 {
247     int i;
248
249     while ((i = getopt(argc, argv, "f:il:npr:sx")) != -1) {
250         switch (i) {
251         case 'f':
252             if ((f_opt = atoi(optarg)) <= 0)
253                 usage();
254             break;
255         case 'i':
256             i_opt = 1;
257             break;
258         case 'l':
259             if ((l_opt = atoi(optarg)) <= 0)
260                 usage();
261             break;
262         case 'n':
263             n_opt = 1;
264             break;
265         case 'p':
266             p_opt = 1;
267             break;
268         case 'r':
269             if ((r_opt = atoi(optarg)) <= 0)
270                 usage();
271             break;
272         case 's':
273             s_opt = 1;
274             break;
275 #if USE_EXTENDED_COLOR
276         case 'x':
277             x_opt = 1;
278             break;
279 #endif
280         default:
281             usage();
282         }
283     }
284     if (optind < argc)
285         usage();
286     if (r_opt <= 0)
287         r_opt = 1;
288
289     setup_test();
290     if (p_opt) {
291         endwin();
292         for (i = f_opt; i < l_opt; ++i) {
293             my_color_t fg, bg;
294             if (PairContent(i, &fg, &bg) == OK) {
295                 printf("%d: %d %d\n", i, fg, bg);
296             } else {
297                 printf("%d: ? ?\n", i);
298             }
299         }
300     } else {
301         int repeat;
302
303         for (repeat = 0; repeat < r_opt; ++repeat) {
304             run_test();
305             if (i_opt) {
306                 addch('.');
307                 refresh();
308             }
309         }
310
311         if (i_opt) {
312             addch('\n');
313         }
314         printw("DONE: ");
315 #if HAVE_GETTIMEOFDAY
316         gettimeofday(&finish_time, 0);
317         printw("%.03f seconds",
318                seconds(&finish_time)
319                - seconds(&initial_time));
320 #endif
321         finish_test();
322     }
323
324     finish(EXIT_SUCCESS);
325 }