1 /* Dummy replacement for part of the public API of the libtextstyle library.
2 Copyright (C) 2006-2007, 2019-2021 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2019. */
18
19 /* This file is used as replacement when libtextstyle with its include file
20 <textstyle.h> is not found.
21 It supports the essential API and implements it in a way that does not
22 provide text styling. That is, it produces plain text output via <stdio.h>
23 FILE objects.
24 Thus, it allows a package to be build with or without a dependency to
25 libtextstyle, with very few occurrences of '#if HAVE_LIBTEXTSTYLE'.
26
27 Restriction:
28 It assumes that freopen() is not being called on stdout and stderr. */
29
30 #ifndef _TEXTSTYLE_H
31 #define _TEXTSTYLE_H
32
33 #include <errno.h>
34 #include <stdarg.h>
35 #include <stdbool.h>
36 #include <stddef.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #if HAVE_TCDRAIN
42 # include <termios.h>
43 #endif
44
45 /* An __attribute__ __format__ specifier for a function that takes a format
46 string and arguments, where the format string directives are the ones
47 standardized by ISO C99 and POSIX.
48 _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD */
49 /* __gnu_printf__ is supported in GCC >= 4.4. */
50 #ifndef _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD
51 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
52 # define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __gnu_printf__
53 # else
54 # define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __printf__
55 # endif
56 #endif
57
58 /* _GL_ATTRIBUTE_MAYBE_UNUSED declares that it is not a programming mistake if
59 the entity is not used. The compiler should not warn if the entity is not
60 used. */
61 #ifndef _GL_ATTRIBUTE_MAYBE_UNUSED
62 # if 0 /* no GCC or clang version supports this yet */
63 # define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]
64 # elif defined __GNUC__ || defined __clang__
65 # define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__))
66 # else
67 # define _GL_ATTRIBUTE_MAYBE_UNUSED
68 # endif
69 #endif
70
71 /* ----------------------------- From ostream.h ----------------------------- */
72
73 /* Describes the scope of a flush operation. */
74 typedef enum
75 {
76 /* Flushes buffers in this ostream_t.
77 Use this value if you want to write to the underlying ostream_t. */
78 FLUSH_THIS_STREAM = 0,
79 /* Flushes all buffers in the current process.
80 Use this value if you want to write to the same target through a
81 different file descriptor or a FILE stream. */
82 FLUSH_THIS_PROCESS = 1,
83 /* Flushes buffers in the current process and attempts to flush the buffers
84 in the kernel.
85 Use this value so that some other process (or the kernel itself)
86 may write to the same target. */
87 FLUSH_ALL = 2
88 } ostream_flush_scope_t;
89
90
91 /* An output stream is an object to which one can feed a sequence of bytes. */
92
93 typedef FILE * ostream_t;
94
95 static inline void
96 ostream_write_mem (ostream_t stream, const void *data, size_t len)
97 {
98 if (len > 0)
99 fwrite (data, 1, len, stream);
100 }
101
102 static inline void
103 ostream_flush (ostream_t stream, ostream_flush_scope_t scope)
104 {
105 fflush (stream);
106 if (scope == FLUSH_ALL)
107 {
108 int fd = fileno (stream);
109 if (fd >= 0)
110 {
111 /* For streams connected to a disk file: */
112 fsync (fd);
113 #if HAVE_TCDRAIN
114 /* For streams connected to a terminal: */
115 {
116 int retval;
117
118 do
119 retval = tcdrain (fd);
120 while (retval < 0 && errno == EINTR);
121 }
122 #endif
123 }
124 }
125 }
126
127 static inline void
128 ostream_free (ostream_t stream)
129 {
130 if (stream == stdin || stream == stderr)
131 fflush (stream);
132 else
133 fclose (stream);
134 }
135
136 static inline void
137 ostream_write_str (ostream_t stream, const char *string)
138 {
139 ostream_write_mem (stream, string, strlen (string));
140 }
141
142 static inline ptrdiff_t ostream_printf (ostream_t stream,
143 const char *format, ...)
144 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || defined __clang__
145 __attribute__ ((__format__ (_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 2, 3)))
146 #endif
147 ;
148 static inline ptrdiff_t
149 ostream_printf (ostream_t stream, const char *format, ...)
150 {
151 va_list args;
152 char *temp_string;
153 ptrdiff_t ret;
154
155 va_start (args, format);
156 ret = vasprintf (&temp_string, format, args);
157 va_end (args);
158 if (ret >= 0)
159 {
160 if (ret > 0)
161 ostream_write_str (stream, temp_string);
162 free (temp_string);
163 }
164 return ret;
165 }
166
167 static inline ptrdiff_t ostream_vprintf (ostream_t stream,
168 const char *format, va_list args)
169 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || defined __clang__
170 __attribute__ ((__format__ (_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 2, 0)))
171 #endif
172 ;
173 static inline ptrdiff_t
174 ostream_vprintf (ostream_t stream, const char *format, va_list args)
175 {
176 char *temp_string;
177 ptrdiff_t ret = vasprintf (&temp_string, format, args);
178 if (ret >= 0)
179 {
180 if (ret > 0)
181 ostream_write_str (stream, temp_string);
182 free (temp_string);
183 }
184 return ret;
185 }
186
187 /* ------------------------- From styled-ostream.h ------------------------- */
188
189 typedef ostream_t styled_ostream_t;
190
191 #define styled_ostream_write_mem ostream_write_mem
192 #define styled_ostream_flush ostream_flush
193 #define styled_ostream_free ostream_free
194
195 static inline void
196 styled_ostream_begin_use_class (_GL_ATTRIBUTE_MAYBE_UNUSED styled_ostream_t stream,
197 _GL_ATTRIBUTE_MAYBE_UNUSED const char *classname)
198 {
199 }
200
201 static inline void
202 styled_ostream_end_use_class (_GL_ATTRIBUTE_MAYBE_UNUSED styled_ostream_t stream,
203 _GL_ATTRIBUTE_MAYBE_UNUSED const char *classname)
204 {
205 }
206
207 static inline const char *
208 styled_ostream_get_hyperlink_ref (_GL_ATTRIBUTE_MAYBE_UNUSED styled_ostream_t stream)
209 {
210 return NULL;
211 }
212
213 static inline const char *
214 styled_ostream_get_hyperlink_id (_GL_ATTRIBUTE_MAYBE_UNUSED styled_ostream_t stream)
215 {
216 return NULL;
217 }
218
219 static inline void
220 styled_ostream_set_hyperlink (_GL_ATTRIBUTE_MAYBE_UNUSED styled_ostream_t stream,
221 _GL_ATTRIBUTE_MAYBE_UNUSED const char *ref,
222 _GL_ATTRIBUTE_MAYBE_UNUSED const char *id)
223 {
224 }
225
226 static inline void
227 styled_ostream_flush_to_current_style (_GL_ATTRIBUTE_MAYBE_UNUSED styled_ostream_t stream)
228 {
229 }
230
231 /* -------------------------- From file-ostream.h -------------------------- */
232
233 typedef ostream_t file_ostream_t;
234
235 #define file_ostream_write_mem ostream_write_mem
236 #define file_ostream_flush ostream_flush
237 #define file_ostream_free ostream_free
238
239 static inline file_ostream_t
240 file_ostream_create (FILE *fp)
241 {
242 return fp;
243 }
244
245 /* --------------------------- From fd-ostream.h --------------------------- */
246
247 typedef ostream_t fd_ostream_t;
248
249 #define fd_ostream_write_mem ostream_write_mem
250 #define fd_ostream_flush ostream_flush
251 #define fd_ostream_free ostream_free
252
253 static inline fd_ostream_t
254 fd_ostream_create (int fd, _GL_ATTRIBUTE_MAYBE_UNUSED const char *filename,
255 _GL_ATTRIBUTE_MAYBE_UNUSED bool buffered)
256 {
257 if (fd == 1)
258 return stdout;
259 else if (fd == 2)
260 return stderr;
261 else
262 return fdopen (fd, "w");
263 }
264
265 /* -------------------------- From term-ostream.h -------------------------- */
266
267 typedef int term_color_t;
268 enum
269 {
270 COLOR_DEFAULT = -1 /* unknown */
271 };
272
273 typedef enum
274 {
275 WEIGHT_NORMAL = 0,
276 WEIGHT_BOLD,
277 WEIGHT_DEFAULT = WEIGHT_NORMAL
278 } term_weight_t;
279
280 typedef enum
281 {
282 POSTURE_NORMAL = 0,
283 POSTURE_ITALIC, /* same as oblique */
284 POSTURE_DEFAULT = POSTURE_NORMAL
285 } term_posture_t;
286
287 typedef enum
288 {
289 UNDERLINE_OFF = 0,
290 UNDERLINE_ON,
291 UNDERLINE_DEFAULT = UNDERLINE_OFF
292 } term_underline_t;
293
294 typedef ostream_t term_ostream_t;
295
296 #define term_ostream_write_mem ostream_write_mem
297 #define term_ostream_flush ostream_flush
298 #define term_ostream_free ostream_free
299
300 static inline term_color_t
301 term_ostream_get_color (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream)
302 {
303 return COLOR_DEFAULT;
304 }
305
306 static inline void
307 term_ostream_set_color (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream,
308 _GL_ATTRIBUTE_MAYBE_UNUSED term_color_t color)
309 {
310 }
311
312 static inline term_color_t
313 term_ostream_get_bgcolor (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream)
314 {
315 return COLOR_DEFAULT;
316 }
317
318 static inline void
319 term_ostream_set_bgcolor (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream,
320 _GL_ATTRIBUTE_MAYBE_UNUSED term_color_t color)
321 {
322 }
323
324 static inline term_weight_t
325 term_ostream_get_weight (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream)
326 {
327 return WEIGHT_DEFAULT;
328 }
329
330 static inline void
331 term_ostream_set_weight (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream,
332 _GL_ATTRIBUTE_MAYBE_UNUSED term_weight_t weight)
333 {
334 }
335
336 static inline term_posture_t
337 term_ostream_get_posture (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream)
338 {
339 return POSTURE_DEFAULT;
340 }
341
342 static inline void
343 term_ostream_set_posture (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream,
344 _GL_ATTRIBUTE_MAYBE_UNUSED term_posture_t posture)
345 {
346 }
347
348 static inline term_underline_t
349 term_ostream_get_underline (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream)
350 {
351 return UNDERLINE_DEFAULT;
352 }
353
354 static inline void
355 term_ostream_set_underline (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream,
356 _GL_ATTRIBUTE_MAYBE_UNUSED term_underline_t underline)
357 {
358 }
359
360 static inline const char *
361 term_ostream_get_hyperlink_ref (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream)
362 {
363 return NULL;
364 }
365
366 static inline const char *
367 term_ostream_get_hyperlink_id (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream)
368 {
369 return NULL;
370 }
371
372 static inline void
373 term_ostream_set_hyperlink (_GL_ATTRIBUTE_MAYBE_UNUSED term_ostream_t stream,
374 _GL_ATTRIBUTE_MAYBE_UNUSED const char *ref,
375 _GL_ATTRIBUTE_MAYBE_UNUSED const char *id)
376 {
377 }
378
379 static inline void
380 term_ostream_flush_to_current_style (term_ostream_t stream)
381 {
382 fflush (stream);
383 }
384
385 typedef enum
386 {
387 TTYCTL_AUTO = 0, /* Automatic best-possible choice. */
388 TTYCTL_NONE, /* No control.
389 Result: Garbled output can occur, and the terminal can
390 be left in any state when the program is interrupted. */
391 TTYCTL_PARTIAL, /* Signal handling.
392 Result: Garbled output can occur, but the terminal will
393 be left in the default state when the program is
394 interrupted. */
395 TTYCTL_FULL /* Signal handling and disabling echo and flush-upon-signal.
396 Result: No garbled output, and the the terminal will
397 be left in the default state when the program is
398 interrupted. */
399 } ttyctl_t;
400
401 static inline term_ostream_t
402 term_ostream_create (int fd, const char *filename,
403 _GL_ATTRIBUTE_MAYBE_UNUSED ttyctl_t tty_control)
404 {
405 return fd_ostream_create (fd, filename, true);
406 }
407
408 /* ----------------------- From term-styled-ostream.h ----------------------- */
409
410 typedef styled_ostream_t term_styled_ostream_t;
411
412 #define term_styled_ostream_write_mem ostream_write_mem
413 #define term_styled_ostream_flush ostream_flush
414 #define term_styled_ostream_free ostream_free
415 #define term_styled_ostream_begin_use_class styled_ostream_begin_use_class
416 #define term_styled_ostream_end_use_class styled_ostream_end_use_class
417 #define term_styled_ostream_get_hyperlink_ref styled_ostream_get_hyperlink_ref
418 #define term_styled_ostream_get_hyperlink_id styled_ostream_get_hyperlink_id
419 #define term_styled_ostream_set_hyperlink styled_ostream_set_hyperlink
420 #define term_styled_ostream_flush_to_current_style styled_ostream_flush_to_current_style
421
422 static inline term_styled_ostream_t
423 term_styled_ostream_create (int fd, const char *filename,
424 _GL_ATTRIBUTE_MAYBE_UNUSED ttyctl_t tty_control,
425 _GL_ATTRIBUTE_MAYBE_UNUSED const char *css_filename)
426 {
427 return fd_ostream_create (fd, filename, true);
428 }
429
430 /* ----------------------- From html-styled-ostream.h ----------------------- */
431
432 typedef styled_ostream_t html_styled_ostream_t;
433
434 static inline html_styled_ostream_t
435 html_styled_ostream_create (_GL_ATTRIBUTE_MAYBE_UNUSED ostream_t destination,
436 _GL_ATTRIBUTE_MAYBE_UNUSED const char *css_filename)
437 {
438 abort ();
439 return NULL;
440 }
441
442 /* ------------------------------ From color.h ------------------------------ */
443
444 #define color_test_mode false
445
446 enum color_option { color_no, color_tty, color_yes, color_html };
447 #define color_mode color_no
448
449 #define style_file_name NULL
450
451 static inline bool
452 handle_color_option (_GL_ATTRIBUTE_MAYBE_UNUSED const char *option)
453 {
454 return false;
455 }
456
457 static inline void
458 handle_style_option (_GL_ATTRIBUTE_MAYBE_UNUSED const char *option)
459 {
460 }
461
462 static inline void
463 print_color_test (void)
464 {
465 abort ();
466 }
467
468 static inline void
469 style_file_prepare (_GL_ATTRIBUTE_MAYBE_UNUSED const char *style_file_envvar,
470 _GL_ATTRIBUTE_MAYBE_UNUSED const char *stylesdir_envvar,
471 _GL_ATTRIBUTE_MAYBE_UNUSED const char *stylesdir_after_install,
472 _GL_ATTRIBUTE_MAYBE_UNUSED const char *default_style_file)
473 {
474 }
475
476 /* ------------------------------ From misc.h ------------------------------ */
477
478 static inline styled_ostream_t
479 styled_ostream_create (int fd, const char *filename,
480 _GL_ATTRIBUTE_MAYBE_UNUSED ttyctl_t tty_control,
481 _GL_ATTRIBUTE_MAYBE_UNUSED const char *css_filename)
482 {
483 return fd_ostream_create (fd, filename, true);
484 }
485
486 static inline void
487 libtextstyle_set_failure_exit_code (_GL_ATTRIBUTE_MAYBE_UNUSED int exit_code)
488 {
489 }
490
491 #endif /* _TEXTSTYLE_H */