nstrftime, c-nstrftime tests: Avoid test failures on native Windows.
[gnulib.git] / tests / test-term-style-control-yes.c
blob6d60450b909d70a8788cd11d3f8b008422451a1e
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/>. */
18 #include <config.h>
20 /* Specification. */
21 #include "term-style-control.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include <unistd.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,
33 - pressing Ctrl-C,
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;
59 static void
60 restore (_GL_UNUSED struct term_style_user_data *user_data)
62 fputs (set_underline_off, stdout);
63 fputs (set_foreground_color_default, stdout);
64 fflush (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 =
92 get_control_data,
93 restore,
94 async_restore,
95 async_set_attributes_from_default
98 int
99 main ()
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,
107 TTYCTL_AUTO);
109 for (;;)
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);
120 fflush (stdout);
122 fputs ("y", stdout);
123 fflush (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);
129 fflush (stdout);
131 /* Optional. */
132 deactivate_term_non_default_mode (&controller, &user_data);
134 fputs ("\n", stdout);
135 fflush (stdout);