blob: fc5926b50386096708e78e4ad639aedef847ca64 [file] [log] [blame]
/****************************************************************************
* Copyright 2018-2019,2020 Thomas E. Dickey *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, *
* distribute, distribute with modifications, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included *
* in all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
* *
* Except as contained in this notice, the name(s) of the above copyright *
* holders shall not be used in advertising or otherwise to promote the *
* sale, use or other dealings in this Software without prior written *
* authorization. *
****************************************************************************/
/*
* $Id: pair_content.c,v 1.14 2020/02/02 23:34:34 tom Exp $
*/
#define NEED_TIME_H
#include <test.priv.h>
#if USE_EXTENDED_COLOR
typedef int my_color_t;
#else
typedef NCURSES_COLOR_T my_color_t;
#endif
typedef struct {
my_color_t fg;
my_color_t bg;
} MYPAIR;
static int f_opt;
static int i_opt;
static int l_opt;
static int n_opt;
static int p_opt;
static int r_opt;
static int s_opt;
#if USE_EXTENDED_COLOR
static int x_opt;
#endif
static MYPAIR *expected;
#if HAVE_GETTIMEOFDAY
static struct timeval initial_time;
static struct timeval finish_time;
#endif
static void
failed(const char *msg)
{
printw("%s", msg);
getch();
endwin();
ExitProgram(EXIT_FAILURE);
}
#if USE_EXTENDED_COLOR
static int
InitPair(int pair, int fg, int bg)
{
int rc;
if (x_opt) {
rc = init_extended_pair(pair, fg, bg);
} else {
rc = init_pair((NCURSES_PAIRS_T) pair,
(NCURSES_COLOR_T) fg,
(NCURSES_COLOR_T) bg);
}
return rc;
}
static int
PairContent(int pair, int *fgp, int *bgp)
{
int rc;
if (x_opt) {
rc = extended_pair_content(pair, fgp, bgp);
} else {
short fg, bg;
if ((rc = pair_content((short) pair, &fg, &bg)) == OK) {
*fgp = fg;
*bgp = bg;
}
}
return rc;
}
#else
#define InitPair(pair,fg,bg) init_pair((NCURSES_COLOR_T)pair,(NCURSES_COLOR_T)fg,(NCURSES_COLOR_T)bg)
#define PairContent(pair,fgp,bgp) pair_content((NCURSES_PAIRS_T)pair,fgp,bgp)
#endif
static my_color_t
random_color(void)
{
return (my_color_t) (rand() % COLORS);
}
static void
setup_test(void)
{
initscr();
cbreak();
noecho();
scrollok(stdscr, TRUE);
if (has_colors()) {
start_color();
if (!f_opt)
f_opt = 1;
if (!l_opt)
l_opt = COLOR_PAIRS;
if (l_opt <= 1)
failed("color-pair limit must be greater than one");
if (!n_opt) {
int pair;
size_t need = (size_t) ((l_opt > COLOR_PAIRS)
? l_opt
: COLOR_PAIRS) + 1;
expected = typeCalloc(MYPAIR, need);
if (s_opt) {
my_color_t fg;
my_color_t bg;
pair = f_opt;
for (fg = 0; fg < COLORS; ++fg) {
for (bg = 0; bg < COLORS; ++bg) {
if (pair < l_opt) {
InitPair(pair, fg, bg);
expected[pair].fg = (my_color_t) fg;
expected[pair].bg = (my_color_t) bg;
++pair;
} else {
break;
}
}
}
} else {
for (pair = f_opt; pair < l_opt; ++pair) {
expected[pair].fg = random_color();
expected[pair].bg = random_color();
InitPair(pair, expected[pair].fg, expected[pair].bg);
}
}
}
} else {
failed("This demo requires a color terminal");
}
#if HAVE_GETTIMEOFDAY
gettimeofday(&initial_time, 0);
#endif
}
static void
run_test(void)
{
int pair;
bool success = TRUE;
for (pair = 1; pair < l_opt; ++pair) {
my_color_t fg;
my_color_t bg;
if (PairContent(pair, &fg, &bg) == OK) {
if (expected != 0) {
if (fg != expected[pair].fg)
success = FALSE;
if (bg != expected[pair].bg)
success = FALSE;
}
}
}
if (i_opt) {
addch(success ? '.' : '?');
refresh();
}
}
static void
finish_test(void)
{
getch();
endwin();
}
#if HAVE_GETTIMEOFDAY
static double
seconds(struct timeval *mark)
{
double result = (double) mark->tv_sec;
result += ((double) mark->tv_usec / 1e6);
return result;
}
#endif
static void
usage(void)
{
static const char *msg[] =
{
"Usage: pair_content [options]"
,""
,"Options:"
," -f PAIR first color pair to test (default: 1)"
," -i interactive, showing test-progress"
," -l PAIR last color pair to test (default: max_pairs-1)"
," -n do not initialize color pairs"
," -p print data for color pairs instead of testing"
," -r COUNT repeat for given count"
," -s initialize pairs sequentially rather than random"
#if USE_EXTENDED_COLOR
," -x use extended color pairs/values"
#endif
};
size_t n;
for (n = 0; n < SIZEOF(msg); n++)
fprintf(stderr, "%s\n", msg[n]);
ExitProgram(EXIT_FAILURE);
}
int
main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
{
int i;
while ((i = getopt(argc, argv, "f:il:npr:sx")) != -1) {
switch (i) {
case 'f':
if ((f_opt = atoi(optarg)) <= 0)
usage();
break;
case 'i':
i_opt = 1;
break;
case 'l':
if ((l_opt = atoi(optarg)) <= 0)
usage();
break;
case 'n':
n_opt = 1;
break;
case 'p':
p_opt = 1;
break;
case 'r':
if ((r_opt = atoi(optarg)) <= 0)
usage();
break;
case 's':
s_opt = 1;
break;
#if USE_EXTENDED_COLOR
case 'x':
x_opt = 1;
break;
#endif
default:
usage();
}
}
if (optind < argc)
usage();
if (r_opt <= 0)
r_opt = 1;
setup_test();
if (p_opt) {
endwin();
for (i = f_opt; i < l_opt; ++i) {
my_color_t fg, bg;
if (PairContent(i, &fg, &bg) == OK) {
printf("%d: %d %d\n", i, fg, bg);
} else {
printf("%d: ? ?\n", i);
}
}
} else {
int repeat;
for (repeat = 0; repeat < r_opt; ++repeat) {
run_test();
if (i_opt) {
addch('.');
refresh();
}
}
if (i_opt) {
addch('\n');
}
printw("DONE: ");
#if HAVE_GETTIMEOFDAY
gettimeofday(&finish_time, 0);
printw("%.03f seconds",
seconds(&finish_time)
- seconds(&initial_time));
#endif
finish_test();
}
ExitProgram(EXIT_SUCCESS);
}