1 /* Interactive test program for the term-style-control module.
2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2019.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
21 #include "term-style-control.h"
27 #include "full-write.h"
29 /* This program outputs an endless amount of lines, each consisting of a
30 single 'y', in red color and underlined.
31 It can be used to exercise race conditions caused by
32 - simultaneous keyboard input on the terminal,
34 - pressing Ctrl-Z and then "fg". */
36 /* ECMA-48 / ISO 6429 escape sequences. See
37 https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
39 static const char set_underline_on
[] = "\033[4m";
40 static const char set_underline_off
[] = "\033[24m";
41 static const char set_foreground_color_red
[] = "\033[31m";
42 static const char set_foreground_color_default
[] = "\033[39m";
44 struct term_style_user_data
46 /* This field is marked volatile, because it is accessed from the
47 async-safe function async_set_attributes_from_default. */
48 bool volatile red_and_underline
;
50 struct term_style_control_data ctrl_data
;
53 static struct term_style_control_data
*
54 get_control_data (struct term_style_user_data
*user_data
)
56 return &user_data
->ctrl_data
;
60 restore (_GL_UNUSED
struct term_style_user_data
*user_data
)
62 fputs (set_underline_off
, stdout
);
63 fputs (set_foreground_color_default
, stdout
);
67 static _GL_ASYNC_SAFE
void
68 async_restore (_GL_UNUSED
struct term_style_user_data
*user_data
)
70 /* No <stdio.h> calls here! */
71 full_write (STDOUT_FILENO
, set_underline_off
,
72 strlen (set_underline_off
));
73 full_write (STDOUT_FILENO
, set_foreground_color_default
,
74 strlen (set_foreground_color_default
));
77 static _GL_ASYNC_SAFE
void
78 async_set_attributes_from_default (struct term_style_user_data
*user_data
)
80 /* No <stdio.h> calls here! */
81 if (user_data
->red_and_underline
)
83 full_write (STDOUT_FILENO
, set_underline_on
,
84 strlen (set_underline_on
));
85 full_write (STDOUT_FILENO
, set_foreground_color_red
,
86 strlen (set_foreground_color_red
));
90 static const struct term_style_controller controller
=
95 async_set_attributes_from_default
101 struct term_style_user_data user_data
;
103 /* Initialization. */
104 user_data
.red_and_underline
= false;
106 activate_term_style_controller (&controller
, &user_data
, STDOUT_FILENO
,
111 /* Before any styling, enable the non-default mode. */
112 activate_term_non_default_mode (&controller
, &user_data
);
114 /* Set user_data.red_and_underline *before* emitting the appropriate
115 escape sequences, otherwise async_set_attributes_from_default will not
116 do its job correctly. */
117 user_data
.red_and_underline
= true;
118 fputs (set_underline_on
, stdout
);
119 fputs (set_foreground_color_red
, stdout
);
125 /* Revert to the default style before emitting a newline. */
126 user_data
.red_and_underline
= false;
127 fputs (set_underline_off
, stdout
);
128 fputs (set_foreground_color_default
, stdout
);
132 deactivate_term_non_default_mode (&controller
, &user_data
);
134 fputs ("\n", stdout
);