xref: /reactos/sdk/lib/ucrt/stdio/fputc.cpp (revision e98e9000)
104e0dc4aSTimo Kreuzer //
204e0dc4aSTimo Kreuzer // fputc.cpp
304e0dc4aSTimo Kreuzer //
404e0dc4aSTimo Kreuzer //      Copyright (c) Microsoft Corporation.  All rights reserved.
504e0dc4aSTimo Kreuzer //
604e0dc4aSTimo Kreuzer // Defines the fputc() family of functions, which write a character to a stream.
704e0dc4aSTimo Kreuzer //
804e0dc4aSTimo Kreuzer #include <corecrt_internal_stdio.h>
904e0dc4aSTimo Kreuzer #include <corecrt_internal_ptd_propagation.h>
1004e0dc4aSTimo Kreuzer 
1104e0dc4aSTimo Kreuzer 
_fputc_nolock_internal(int const c,FILE * const public_stream,__crt_cached_ptd_host & ptd)1204e0dc4aSTimo Kreuzer extern "C" int __cdecl _fputc_nolock_internal(int const c, FILE* const public_stream, __crt_cached_ptd_host& ptd)
1304e0dc4aSTimo Kreuzer {
1404e0dc4aSTimo Kreuzer     __crt_stdio_stream const stream(public_stream);
1504e0dc4aSTimo Kreuzer 
1604e0dc4aSTimo Kreuzer     --stream->_cnt;
1704e0dc4aSTimo Kreuzer 
1804e0dc4aSTimo Kreuzer     // If there is no room for the character in the buffer, flush the buffer and
1904e0dc4aSTimo Kreuzer     // write the character:
2004e0dc4aSTimo Kreuzer     if (stream->_cnt < 0)
2104e0dc4aSTimo Kreuzer     {
2204e0dc4aSTimo Kreuzer         return __acrt_stdio_flush_and_write_narrow_nolock(c, stream.public_stream(), ptd);
2304e0dc4aSTimo Kreuzer     }
2404e0dc4aSTimo Kreuzer 
2504e0dc4aSTimo Kreuzer     // Otherwise, there is sufficient room, so we can write directly to the buffer:
2604e0dc4aSTimo Kreuzer     char const char_value = static_cast<char>(c);
2704e0dc4aSTimo Kreuzer     *stream->_ptr++ = char_value;
2804e0dc4aSTimo Kreuzer     return char_value & 0xff;
2904e0dc4aSTimo Kreuzer }
3004e0dc4aSTimo Kreuzer 
_fputc_nolock(int const c,FILE * const public_stream)3104e0dc4aSTimo Kreuzer extern "C" int __cdecl _fputc_nolock(int const c, FILE* const public_stream)
3204e0dc4aSTimo Kreuzer {
3304e0dc4aSTimo Kreuzer     __crt_cached_ptd_host ptd;
3404e0dc4aSTimo Kreuzer     return _fputc_nolock_internal(c, public_stream, ptd);
3504e0dc4aSTimo Kreuzer }
3604e0dc4aSTimo Kreuzer 
_putc_nolock(int const c,FILE * const stream)3704e0dc4aSTimo Kreuzer extern "C" int __cdecl _putc_nolock(int const c, FILE* const stream)
3804e0dc4aSTimo Kreuzer {
3904e0dc4aSTimo Kreuzer     return _fputc_nolock(c, stream);
4004e0dc4aSTimo Kreuzer }
4104e0dc4aSTimo Kreuzer 
4204e0dc4aSTimo Kreuzer 
4304e0dc4aSTimo Kreuzer 
4404e0dc4aSTimo Kreuzer // Writes a character to a stream.  Returns the character on success; returns
4504e0dc4aSTimo Kreuzer // EOF on failure.
_fputc_internal(int const c,FILE * const stream,__crt_cached_ptd_host & ptd)4604e0dc4aSTimo Kreuzer static int __cdecl _fputc_internal(int const c, FILE* const stream, __crt_cached_ptd_host& ptd)
4704e0dc4aSTimo Kreuzer {
4804e0dc4aSTimo Kreuzer     _UCRT_VALIDATE_RETURN(ptd, stream != nullptr, EINVAL, EOF);
4904e0dc4aSTimo Kreuzer 
5004e0dc4aSTimo Kreuzer     int return_value = 0;
5104e0dc4aSTimo Kreuzer 
5204e0dc4aSTimo Kreuzer     _lock_file(stream);
5304e0dc4aSTimo Kreuzer     __try
5404e0dc4aSTimo Kreuzer     {
5504e0dc4aSTimo Kreuzer         _UCRT_VALIDATE_STREAM_ANSI_RETURN(ptd, stream, EINVAL, EOF);
5604e0dc4aSTimo Kreuzer 
5704e0dc4aSTimo Kreuzer         return_value = _fputc_nolock_internal(c, stream, ptd);
5804e0dc4aSTimo Kreuzer     }
5904e0dc4aSTimo Kreuzer     __finally
6004e0dc4aSTimo Kreuzer     {
6104e0dc4aSTimo Kreuzer         _unlock_file(stream);
6204e0dc4aSTimo Kreuzer     }
63*e98e9000STimo Kreuzer     __endtry
6404e0dc4aSTimo Kreuzer 
6504e0dc4aSTimo Kreuzer     return return_value;
6604e0dc4aSTimo Kreuzer }
6704e0dc4aSTimo Kreuzer 
6804e0dc4aSTimo Kreuzer // Writes a character to a stream.  Returns the character on success; returns
6904e0dc4aSTimo Kreuzer // EOF on failure.
fputc(int const c,FILE * const stream)7004e0dc4aSTimo Kreuzer extern "C" int __cdecl fputc(int const c, FILE* const stream)
7104e0dc4aSTimo Kreuzer {
7204e0dc4aSTimo Kreuzer     __crt_cached_ptd_host ptd;
7304e0dc4aSTimo Kreuzer     return _fputc_internal(c, stream, ptd);
7404e0dc4aSTimo Kreuzer }
7504e0dc4aSTimo Kreuzer 
7604e0dc4aSTimo Kreuzer 
7704e0dc4aSTimo Kreuzer 
7804e0dc4aSTimo Kreuzer // Writes a character to a stream.  See fputc() for details.
putc(int const c,FILE * const stream)7904e0dc4aSTimo Kreuzer extern "C" int __cdecl putc(int const c, FILE* const stream)
8004e0dc4aSTimo Kreuzer {
8104e0dc4aSTimo Kreuzer     return fputc(c, stream);
8204e0dc4aSTimo Kreuzer }
8304e0dc4aSTimo Kreuzer 
8404e0dc4aSTimo Kreuzer 
8504e0dc4aSTimo Kreuzer 
8604e0dc4aSTimo Kreuzer // Writes a character to stdout.  See fputc() for details.
_fputchar(int const c)8704e0dc4aSTimo Kreuzer extern "C" int __cdecl _fputchar(int const c)
8804e0dc4aSTimo Kreuzer {
8904e0dc4aSTimo Kreuzer     return fputc(c, stdout);
9004e0dc4aSTimo Kreuzer }
9104e0dc4aSTimo Kreuzer 
9204e0dc4aSTimo Kreuzer 
9304e0dc4aSTimo Kreuzer 
9404e0dc4aSTimo Kreuzer // Writes a character to stdout.  See fputc() for details.
putchar(int const c)9504e0dc4aSTimo Kreuzer extern "C" int __cdecl putchar(int const c)
9604e0dc4aSTimo Kreuzer {
9704e0dc4aSTimo Kreuzer     return _fputchar(c);
9804e0dc4aSTimo Kreuzer }
99