diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-08-09 19:45:56 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-08-09 19:45:56 +0300 |
commit | acae72517bc892911bf9b0f261ef41356e7e2c44 (patch) | |
tree | 84b567960ec50c99076f4f5166cc33ee50456c6e | |
parent | c8bdb828d00cd193be4ae03e32beb46e4cf6a317 (diff) | |
download | sciteco-acae72517bc892911bf9b0f261ef41356e7e2c44.tar.gz |
Win32: avoid any automatic LF to CRLF conversions when writing to stdout
* At least the MSVCRT does this by default, i.e. the translation mode of stdout
is not _O_BINARY.
* This broke piping through SciTECO with --stdin --stdout, as this relies on SciTECO's
builtin EOL normalization. Instead, you would get DOS linebreaks on output even if the
source stream contains only UNIX linebreaks.
* It would also break binary filters.
* It seems to be safe to print only LF also for regular stdio (help and error messages),
so I simply disaply the stdout (and stdin and stderr) EOL translation globally.
* Also fixes Troff warnings due to the .in preprocessor writing output with DOS linebreaks.
* Added a test case. All future platforms shouldn't perform any unexpected EOL translations
on output.
-rw-r--r-- | src/main.c | 19 | ||||
-rw-r--r-- | tests/testsuite.at | 4 |
2 files changed, 23 insertions, 0 deletions
@@ -30,6 +30,11 @@ #include <glib/gprintf.h> #include <glib/gstdio.h> +#ifdef G_OS_WIN32 +#include <fcntl.h> +#include <io.h> +#endif + #ifdef HAVE_SYS_CAPSICUM_H #include <sys/capsicum.h> #endif @@ -362,6 +367,20 @@ main(int argc, char **argv) g_autoptr(GError) error = NULL; teco_int_t ret = EXIT_SUCCESS; +#ifdef G_OS_WIN32 + /* + * Windows might by default perform EOL translations, especially + * when writing to stdout, i.e. translate LF to CRLF. + * This would break at the very least --stdout, where you are + * expected to get the linebreaks configured on the current buffer via EL. + * It would also break binary filters on Windows. + * Since printing LF to the console is safe nowadays, we just do that + * globally. + */ + for (gint fd = 0; fd <= 2; fd++) + _setmode(fd, _O_BINARY); +#endif + #ifdef DEBUG_PAUSE /* Windows debugging hack (see above) */ system("pause"); diff --git a/tests/testsuite.at b/tests/testsuite.at index 3a2fc2e..3728723 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -232,6 +232,10 @@ AT_DATA([expout], [[1058 1058 ]]) AT_CHECK([[printf "ТЕСТ" | $SCITECO -qe '<^TUa Qa:; Qa=>']], 0, expout, ignore) +# Writing to stdout should not perform any unexpected EOL translations. +# When using --stdin/--stdout, we can rely on the builtin EOL normalization. +TE_CHECK([[10^T]], 0, stdout, ignore) +TE_CHECK([[16,0ED @EB/stdout/ Z-1"N(0/0)' 0A-10"N(0/0)']], 0, ignore, ignore) AT_CLEANUP AT_SETUP([Convert between line and glyph positions]) |