usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-term-style-control-hello.c
blobda71c25f8e838608241c90917538f0f9815292e5
1 /* Simple 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 the line: Hello Dr. Linus Pauling!
30 with underlining here: _________________
31 and a cyan background color here: _____
34 /* ECMA-48 / ISO 6429 escape sequences. See
35 https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
37 static const char set_underline_on[] = "\033[4m";
38 static const char set_underline_off[] = "\033[24m";
39 static const char set_background_color_cyan[] = "\033[46m";
40 static const char set_background_color_default[] = "\033[49m";
42 struct term_style_user_data
44 /* These fields are marked volatile, because they are accessed from the
45 async-safe function async_set_attributes_from_default. */
46 bool volatile underline;
47 bool volatile background_color_cyan;
49 struct term_style_control_data ctrl_data;
52 static struct term_style_control_data *
53 get_control_data (struct term_style_user_data *user_data)
55 return &user_data->ctrl_data;
58 static void
59 restore (_GL_UNUSED struct term_style_user_data *user_data)
61 fputs (set_underline_off, stdout);
62 fputs (set_background_color_default, stdout);
63 fflush (stdout);
66 static _GL_ASYNC_SAFE void
67 async_restore (_GL_UNUSED struct term_style_user_data *user_data)
69 /* No <stdio.h> calls here! */
70 full_write (STDOUT_FILENO, set_underline_off,
71 strlen (set_underline_off));
72 full_write (STDOUT_FILENO, set_background_color_default,
73 strlen (set_background_color_default));
76 static _GL_ASYNC_SAFE void
77 async_set_attributes_from_default (struct term_style_user_data *user_data)
79 /* No <stdio.h> calls here! */
80 if (user_data->underline)
81 full_write (STDOUT_FILENO, set_underline_on,
82 strlen (set_underline_on));
83 if (user_data->background_color_cyan)
84 full_write (STDOUT_FILENO, set_background_color_cyan,
85 strlen (set_background_color_cyan));
88 static const struct term_style_controller controller =
90 get_control_data,
91 restore,
92 async_restore,
93 async_set_attributes_from_default
96 int
97 main ()
99 struct term_style_user_data user_data;
101 /* Initialization. */
102 user_data.underline = false;
103 user_data.background_color_cyan = false;
105 activate_term_style_controller (&controller, &user_data, STDOUT_FILENO,
106 TTYCTL_AUTO);
108 /* As long as no styling is needed, we can stay in the default mode. */
109 fputs ("Hello ", stdout);
110 fflush (stdout);
112 /* Before any styling, enable the non-default mode. */
113 activate_term_non_default_mode (&controller, &user_data);
115 /* Set user_data.underline *before* emitting the appropriate
116 escape sequences, otherwise async_set_attributes_from_default will not
117 do its job correctly. */
118 user_data.underline = true;
119 fputs (set_underline_on, stdout);
120 fflush (stdout);
122 fputs ("Dr. ", stdout);
123 fflush (stdout);
125 /* Set user_data.background_color_cyan *before* emitting the appropriate
126 escape sequences, otherwise async_set_attributes_from_default will not
127 do its job correctly. */
128 user_data.background_color_cyan = true;
129 fputs (set_background_color_cyan, stdout);
130 fflush (stdout);
132 fputs ("Linus", stdout);
133 fflush (stdout);
135 user_data.background_color_cyan = false;
136 fputs (set_background_color_default, stdout);
137 fflush (stdout);
139 fputs (" Pauling", stdout);
140 fflush (stdout);
142 user_data.underline = false;
143 fputs (set_underline_off, stdout);
144 fflush (stdout);
146 /* Needed as a prerequisite of the deactivate_term_style_controller call
147 below. */
148 deactivate_term_non_default_mode (&controller, &user_data);
150 fputs ("!\n", stdout);
152 /* If the user_data was allocated in heap memory, with indefinite extent,
153 this call would be optional. But since we have allocated it on the
154 stack, we must deactivate it before it goes out of scope. Otherwise
155 we get undefined behaviour in an atexit() handler. */
156 deactivate_term_style_controller (&controller, &user_data);
158 return 0;