root/maint/gnulib/tests/test-term-style-control-yes.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_control_data
  2. restore
  3. async_restore
  4. async_set_attributes_from_default
  5. main

   1 /* Interactive test program for the term-style-control module.
   2    Copyright (C) 2019-2021 Free Software Foundation, Inc.
   3    Written by Bruno Haible <bruno@clisp.org>, 2019.
   4 
   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.
   9 
  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.
  14 
  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/>.  */
  17 
  18 #include <config.h>
  19 
  20 /* Specification.  */
  21 #include "term-style-control.h"
  22 
  23 #include <stdbool.h>
  24 #include <stdio.h>
  25 #include <string.h>
  26 #include <unistd.h>
  27 
  28 #include "full-write.h"
  29 
  30 /* This program outputs an endless amount of lines, each consisting of a
  31    single 'y', in red color and underlined.
  32    It can be used to exercise race conditions caused by
  33      - simultaneous keyboard input on the terminal,
  34      - pressing Ctrl-C,
  35      - pressing Ctrl-Z and then "fg".  */
  36 
  37 /* ECMA-48 / ISO 6429 escape sequences.  See
  38    https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
  39  */
  40 static const char set_underline_on[] = "\033[4m";
  41 static const char set_underline_off[] = "\033[24m";
  42 static const char set_foreground_color_red[] = "\033[31m";
  43 static const char set_foreground_color_default[] = "\033[39m";
  44 
  45 struct term_style_user_data
  46 {
  47   /* This field is marked volatile, because it is accessed from the
  48      async-safe function async_set_attributes_from_default.  */
  49   bool volatile red_and_underline;
  50 
  51   struct term_style_control_data ctrl_data;
  52 };
  53 
  54 static struct term_style_control_data *
  55 get_control_data (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57   return &user_data->ctrl_data;
  58 }
  59 
  60 static void
  61 restore (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63   fputs (set_underline_off, stdout);
  64   fputs (set_foreground_color_default, stdout);
  65   fflush (stdout);
  66 }
  67 
  68 static _GL_ASYNC_SAFE void
  69 async_restore (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  70 {
  71   /* No <stdio.h> calls here!  */
  72   full_write (STDOUT_FILENO, set_underline_off,
  73               strlen (set_underline_off));
  74   full_write (STDOUT_FILENO, set_foreground_color_default,
  75               strlen (set_foreground_color_default));
  76 }
  77 
  78 static _GL_ASYNC_SAFE void
  79 async_set_attributes_from_default (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81   /* No <stdio.h> calls here!  */
  82   if (user_data->red_and_underline)
  83     {
  84       full_write (STDOUT_FILENO, set_underline_on,
  85                   strlen (set_underline_on));
  86       full_write (STDOUT_FILENO, set_foreground_color_red,
  87                   strlen (set_foreground_color_red));
  88     }
  89 }
  90 
  91 static const struct term_style_controller controller =
  92 {
  93   get_control_data,
  94   restore,
  95   async_restore,
  96   async_set_attributes_from_default
  97 };
  98 
  99 int
 100 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102   struct term_style_user_data user_data;
 103 
 104   /* Initialization.  */
 105   user_data.red_and_underline = false;
 106 
 107   activate_term_style_controller (&controller, &user_data, STDOUT_FILENO,
 108                                   TTYCTL_AUTO);
 109 
 110   for (;;)
 111     {
 112       /* Before any styling, enable the non-default mode.  */
 113       activate_term_non_default_mode (&controller, &user_data);
 114 
 115       /* Set user_data.red_and_underline *before* emitting the appropriate
 116          escape sequences, otherwise async_set_attributes_from_default will not
 117          do its job correctly.  */
 118       user_data.red_and_underline = true;
 119       fputs (set_underline_on, stdout);
 120       fputs (set_foreground_color_red, stdout);
 121       fflush (stdout);
 122 
 123       fputs ("y", stdout);
 124       fflush (stdout);
 125 
 126       /* Revert to the default style before emitting a newline.  */
 127       user_data.red_and_underline = false;
 128       fputs (set_underline_off, stdout);
 129       fputs (set_foreground_color_default, stdout);
 130       fflush (stdout);
 131 
 132       /* Optional.  */
 133       deactivate_term_non_default_mode (&controller, &user_data);
 134 
 135       fputs ("\n", stdout);
 136       fflush (stdout);
 137     }
 138 }

/* [previous][next][first][last][top][bottom][index][help] */