xref: /reactos/sdk/lib/ucrt/stdio/fputc.cpp (revision e98e9000)
1 //
2 // fputc.cpp
3 //
4 //      Copyright (c) Microsoft Corporation.  All rights reserved.
5 //
6 // Defines the fputc() family of functions, which write a character to a stream.
7 //
8 #include <corecrt_internal_stdio.h>
9 #include <corecrt_internal_ptd_propagation.h>
10 
11 
_fputc_nolock_internal(int const c,FILE * const public_stream,__crt_cached_ptd_host & ptd)12 extern "C" int __cdecl _fputc_nolock_internal(int const c, FILE* const public_stream, __crt_cached_ptd_host& ptd)
13 {
14     __crt_stdio_stream const stream(public_stream);
15 
16     --stream->_cnt;
17 
18     // If there is no room for the character in the buffer, flush the buffer and
19     // write the character:
20     if (stream->_cnt < 0)
21     {
22         return __acrt_stdio_flush_and_write_narrow_nolock(c, stream.public_stream(), ptd);
23     }
24 
25     // Otherwise, there is sufficient room, so we can write directly to the buffer:
26     char const char_value = static_cast<char>(c);
27     *stream->_ptr++ = char_value;
28     return char_value & 0xff;
29 }
30 
_fputc_nolock(int const c,FILE * const public_stream)31 extern "C" int __cdecl _fputc_nolock(int const c, FILE* const public_stream)
32 {
33     __crt_cached_ptd_host ptd;
34     return _fputc_nolock_internal(c, public_stream, ptd);
35 }
36 
_putc_nolock(int const c,FILE * const stream)37 extern "C" int __cdecl _putc_nolock(int const c, FILE* const stream)
38 {
39     return _fputc_nolock(c, stream);
40 }
41 
42 
43 
44 // Writes a character to a stream.  Returns the character on success; returns
45 // EOF on failure.
_fputc_internal(int const c,FILE * const stream,__crt_cached_ptd_host & ptd)46 static int __cdecl _fputc_internal(int const c, FILE* const stream, __crt_cached_ptd_host& ptd)
47 {
48     _UCRT_VALIDATE_RETURN(ptd, stream != nullptr, EINVAL, EOF);
49 
50     int return_value = 0;
51 
52     _lock_file(stream);
53     __try
54     {
55         _UCRT_VALIDATE_STREAM_ANSI_RETURN(ptd, stream, EINVAL, EOF);
56 
57         return_value = _fputc_nolock_internal(c, stream, ptd);
58     }
59     __finally
60     {
61         _unlock_file(stream);
62     }
63     __endtry
64 
65     return return_value;
66 }
67 
68 // Writes a character to a stream.  Returns the character on success; returns
69 // EOF on failure.
fputc(int const c,FILE * const stream)70 extern "C" int __cdecl fputc(int const c, FILE* const stream)
71 {
72     __crt_cached_ptd_host ptd;
73     return _fputc_internal(c, stream, ptd);
74 }
75 
76 
77 
78 // Writes a character to a stream.  See fputc() for details.
putc(int const c,FILE * const stream)79 extern "C" int __cdecl putc(int const c, FILE* const stream)
80 {
81     return fputc(c, stream);
82 }
83 
84 
85 
86 // Writes a character to stdout.  See fputc() for details.
_fputchar(int const c)87 extern "C" int __cdecl _fputchar(int const c)
88 {
89     return fputc(c, stdout);
90 }
91 
92 
93 
94 // Writes a character to stdout.  See fputc() for details.
putchar(int const c)95 extern "C" int __cdecl putchar(int const c)
96 {
97     return _fputchar(c);
98 }
99