VirtualBox

source: kBuild/trunk/src/lib/msc_buffered_printf.c@ 2999

Last change on this file since 2999 was 2967, checked in by bird, 8 years ago

kFsCache: Implemented object names changing to a longer ones.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1/* $Id: msc_buffered_printf.c 2967 2016-09-26 18:14:13Z bird $ */
2/** @file
3 * printf, vprintf, fprintf, puts, fputs console optimizations for Windows/MSC.
4 */
5
6/*
7 * Copyright (c) 2016 knut st. osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 *
27 * Alternatively, the content of this file may be used under the terms of the
28 * GPL version 2 or later, or LGPL version 2.1 or later.
29 */
30
31
32/*********************************************************************************************************************************
33* Header Files *
34*********************************************************************************************************************************/
35#include <Windows.h>
36#include <stdio.h>
37#include <stdarg.h>
38#include <io.h>
39#include <conio.h>
40#include <malloc.h>
41
42#undef printf
43#undef vprintf
44#undef fprintf
45#undef puts
46#undef fputs
47#pragma warning(disable: 4273) /* inconsistent dll linkage*/
48
49#ifndef KWORKER
50# define DLL_IMPORT __declspec(dllexport)
51#else
52# define DLL_IMPORT
53#endif
54
55extern size_t maybe_con_fwrite(void const *pvBuf, size_t cbUnit, size_t cUnits, FILE *pFile);
56
57
58/**
59 * Replaces printf for MSC to speed up console output.
60 *
61 * @returns chars written on success, -1 and errno on failure.
62 * @param pszFormat The format string.
63 * @param ... Format arguments.
64 */
65DLL_IMPORT
66int __cdecl printf(const char *pszFormat, ...)
67{
68 int cchRet;
69 va_list va;
70 va_start(va, pszFormat);
71 cchRet = vprintf(pszFormat, va);
72 va_end(va);
73 return cchRet;
74}
75
76
77/**
78 * Replaces vprintf for MSC to speed up console output.
79 *
80 * @returns chars written on success, -1 and errno on failure.
81 * @param pszFormat The format string.
82 * @param va Format arguments.
83 */
84DLL_IMPORT
85int __cdecl vprintf(const char *pszFormat, va_list va)
86{
87 /*
88 * If it's a TTY, try format into a stack buffer and output using our
89 * console optimized fwrite wrapper.
90 */
91 if (*pszFormat != '\0')
92 {
93 int fd = fileno(stdout);
94 if (fd >= 0)
95 {
96 if (isatty(fd))
97 {
98 char *pszTmp = (char *)alloca(16384);
99 va_list va2 = va;
100 int cchRet = vsnprintf(pszTmp, 16384, pszFormat, va2);
101 if (cchRet < 16384 - 1)
102 return (int)maybe_con_fwrite(pszTmp, cchRet, 1, stdout);
103 }
104 }
105 }
106
107 /*
108 * Fallback.
109 */
110 return vfprintf(stdout, pszFormat, va);
111}
112
113
114/**
115 * Replaces fprintf for MSC to speed up console output.
116 *
117 * @returns chars written on success, -1 and errno on failure.
118 * @param pFile The output file/stream.
119 * @param pszFormat The format string.
120 * @param va Format arguments.
121 */
122DLL_IMPORT
123int __cdecl fprintf(FILE *pFile, const char *pszFormat, ...)
124{
125 va_list va;
126 int cchRet;
127
128 /*
129 * If it's a TTY, try format into a stack buffer and output using our
130 * console optimized fwrite wrapper.
131 */
132 if (*pszFormat != '\0')
133 {
134 int fd = fileno(pFile);
135 if (fd >= 0)
136 {
137 if (isatty(fd))
138 {
139 char *pszTmp = (char *)alloca(16384);
140 if (pszTmp)
141 {
142 va_start(va, pszFormat);
143 cchRet = vsnprintf(pszTmp, 16384, pszFormat, va);
144 va_end(va);
145 if (cchRet < 16384 - 1)
146 return (int)maybe_con_fwrite(pszTmp, cchRet, 1, pFile);
147 }
148 }
149 }
150 }
151
152 /*
153 * Fallback.
154 */
155 va_start(va, pszFormat);
156 cchRet = vfprintf(pFile, pszFormat, va);
157 va_end(va);
158 return cchRet;
159}
160
161
162/**
163 * Replaces puts for MSC to speed up console output.
164 *
165 * @returns Units written; 0 & errno on failure.
166 * @param pszString The string to write. (newline is appended)
167 */
168DLL_IMPORT
169int __cdecl puts(const char *pszString)
170{
171 size_t cchString = strlen(pszString);
172 size_t cch;
173
174 /*
175 * If it's a TTY, we convert it to a wide char string with a newline
176 * appended right here. Going thru maybe_con_fwrite is just extra
177 * buffering due to the added newline.
178 */
179 if (*pszString != '\0')
180 {
181 int fd = fileno(stdout);
182 if (fd >= 0)
183 {
184 if (isatty(fd))
185 {
186 HANDLE hCon = (HANDLE)_get_osfhandle(fd);
187 if ( hCon != INVALID_HANDLE_VALUE
188 && hCon != NULL)
189 {
190 /* We need to append a newline, so we can just as well do the conversion here. */
191 size_t cwcTmp = cchString * 2 + 16 + 2;
192 wchar_t *pawcTmp = (wchar_t *)malloc(cwcTmp * sizeof(wchar_t));
193 if (pawcTmp)
194 {
195 int cwcToWrite;
196 static UINT s_uConsoleCp = 0;
197 if (s_uConsoleCp == 0)
198 s_uConsoleCp = GetConsoleCP();
199
200 cwcToWrite = MultiByteToWideChar(s_uConsoleCp, 0 /*dwFlags*/, pszString, (int)cchString, pawcTmp,
201 (int)(cwcTmp - 2));
202 if (cwcToWrite > 0)
203 {
204 int rc;
205
206 pawcTmp[cwcToWrite++] = '\n';
207 pawcTmp[cwcToWrite] = '\0';
208
209 /* Let the CRT do the rest. At least the Visual C++ 2010 CRT
210 sources indicates _cputws will do the right thing we want. */
211 fflush(stdout);
212 rc = _cputws(pawcTmp);
213 free(pawcTmp);
214 return rc;
215 }
216 free(pawcTmp);
217 }
218 }
219 }
220 }
221 }
222
223 /*
224 * Fallback.
225 */
226 cch = fwrite(pszString, cchString, 1, stdout);
227 if (cch == cchString)
228 {
229 if (putc('\n', stdout) != EOF)
230 return 0;
231 }
232 return -1;
233}
234
235
236/**
237 * Replaces puts for MSC to speed up console output.
238 *
239 * @returns Units written; 0 & errno on failure.
240 * @param pszString The string to write (no newline added).
241 * @param pFile The output file.
242 */
243DLL_IMPORT
244int __cdecl fputs(const char *pszString, FILE *pFile)
245{
246 size_t cchString = strlen(pszString);
247 size_t cch = maybe_con_fwrite(pszString, cchString, 1, pFile);
248 if (cch == cchString)
249 return 0;
250 return -1;
251}
252
253
254
255void * const __imp_printf = (void *)(uintptr_t)printf;
256void * const __imp_vprintf = (void *)(uintptr_t)vprintf;
257void * const __imp_fprintf = (void *)(uintptr_t)fprintf;
258void * const __imp_puts = (void *)(uintptr_t)puts;
259void * const __imp_fputs = (void *)(uintptr_t)fputs;
260
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette