* gnulib-local/lib/ostream.oo.h (ostream_flush_scope_t): New type.
(ostream::flush): Add scope parameter.
* gnulib-local/lib/file-ostream.oo.c: Include <unistd.h>, <termios.h>.
(file_ostream::flush): Add a scope parameter.
* gnulib-local/modules/file-ostream (Depends-on): Add 'fsync'.
(configure.ac): Check for tcdrain.
* gnulib-local/lib/fd-ostream.oo.c: Include <unistd.h>, <termios.h>.
(fd_ostream::flush): Add a scope parameter.
(fd_ostream::free): Update flush call.
* gnulib-local/modules/fd-ostream (Depends-on): Add 'fsync'.
(configure.ac): Check for tcdrain.
* gnulib-local/lib/term-ostream.oo.c: Include <unistd.h>, <termios.h>.
(term_ostream::flush): Add scope parameter.
(term_ostream::free): Update flush call.
* gnulib-local/m4/term-ostream.m4 (gl_TERM_OSTREAM): Check for tcdrain.
* gnulib-local/modules/term-ostream (Depends-on): Add 'fsync'.
* gnulib-local/lib/memory-ostream.oo.c (memory_ostream::flush): Add scope
parameter.
* gnulib-local/lib/iconv-ostream.oo.c (iconv_ostream::flush): Add scope
parameter.
* gnulib-local/lib/html-ostream.oo.c (html_ostream::flush): Add scope parameter.
Emit closing </span> tags.
* gnulib-local/lib/fd-styled-ostream.oo.c (fd_styled_ostream::flush): Add scope
parameter.
* gnulib-local/lib/term-styled-ostream.oo.c (term_styled_ostream::flush): Add
scope parameter.
* gnulib-local/lib/html-styled-ostream.oo.c (html_styled_ostream::flush): Add
scope parameter.
* libtextstyle/lib/textstyle.h (ostream_flush_scope_t): New type.
(ostream_flush, styled_ostream_flush, file_ostream_flush, fd_ostream_flush,
term_ostream_flush, memory_ostream_flush, iconv_ostream_flush,
html_ostream_flush, term_styled_ostream_flush, html_styled_ostream_flush): Add
scope parameter.
* libtextstyle/doc/libtextstyle.texi (The ostream class): Add scope parameter to
flush method.
* libtextstyle/NEWS: Mention the change.
/* Output stream referring to a file descriptor.
- Copyright (C) 2006-2007 Free Software Foundation, Inc.
+ Copyright (C) 2006-2007, 2019 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2006.
This program is free software: you can redistribute it and/or modify
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#if HAVE_TCDRAIN
+# include <termios.h>
+#endif
#include "error.h"
#include "full-write.h"
}
static void
-fd_ostream::flush (fd_ostream_t stream)
+fd_ostream::flush (fd_ostream_t stream, ostream_flush_scope_t scope)
{
if (stream->buffer != NULL && stream->avail < BUFSIZE)
{
error (EXIT_FAILURE, errno, _("error writing to %s"), stream->filename);
stream->avail = BUFSIZE;
}
+ if (scope == FLUSH_ALL)
+ {
+ /* For streams connected to a disk file: */
+ fsync (stream->fd);
+ #if HAVE_TCDRAIN
+ /* For streams connected to a terminal: */
+ tcdrain (stream->fd);
+ #endif
+ }
}
static void
fd_ostream::free (fd_ostream_t stream)
{
- fd_ostream_flush (stream);
+ fd_ostream_flush (stream, FLUSH_THIS_STREAM);
free (stream->filename);
free (stream);
}
}
static void
-fd_styled_ostream::flush (fd_styled_ostream_t stream)
+fd_styled_ostream::flush (fd_styled_ostream_t stream, ostream_flush_scope_t scope)
{
- fd_ostream_flush (stream->destination);
+ fd_ostream_flush (stream->destination, scope);
}
static void
/* Output stream referring to an stdio FILE.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2019 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2006.
This program is free software: you can redistribute it and/or modify
#include "file-ostream.h"
#include <stdlib.h>
+#include <unistd.h>
+#if HAVE_TCDRAIN
+# include <termios.h>
+#endif
#include "xalloc.h"
}
static void
-file_ostream::flush (file_ostream_t stream)
+file_ostream::flush (file_ostream_t stream, ostream_flush_scope_t scope)
{
- /* This ostream has no internal buffer. No need to fflush (stream->fp),
- since it's external to this ostream. */
+ /* This ostream has no internal buffer, therefore nothing to do for
+ scope == FLUSH_THIS_STREAM. */
+ if (scope != FLUSH_THIS_STREAM)
+ {
+ fflush (stream->fp);
+ if (scope == FLUSH_ALL)
+ {
+ int fd = fileno (stream->fp);
+ if (fd >= 0)
+ {
+ /* For streams connected to a disk file: */
+ fsync (fd);
+ #if HAVE_TCDRAIN
+ /* For streams connected to a terminal: */
+ tcdrain (fd);
+ #endif
+ }
+ }
+ }
}
static void
size_t prev_class_stack_size = stream->curr_class_stack_size;
stream->curr_class_stack_size = 0;
emit_pending_spans (stream, false);
- ostream_write_str (stream->destination, "<br/>");
stream->curr_class_stack_size = prev_class_stack_size;
+ ostream_write_str (stream->destination, "<br/>");
shrink_class_stack (stream);
verify_invariants (stream);
}
}
static void
-html_ostream::flush (html_ostream_t stream)
+html_ostream::flush (html_ostream_t stream, ostream_flush_scope_t scope)
{
- /* There's nothing to do here, since stream->buf[] contains only a few
- bytes that don't correspond to a character, and it's not worth closing
- the open spans. */
+ verify_invariants (stream);
+ /* stream->buf[] contains only a few bytes that don't correspond to a
+ character. Can't flush it. */
+ /* Close the open <span> tags, and prepare for reopening the same <span>
+ tags. */
+ size_t prev_class_stack_size = stream->curr_class_stack_size;
+ stream->curr_class_stack_size = 0;
+ emit_pending_spans (stream, false);
+ stream->curr_class_stack_size = prev_class_stack_size;
+ shrink_class_stack (stream);
+ verify_invariants (stream);
+
+ if (scope != FLUSH_THIS_STREAM)
+ ostream_flush (stream->destination, scope);
}
static void
}
static void
-html_styled_ostream::flush (html_styled_ostream_t stream)
+html_styled_ostream::flush (html_styled_ostream_t stream, ostream_flush_scope_t scope)
{
- html_ostream_flush (stream->html_destination);
+ html_ostream_flush (stream->html_destination, scope);
}
static void
/* Output stream that converts the output to another encoding.
- Copyright (C) 2006-2007, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2006-2007, 2010, 2019 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2006.
This program is free software: you can redistribute it and/or modify
}
static void
-iconv_ostream::flush (iconv_ostream_t stream)
+iconv_ostream::flush (iconv_ostream_t stream, ostream_flush_scope_t scope)
{
- /* There's nothing we can do here, since stream->buf[] contains only a few
- bytes that don't correspond to a character. */
+ /* For scope == FLUSH_THIS_STREAM, there's nothing we can do here, since
+ stream->buf[] contains only a few bytes that don't correspond to a
+ character. */
+ if (scope != FLUSH_THIS_STREAM)
+ ostream_flush (stream->destination, scope);
}
static void
/* Output stream that accumulates the output in memory.
- Copyright (C) 2006-2007 Free Software Foundation, Inc.
+ Copyright (C) 2006-2007, 2019 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2006.
This program is free software: you can redistribute it and/or modify
}
static void
-memory_ostream::flush (memory_ostream_t stream)
+memory_ostream::flush (memory_ostream_t stream, ostream_flush_scope_t scope)
{
}
/* Abstract output stream data type.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2019 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2006.
This program is free software: you can redistribute it and/or modify
#include "moo.h"
+
+/* Describes the scope of a flush operation. */
+typedef enum
+{
+ /* Flushes buffers in this ostream_t.
+ Use this value if you want to write to the underlying ostream_t. */
+ FLUSH_THIS_STREAM = 0,
+ /* Flushes all buffers in the current process.
+ Use this value if you want to write to the same target through a
+ different file descriptor or a FILE stream. */
+ FLUSH_THIS_PROCESS = 1,
+ /* Flushes buffers in the current process and attempts to flush the buffers
+ in the kernel.
+ Use this value so that some other process (or the kernel itself)
+ may write to the same target. */
+ FLUSH_ALL = 2
+} ostream_flush_scope_t;
+
+
/* An output stream is an object to which one can feed a sequence of bytes. */
struct ostream
void write_mem (ostream_t stream, const void *data, size_t len);
/* Bring buffered data to its destination. */
- void flush (ostream_t stream);
+ void flush (ostream_t stream, ostream_flush_scope_t scope);
/* Close and free a stream. */
void free (ostream_t stream);
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#if HAVE_TCDRAIN
+# include <termios.h>
+#endif
#include "error.h"
#include "fatal-signal.h"
}
static void
-term_ostream::flush (term_ostream_t stream)
+term_ostream::flush (term_ostream_t stream, ostream_flush_scope_t scope)
{
output_buffer (stream);
+ if (scope == FLUSH_ALL)
+ {
+ /* For streams connected to a disk file: */
+ fsync (stream->fd);
+ #if HAVE_TCDRAIN
+ /* For streams connected to a terminal: */
+ tcdrain (stream->fd);
+ #endif
+ }
}
static void
term_ostream::free (term_ostream_t stream)
{
- term_ostream_flush (stream);
+ term_ostream_flush (stream, FLUSH_THIS_STREAM);
free (stream->filename);
if (stream->set_a_foreground != NULL)
free (stream->set_a_foreground);
}
static void
-term_styled_ostream::flush (term_styled_ostream_t stream)
+term_styled_ostream::flush (term_styled_ostream_t stream, ostream_flush_scope_t scope)
{
- term_ostream_flush (stream->destination);
+ term_ostream_flush (stream->destination, scope);
}
static void
-# term-ostream.m4 serial 1
-dnl Copyright (C) 2006 Free Software Foundation, Inc.
+# term-ostream.m4 serial 2
+dnl Copyright (C) 2006, 2019 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_TERM_OSTREAM],
[
AC_REQUIRE([AC_C_INLINE])
+ AC_CHECK_FUNCS_ONCE([tcdrain])
])
error
stdlib
full-write
+fsync
gettext
xalloc
configure.ac:
+AC_CHECK_FUNCS_ONCE([tcdrain])
Makefile.am:
lib_SOURCES += fd-ostream.c
Depends-on:
ostream
+fsync
xalloc
configure.ac:
+AC_CHECK_FUNCS_ONCE([tcdrain])
Makefile.am:
lib_SOURCES += file-ostream.c
fatal-signal
sigprocmask
full-write
+fsync
gettext-h
terminfo-h
xalloc
/lib/float+.h
/lib/float.c
/lib/float.in.h
+/lib/fsync.c
/lib/full-write.c
/lib/full-write.h
/lib/getprogname.c
+New in 0.6:
+* The ostream_t operation 'flush' now takes an additional argument, of type
+ ostream_flush_scope_t.
+
New in 0.5:
* The libtextstyle library can now be built and installed independently
Writes a string's contents to a stream.
@end deftypefn
-@deftypefn Function void ostream_flush (ostream_t@tie{}@var{stream})
+@deftypefn Function void ostream_flush (ostream_t@tie{}@var{stream}, ostream_flush_scope_t@tie{}@var{scope})
Brings buffered data to its destination.
@end deftypefn
/* ----------------------------- From ostream.h ----------------------------- */
+/* Describes the scope of a flush operation. */
+typedef enum
+{
+ /* Flushes buffers in this ostream_t.
+ Use this value if you want to write to the underlying ostream_t. */
+ FLUSH_THIS_STREAM = 0,
+ /* Flushes all buffers in the current process.
+ Use this value if you want to write to the same target through a
+ different file descriptor or a FILE stream. */
+ FLUSH_THIS_PROCESS = 1,
+ /* Flushes buffers in the current process and attempts to flush the buffers
+ in the kernel.
+ Use this value so that some other process (or the kernel itself)
+ may write to the same target. */
+ FLUSH_ALL = 2
+} ostream_flush_scope_t;
+
+
/* An output stream is an object to which one can feed a sequence of bytes. */
struct any_ostream_representation;
extern "C" {
#endif
extern void ostream_write_mem (ostream_t first_arg, const void *data, size_t len);
-extern void ostream_flush (ostream_t first_arg);
+extern void ostream_flush (ostream_t first_arg, ostream_flush_scope_t scope);
extern void ostream_free (ostream_t first_arg);
#ifdef __cplusplus
}
extern "C" {
#endif
extern void styled_ostream_write_mem (styled_ostream_t first_arg, const void *data, size_t len);
-extern void styled_ostream_flush (styled_ostream_t first_arg);
+extern void styled_ostream_flush (styled_ostream_t first_arg, ostream_flush_scope_t scope);
extern void styled_ostream_free (styled_ostream_t first_arg);
extern void styled_ostream_begin_use_class (styled_ostream_t first_arg, const char *classname);
extern void styled_ostream_end_use_class (styled_ostream_t first_arg, const char *classname);
extern "C" {
#endif
extern void file_ostream_write_mem (file_ostream_t first_arg, const void *data, size_t len);
-extern void file_ostream_flush (file_ostream_t first_arg);
+extern void file_ostream_flush (file_ostream_t first_arg, ostream_flush_scope_t scope);
extern void file_ostream_free (file_ostream_t first_arg);
#ifdef __cplusplus
}
extern "C" {
#endif
extern void fd_ostream_write_mem (fd_ostream_t first_arg, const void *data, size_t len);
-extern void fd_ostream_flush (fd_ostream_t first_arg);
+extern void fd_ostream_flush (fd_ostream_t first_arg, ostream_flush_scope_t scope);
extern void fd_ostream_free (fd_ostream_t first_arg);
#ifdef __cplusplus
}
extern "C" {
#endif
extern void term_ostream_write_mem (term_ostream_t first_arg, const void *data, size_t len);
-extern void term_ostream_flush (term_ostream_t first_arg);
+extern void term_ostream_flush (term_ostream_t first_arg, ostream_flush_scope_t scope);
extern void term_ostream_free (term_ostream_t first_arg);
extern term_color_t term_ostream_rgb_to_color (term_ostream_t first_arg, int red, int green, int blue);
extern term_color_t term_ostream_get_color (term_ostream_t first_arg);
extern "C" {
#endif
extern void memory_ostream_write_mem (memory_ostream_t first_arg, const void *data, size_t len);
-extern void memory_ostream_flush (memory_ostream_t first_arg);
+extern void memory_ostream_flush (memory_ostream_t first_arg, ostream_flush_scope_t scope);
extern void memory_ostream_free (memory_ostream_t first_arg);
extern void memory_ostream_contents (memory_ostream_t first_arg, const void **bufp, size_t *buflenp);
#ifdef __cplusplus
extern "C" {
#endif
extern void iconv_ostream_write_mem (iconv_ostream_t first_arg, const void *data, size_t len);
-extern void iconv_ostream_flush (iconv_ostream_t first_arg);
+extern void iconv_ostream_flush (iconv_ostream_t first_arg, ostream_flush_scope_t scope);
extern void iconv_ostream_free (iconv_ostream_t first_arg);
#ifdef __cplusplus
}
extern "C" {
#endif
extern void html_ostream_write_mem (html_ostream_t first_arg, const void *data, size_t len);
-extern void html_ostream_flush (html_ostream_t first_arg);
+extern void html_ostream_flush (html_ostream_t first_arg, ostream_flush_scope_t scope);
extern void html_ostream_free (html_ostream_t first_arg);
extern void html_ostream_begin_span (html_ostream_t first_arg, const char *classname);
extern void html_ostream_end_span (html_ostream_t first_arg, const char *classname);
extern "C" {
#endif
extern void term_styled_ostream_write_mem (term_styled_ostream_t first_arg, const void *data, size_t len);
-extern void term_styled_ostream_flush (term_styled_ostream_t first_arg);
+extern void term_styled_ostream_flush (term_styled_ostream_t first_arg, ostream_flush_scope_t scope);
extern void term_styled_ostream_free (term_styled_ostream_t first_arg);
extern void term_styled_ostream_begin_use_class (term_styled_ostream_t first_arg, const char *classname);
extern void term_styled_ostream_end_use_class (term_styled_ostream_t first_arg, const char *classname);
extern "C" {
#endif
extern void html_styled_ostream_write_mem (html_styled_ostream_t first_arg, const void *data, size_t len);
-extern void html_styled_ostream_flush (html_styled_ostream_t first_arg);
+extern void html_styled_ostream_flush (html_styled_ostream_t first_arg, ostream_flush_scope_t scope);
extern void html_styled_ostream_free (html_styled_ostream_t first_arg);
extern void html_styled_ostream_begin_use_class (html_styled_ostream_t first_arg, const char *classname);
extern void html_styled_ostream_end_use_class (html_styled_ostream_t first_arg, const char *classname);