root/maint/gnulib/tests/test-term-style-control-hello.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 /* Simple 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 the line:     Hello Dr. Linus Pauling!
  31    with underlining here:                   _________________
  32    and a cyan background color here:            _____
  33  */
  34 
  35 /* ECMA-48 / ISO 6429 escape sequences.  See
  36    https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
  37  */
  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";
  42 
  43 struct term_style_user_data
  44 {
  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;
  49 
  50   struct term_style_control_data ctrl_data;
  51 };
  52 
  53 static struct term_style_control_data *
  54 get_control_data (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56   return &user_data->ctrl_data;
  57 }
  58 
  59 static void
  60 restore (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62   fputs (set_underline_off, stdout);
  63   fputs (set_background_color_default, stdout);
  64   fflush (stdout);
  65 }
  66 
  67 static _GL_ASYNC_SAFE void
  68 async_restore (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  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));
  75 }
  76 
  77 static _GL_ASYNC_SAFE void
  78 async_set_attributes_from_default (struct term_style_user_data *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  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));
  87 }
  88 
  89 static const struct term_style_controller controller =
  90 {
  91   get_control_data,
  92   restore,
  93   async_restore,
  94   async_set_attributes_from_default
  95 };
  96 
  97 int
  98 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100   struct term_style_user_data user_data;
 101 
 102   /* Initialization.  */
 103   user_data.underline = false;
 104   user_data.background_color_cyan = false;
 105 
 106   activate_term_style_controller (&controller, &user_data, STDOUT_FILENO,
 107                                   TTYCTL_AUTO);
 108 
 109   /* As long as no styling is needed, we can stay in the default mode.  */
 110   fputs ("Hello ", stdout);
 111   fflush (stdout);
 112 
 113   /* Before any styling, enable the non-default mode.  */
 114   activate_term_non_default_mode (&controller, &user_data);
 115 
 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);
 122 
 123   fputs ("Dr. ", stdout);
 124   fflush (stdout);
 125 
 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);
 132 
 133   fputs ("Linus", stdout);
 134   fflush (stdout);
 135 
 136   user_data.background_color_cyan = false;
 137   fputs (set_background_color_default, stdout);
 138   fflush (stdout);
 139 
 140   fputs (" Pauling", stdout);
 141   fflush (stdout);
 142 
 143   user_data.underline = false;
 144   fputs (set_underline_off, stdout);
 145   fflush (stdout);
 146 
 147   /* Needed as a prerequisite of the deactivate_term_style_controller call
 148      below.  */
 149   deactivate_term_non_default_mode (&controller, &user_data);
 150 
 151   fputs ("!\n", stdout);
 152 
 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);
 158 
 159   return 0;
 160 }

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