On 1/5/21 1:51 PM, Tom Honermann via SG16 wrote:
On 12/5/20 5:16 PM, Tom Honermann via SG16 wrote:
On 12/5/20 4:31 PM, Jens Maurer wrote:
On 05/12/2020 22.16, Tom Honermann wrote:
On 11/28/20 11:33 AM, Victor Zverovich wrote:
And then there is the facility of converting the C++ literal encoding to the console encoding, if necessary.  Again, this should be a separate facility, preferably offering a generic transcoding facility that can be specialized for the console-only use case.
While I agree that such a transcoding facility would be useful I think it is out of scope of the current paper. The latter requires only minimal transcoding facilities for the Unicode case and only on some platforms where dedicated system APIs exist.
I agree that distinct interfaces should be provided for each of these concerns, but I also think each can be pursued separately and need not hold up the proposed feature.  We can always re-specify the proposed behavior in terms of new interfaces via as-if in the future.
Let me disagree here.  It took years for to_chars (the underlying
elementary operation) to arrive after std::to_string was standardized.

I have no objection to providing high-level facilities in C++,
but I want the option to ignore those high-level facilities
if need be.  Apparently, there is an appetite to differentiate
"writing to the console" vs. "writing to a file", and that
appears to be a useful low-level query to have.

I agree that it is useful to have.  But it is also functionality that has been readily available for most systems for a long time now and there hasn't been a push to standardize it in C or C++ thus far.  I'm not opposed to adding it at all, I just don't want the lack of it to hold up Victor's proposal.  At any rate, here is a fairly portable (untested) implementation (with lax error handling) for C style streams (the Windows implementation would be better implemented using whatever Win32 features _isatty() uses).

#if defined(_XOPEN_SOURCE)
#include <stdio.h>
#include <unistd.h>
#elif defined(_MSC_VER)
#include <io.h>
#endif

bool is_attached_to_terminal(FILE* fp) {
#if defined(_XOPEN_SOURCE)
  return isatty(fileno(fp));
#elif defined(_MSC_VER)
  return _isatty(_fileno(fp));
#endif
}

While playing around with the console encoding, I discovered that the MSVC provided _isatty() returns true for any character device, not just a console.  From the documentation:

> The _isatty function determines whether fd is associated with a character device (a terminal, console, printer, or serial port).

Here is code that does validate whether the standard file streams are directed to a Windows console:

#include <windows.h>
#include <io.h>
#include <stdio.h>
#include <iostream>
#include <string>

bool is_console(FILE *fp) {
    if (! fp) {
        return false;
    }
    int fd = _fileno(fp);
    if (fd < 0) {
        return false;
    }
    HANDLE h = (HANDLE)_get_osfhandle(fd);
    if (h == INVALID_HANDLE_VALUE) {
        return false;
    }
    DWORD mode;
    BOOL result;
    result = GetConsoleMode(h, &mode);
    if (! result) {
        return false;
    }
    return true;
}

struct stream_desc {
    std::string name;
    FILE *fp;
};

int main() {
    stream_desc streams[] = {
        { "stdin", stdin },
    { "stdout", stdout },
    { "stderr", stderr }
    };
    for (auto sd : streams) {
        if (is_console(sd.fp)) {
            std::cout << sd.name << ": console\n";
        } else {
            std::cout << sd.name << ": not a console\n";
        }
    }
}

When saved as is-console.cpp and compiled with cl /Feis-console.exe /EHsc is-console.cpp:

>is-console
stdin: console
stdout: console
stderr: console

>echo. | is-console
stdin: not a console
stdout: console
stderr: console

>is-console | findstr .
stdin: console
stdout: not a console
stderr: console

>is-console 2>nul
stdin: console
stdout: console
stderr: not a console

>is-console 2>&1
stdin: console
stdout: console
stderr: console

>is-console >&2
stdin: console
stdout: console
stderr: console

>echo. | is-console 2>&1 | findstr .
stdin: not a console
stdout: not a console
stderr: not a console

I forgot to mention; these are the results running the utility in a typical cmd.exe window.  The same results are produced running in a Windows Terminal environment.

However, when run in a Cygwin MinTTY environment, the utility always reports each as not a console.  This is a good thing, MinTTY does not provide a console in the Windows sense; it provides a terminal.

Tom.