ruby-changes:67833
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:02:32 +0900 (JST)
Subject: [ruby-changes:67833] 809138fe4b (master): include/ruby/io.h: add doxyen
https://git.ruby-lang.org/ruby.git/commit/?id=809138fe4b From 809138fe4bb4e72b9c790de794b6ca50b8586291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Thu, 8 Jul 2021 12:48:32 +0900 Subject: include/ruby/io.h: add doxyen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/io.h | 837 +++++++++++++++++++++++++++++++++++++++++++++++-- template/Doxyfile.tmpl | 1 + 2 files changed, 809 insertions(+), 29 deletions(-) diff --git a/include/ruby/io.h b/include/ruby/io.h index dfef85b..c117087 100644 --- a/include/ruby/io.h +++ b/include/ruby/io.h @@ -20,6 +20,8 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/io.h#L20 #endif #include <errno.h> + +/** @cond INTERNAL_MACRO */ #if defined(HAVE_POLL) # ifdef _AIX # define reqevents events @@ -40,39 +42,99 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/io.h#L42 # define RB_WAITFD_PRI 0x002 # define RB_WAITFD_OUT 0x004 #endif +/** @endcond */ -typedef enum { - RUBY_IO_READABLE = RB_WAITFD_IN, - RUBY_IO_WRITABLE = RB_WAITFD_OUT, - RUBY_IO_PRIORITY = RB_WAITFD_PRI, -} rb_io_event_t; - +#include "ruby/internal/attr/const.h" +#include "ruby/internal/attr/pure.h" +#include "ruby/internal/attr/noreturn.h" #include "ruby/internal/dllexport.h" +#include "ruby/internal/value.h" +#include "ruby/backward/2/attributes.h" /* PACKED_STRUCT_UNALIGNED */ + RBIMPL_SYMBOL_EXPORT_BEGIN() +struct stat; +struct timeval; + +/** + * Type of events that an IO can wait. + * + * @internal + * + * This is visible from extension libraries because `io/wait` wants it. + */ +typedef enum { + RUBY_IO_READABLE = RB_WAITFD_IN, /**< `IO::READABLE` */ + RUBY_IO_WRITABLE = RB_WAITFD_OUT, /**< `IO::WRITABLE` */ + RUBY_IO_PRIORITY = RB_WAITFD_PRI, /**< `IO::PRIORITY` */ +} rb_io_event_t; + +/** + * IO buffers. This is an implementation detail of ::rb_io_t::wbuf and + * ::rb_io_t::rbuf. People don't manipulate it directly. + */ PACKED_STRUCT_UNALIGNED(struct rb_io_buffer_t { + + /** Pointer to the underlying memory region, of at least `capa` bytes. */ char *ptr; /* off + len <= capa */ + + /** Offset inside of `ptr`. */ int off; + + /** Length of the buffer. */ int len; + + /** Designed capacity of the buffer. */ int capa; }); + +/** @alias{rb_io_buffer_t} */ typedef struct rb_io_buffer_t rb_io_buffer_t; +/** Ruby's IO, metadata and buffers. */ typedef struct rb_io_t { + + /** The IO's Ruby level counterpart. */ VALUE self; - FILE *stdio_file; /* stdio ptr for read/write if available */ - int fd; /* file descriptor */ - int mode; /* mode flags: FMODE_XXXs */ - rb_pid_t pid; /* child's pid (for pipes) */ - int lineno; /* number of lines read */ - VALUE pathv; /* pathname for file */ - void (*finalize)(struct rb_io_t*,int); /* finalize proc */ + /** stdio ptr for read/write, if available. */ + FILE *stdio_file; + + /** file descriptor. */ + int fd; + + /** mode flags: FMODE_XXXs */ + int mode; + + /** child's pid (for pipes) */ + rb_pid_t pid; - rb_io_buffer_t wbuf, rbuf; + /** number of lines read */ + int lineno; + /** pathname for file */ + VALUE pathv; + + /** finalize proc */ + void (*finalize)(struct rb_io_t*,int); + + /** Write buffer. */ + rb_io_buffer_t wbuf; + + /** + * (Byte) read buffer. Note also that there is a field called + * ::rb_io_t::cbuf, which also concerns read IO. + */ + rb_io_buffer_t rbuf; + + /** + * Duplex IO object, if set. + * + * @see rb_io_set_write_io() + */ VALUE tied_io_for_writing; + /** Decomposed encoding flags (e.g. `"enc:enc2""`). */ /* * enc enc2 read action write action * NULL NULL force_encoding(default_external) write the byte sequence of str @@ -80,106 +142,823 @@ typedef struct rb_io_t { https://github.com/ruby/ruby/blob/trunk/include/ruby/io.h#L142 * e1 e2 convert from e2 to e1 convert str.encoding to e2 */ struct rb_io_enc_t { + /** Internal encoding. */ rb_encoding *enc; + + /** External encoding. */ rb_encoding *enc2; + + /** + * Flags. + * + * @see enum ::ruby_econv_flag_type + */ int ecflags; + + /** + * Flags as Ruby hash. + * + * @internal + * + * This is set. But used from nowhere maybe? + */ VALUE ecopts; - } encs; + } encs; /**< Decomposed encoding flags. */ + /** Encoding converter used when reading from this IO. */ rb_econv_t *readconv; + + /** + * rb_io_ungetc() destination. This buffer is read before checking + * ::rb_io_t::rbuf + */ rb_io_buffer_t cbuf; + /** Encoding converter used when writing to this IO. */ rb_econv_t *writeconv; + + /** + * This is, when set, an instance of ::rb_cString which holds the "common" + * encoding. Write conversion can convert strings twice... In case + * conversion from encoding X to encoding Y does not exist, Ruby finds an + * encoding Z that bridges the two, so that X to Z to Y conversion happens. + */ VALUE writeconv_asciicompat; + + /** Whether ::rb_io_t::writeconv is already set up. */ int writeconv_initialized; + + /** + * Value of ::rb_io_t::rb_io_enc_t::ecflags stored right before + * initialising ::rb_io_t::writeconv. + */ int writeconv_pre_ecflags; + + /** + * Value of ::rb_io_t::rb_io_enc_t::ecopts stored right before initialising + * ::rb_io_t::writeconv. + */ VALUE writeconv_pre_ecopts; + /** + * This is a Ruby level mutex. It avoids multiple threads to write to an + * IO at once; helps for instance rb_io_puts() to ensure newlines right + * next to its arguments. + * + * This of course doesn't help inter-process IO interleaves, though. + */ VALUE write_lock; } rb_io_t; +/** @alias{rb_io_enc_t} */ typedef struct rb_io_enc_t rb_io_enc_t; +/** + * @private + * + * @deprecated This macro once was a thing in the old days, but makes no sense + * any longer today. Exists here for backwards compatibility + * only. You can safely forget about it. + */ #define HAVE_RB_IO_T 1 +/** + * @name Possible flags for ::rb_io_t::mode + * + * @{ + */ + +/** The IO is opened for reading. */ #define FMODE_READABLE 0x00000001 + +/** The IO is opened for writing. */ #define FMODE_WRITABLE 0x00000002 + +/** The IO is opened for both read/write. */ #define FMODE_READWRITE (FMODE_READABLE|FMODE_WRITABLE) + +/** + * The IO is in "binary mode". This is not what everything rb_io_binmode() + * concerns. This low-level flag is to stop CR <-> CRLF conversions that would + * happen in the underlying operating system. + * + * Setting this one and #FMODE_TEXTMODE at the same time is a contradiction. + * Setting this one and #ECONV_NEWLINE_DECORATOR_MASK at the same time is also + * a contradiction. + */ #define FMODE_BINMODE 0x00000004 + +/** + * The IO is in "sync mode". All output is immediately flushed to the + * underlying operating system then. Can be set via rb_io_synchronized(), but + * there is no way except calling `IO#sync=` to reset. + */ #define FMODE_SYNC 0x00000008 + +/** + * The IO is a TTY. What is a TTY and what isn't depends on the underlying + * operating system's `isatty(3)` output. You cannot change this. + */ #define FMODE_TTY 0x00000010 + +/** + * Ruby eventually detects that the IO is bidirectional. For instance a TTY + * has such property. There are several other things known to be duplexed. + * Additionally you (extension library authors) can also implement your own + * bidirectional IO subclasses. One of such example is `Socket`. + */ #define FMODE_DUPLEX 0x00000020 + +/** + * The IO is opened for appending. This mode always writes at the end of the + * IO. Ruby manages this flag for record but basically the logic behind this + * mode is at the underlying operating system. We almost do nothing. + */ #define FMODE_APPEND 0x00000040 + +/** + * The IO is opened for creating. This makes sense only when the destination + * file does not exist at the time the IO object was created. This is the + * default mode for writing, but you can pass `"r+"` to `IO.open` etc., to + * reroute this creation. + */ #define FMODE_CREATE 0x00000080 /* #define FMODE_NOREVLOOKUP 0x00000100 */ + +/** + * This flag amends the effect of #FMODE_CREATE, so that if there already is a + * file at the given path the operation fails. Using this you can be sure that + * the file you get is a fresh new one. + */ #define FMODE_EXCL 0x00000400 + +/** + * This flag amends the effect of #FMODE_CREATE, so that if there already is a + * file at the given path it gets truncated. + */ #define FMODE_TRUNC 0x00000800 + +/** + * The IO is in "text mode". On systems where such mode make sense, this flag + * changes the way the IO handles the contents. On POSIX systems it is + * basically a no-op, but with this flag set you can optionally let Ruby + * manually convert newlines, unlike when in binary mode: + * + * ```ruby + * IO.open("/p/a/t/h", "wt", crlf_newline: true) # "wb" is NG. + * ``` + * + * Setting this one and #FMODE_BINMODE at the same time is a contradiction. + */ #define FMODE_TEXTMODE 0x00001000 /* #define FMODE_PREP 0x00010000 */ +/* #define FMODE_SIGNAL_ON_EPIPE 0x00020000 */ + +/** + * This flag amends the encoding of the IO so that the BOM of the contents of + * the IO takes effect (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/