diff options
author | Samuel Williams <[email protected]> | 2025-04-16 16:50:37 +0900 |
---|---|---|
committer | GitHub <[email protected]> | 2025-04-16 07:50:37 +0000 |
commit | 8d21f666b8098545a366c46f1990edf2a9f4ffcb (patch) | |
tree | cea6dfae46d94d2dbfbd24cc0a332ed37417ea0f /include/ruby | |
parent | d842554769157087f23459e8f0ef9eec8fd7b7fe (diff) |
Introduce `enum rb_io_mode`. (#7894)
Notes
Notes:
Merged-By: ioquatix <[email protected]>
Diffstat (limited to 'include/ruby')
-rw-r--r-- | include/ruby/io.h | 257 |
1 files changed, 141 insertions, 116 deletions
diff --git a/include/ruby/io.h b/include/ruby/io.h index d2fd3ed317..11d5ce5bfe 100644 --- a/include/ruby/io.h +++ b/include/ruby/io.h @@ -137,6 +137,143 @@ struct rb_io_encoding { VALUE ecopts; }; +/** + * @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 +/** + * This flag means that an IO object is wrapping an "external" file descriptor, + * which is owned by something outside the Ruby interpreter (usually a C extension). + * Ruby will not close this file when the IO object is garbage collected. + * If this flag is set, then IO#autoclose? is false, and vice-versa. + * + * This flag was previously called FMODE_PREP internally. + */ +#define FMODE_EXTERNAL 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. + */ +#define FMODE_SETENC_BY_BOM 0x00100000 +/* #define FMODE_UNIX 0x00200000 */ +/* #define FMODE_INET 0x00400000 */ +/* #define FMODE_INET6 0x00800000 */ + +/** @} */ + +enum rb_io_mode { + RUBY_IO_MODE_EXTERNAL = FMODE_EXTERNAL, + + RUBY_IO_MODE_READABLE = FMODE_READABLE, + RUBY_IO_MODE_WRITABLE = FMODE_WRITABLE, + RUBY_IO_MODE_READABLE_WRITABLE = (RUBY_IO_MODE_READABLE|RUBY_IO_MODE_WRITABLE), + + RUBY_IO_MODE_BINARY = FMODE_BINMODE, + RUBY_IO_MODE_TEXT = FMODE_TEXTMODE, + RUBY_IO_MODE_TEXT_SET_ENCODING_FROM_BOM = FMODE_SETENC_BY_BOM, + + RUBY_IO_MODE_SYNCHRONISED = FMODE_SYNC, + + RUBY_IO_MODE_TTY = FMODE_TTY, + + RUBY_IO_MODE_DUPLEX = FMODE_DUPLEX, + + RUBY_IO_MODE_APPEND = FMODE_APPEND, + RUBY_IO_MODE_CREATE = FMODE_CREATE, + RUBY_IO_MODE_EXCLUSIVE = FMODE_EXCL, + RUBY_IO_MODE_TRUNCATE = FMODE_TRUNC, +}; + +typedef enum rb_io_mode rb_io_mode_t; + #ifndef HAVE_RB_IO_T #define HAVE_RB_IO_T 1 /** Ruby's IO, metadata and buffers. */ @@ -155,7 +292,7 @@ struct rb_io { /** mode flags: FMODE_XXXs */ RBIMPL_ATTR_DEPRECATED(("rb_io_mode")) - int mode; + enum rb_io_mode mode; /** child's pid (for pipes) */ RBIMPL_ATTR_DEPRECATED(("with no replacement")) @@ -261,118 +398,6 @@ typedef struct rb_io rb_io_t; typedef struct rb_io_encoding rb_io_enc_t; /** - * @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 -/** - * This flag means that an IO object is wrapping an "external" file descriptor, - * which is owned by something outside the Ruby interpreter (usually a C extension). - * Ruby will not close this file when the IO object is garbage collected. - * If this flag is set, then IO#autoclose? is false, and vice-versa. - * - * This flag was previously called FMODE_PREP internally. - */ -#define FMODE_EXTERNAL 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. - */ -#define FMODE_SETENC_BY_BOM 0x00100000 -/* #define FMODE_UNIX 0x00200000 */ -/* #define FMODE_INET 0x00400000 */ -/* #define FMODE_INET6 0x00800000 */ - -/** @} */ - -/** * Allocate a new IO object, with the given file descriptor. */ VALUE rb_io_open_descriptor(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, struct rb_io_encoding *encoding); @@ -525,7 +550,7 @@ FILE *rb_fdopen(int fd, const char *modestr); * * rb_io_modestr_fmode() is not a pure function because it raises. */ -int rb_io_modestr_fmode(const char *modestr); +enum rb_io_mode rb_io_modestr_fmode(const char *modestr); /** * Identical to rb_io_modestr_fmode(), except it returns a mixture of `O_` @@ -780,7 +805,7 @@ int rb_io_mode(VALUE io); * @post `enc2_p` is the specified external encoding. * @post `fmode_p` is the specified set of `FMODE_` modes. */ -int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p); +int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, enum rb_io_mode *fmode_p); /** * This function can be seen as an extended version of @@ -849,7 +874,7 @@ int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding ** * ) -> void * ``` */ -void rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, int *oflags_p, int *fmode_p, rb_io_enc_t *convconfig_p); +void rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, int *oflags_p, enum rb_io_mode *fmode_p, rb_io_enc_t *convconfig_p); /* :TODO: can this function be __attribute__((warn_unused_result)) or not? */ /** |