unistr/u{8,16,32}-uctomb: Avoid possible trouble with huge strings.
[gnulib.git] / tests / test-term-style-control-hello.c
blob61f17253392421193b48f14390caaf594beac47b
1 /* Simple test program for the term-style-control module.
2 Copyright (C) 2019-2020 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 <stdbool.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <unistd.h>
28 #include "full-write.h"
30 /* This program outputs the line: Hello Dr. Linus Pauling!
31 with underlining here: _________________
32 and a cyan background color here: _____
35 /* ECMA-48 / ISO 6429 escape sequences. See
36 https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
38 static const char set_underline_on[] = "\033[4m";
39 static const char set_underline_off[] = "\033[24m";
40 static const char set_background_color_cyan[] = "\033[46m";
41 static const char set_background_color_default[] = "\033[49m";
43 struct term_style_user_data
45 /* These fields are marked volatile, because they are accessed from the
46 async-safe function async_set_attributes_from_default. */
47 bool volatile underline;
48 bool volatile background_color_cyan;
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 (struct term_style_user_data *user_data)
62 fputs (set_underline_off, stdout);
63 fputs (set_background_color_default, stdout);
64 fflush (stdout);
67 static _GL_ASYNC_SAFE void
68 async_restore (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_background_color_default,
74 strlen (set_background_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->underline)
82 full_write (STDOUT_FILENO, set_underline_on,
83 strlen (set_underline_on));
84 if (user_data->background_color_cyan)
85 full_write (STDOUT_FILENO, set_background_color_cyan,
86 strlen (set_background_color_cyan));
89 static const struct term_style_controller controller =
91 get_control_data,
92 restore,
93 async_restore,
94 async_set_attributes_from_default
97 int
98 main (int argc, char *argv[])
100 struct term_style_user_data user_data;
102 /* Initialization. */
103 user_data.underline = false;
104 user_data.background_color_cyan = false;
106 activate_term_style_controller (&controller, &user_data, STDOUT_FILENO,
107 TTYCTL_AUTO);
109 /* As long as no styling is needed, we can stay in the default mode. */
110 fputs ("Hello ", stdout);
111 fflush (stdout);
113 /* Before any styling, enable the non-default mode. */
114 activate_term_non_default_mode (&controller, &user_data);
116 /* Set user_data.underline *before* emitting the appropriate
117 escape sequences, otherwise async_set_attributes_from_default will not
118 do its job correctly. */
119 user_data.underline = true;
120 fputs (set_underline_on, stdout);
121 fflush (stdout);
123 fputs ("Dr. ", stdout);
124 fflush (stdout);
126 /* Set user_data.background_color_cyan *before* emitting the appropriate
127 escape sequences, otherwise async_set_attributes_from_default will not
128 do its job correctly. */
129 user_data.background_color_cyan = true;
130 fputs (set_background_color_cyan, stdout);
131 fflush (stdout);
133 fputs ("Linus", stdout);
134 fflush (stdout);
136 user_data.background_color_cyan = false;
137 fputs (set_background_color_default, stdout);
138 fflush (stdout);
140 fputs (" Pauling", stdout);
141 fflush (stdout);
143 user_data.underline = false;
144 fputs (set_underline_off, stdout);
145 fflush (stdout);
147 /* Needed as a prerequisite of the deactivate_term_style_controller call
148 below. */
149 deactivate_term_non_default_mode (&controller, &user_data);
151 fputs ("!\n", stdout);
153 /* If the user_data was allocated in heap memory, with indefinite extent,
154 this call would be optional. But since we have allocated it on the
155 stack, we must deactivate it before it goes out of scope. Otherwise
156 we get undefined behaviour in an atexit() handler. */
157 deactivate_term_style_controller (&controller, &user_data);
159 return 0;