1 /* smallprint.cc: small print routines for WIN32
3 Copyright 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
18 #define LLMASK (0xffffffffffffffffULL)
19 #define LMASK (0xffffffff)
21 #define rnarg(dst, base, dosign, len, pad) __rn ((dst), (base), (dosign), va_arg (ap, long), len, pad, LMASK)
22 #define rnargLL(dst, base, dosign, len, pad) __rn ((dst), (base), (dosign), va_arg (ap, unsigned long long), len, pad, LLMASK)
24 static char __fastcall *
25 __rn (char *dst, int base, int dosign, long long val, int len, int pad, unsigned long long mask)
27 /* longest number is ULLONG_MAX, 18446744073709551615, 20 digits */
28 unsigned long long uval = 0;
30 static const char str[] = "0123456789ABCDEF";
33 if (dosign && val < 0)
38 else if (dosign > 0 && val > 0)
50 res[l++] = str[uval % base];
65 __small_vsprintf (char *dst, const char *fmt, va_list ap)
67 char tmp[NT_MAX_PATH];
71 UNICODE_STRING uw, *us;
73 DWORD err = GetLastError ();
108 case '1': case '2': case '3': case '4':
109 case '5': case '6': case '7': case '8': case '9':
110 len = len * 10 + (c - '0');
116 int c = va_arg (ap, int);
117 if (c > ' ' && c <= 127)
123 dst = __rn (dst, 16, 0, c, len, pad, LMASK);
129 WCHAR wc = (WCHAR) va_arg (ap, int);
131 sys_wcstombs (buf, 4, &wc, 1);
132 for (c = buf; *c; ++c)
139 dst = __rn (dst, 16, 0, *c, len, pad, LMASK);
143 strcpy (dst, "Win32 error ");
144 dst = __rn (dst + sizeof ("Win32 error"), 10, 0, err, len, pad, LMASK);
147 dst = rnarg (dst, 10, addsign, len, pad);
150 dst = rnargLL (dst, 10, addsign, len, pad);
153 dst = rnarg (dst, 10, 0, len, pad);
156 dst = rnargLL (dst, 10, 0, len, pad);
159 dst = rnarg (dst, 8, 0, len, pad);
166 dst = rnarg (dst, 16, 0, len, pad);
169 dst = rnargLL (dst, 16, 0, len, pad);
172 if (!GetModuleFileName (NULL, tmp, NT_MAX_PATH))
173 s = "cygwin program";
178 n = strtol (fmt, (char **) &fmt, 10);
182 s = va_arg (ap, char *);
186 for (i = 0; *s && i < n; i++)
190 w = va_arg (ap, PWCHAR);
191 RtlInitUnicodeString (&uw, w);
195 us = va_arg (ap, PUNICODE_STRING);
200 if (!sys_wcstombs_alloc (&tmpbuf, HEAP_NOTHEAP, us->Buffer,
201 us->Length / sizeof (WCHAR)))
203 s = "invalid UNICODE_STRING";
207 for (i = 0; *tmp && i < n; i++)
227 __small_sprintf (char *dst, const char *fmt, ...)
232 r = __small_vsprintf (dst, fmt, ap);
238 small_printf (const char *fmt, ...)
245 #if 0 /* Turn on to force console errors */
246 extern SECURITY_ATTRIBUTES sec_none;
247 HANDLE h = CreateFileA ("CONOUT$", GENERIC_READ|GENERIC_WRITE,
248 FILE_SHARE_WRITE | FILE_SHARE_WRITE, &sec_none,
249 OPEN_EXISTING, 0, 0);
251 SetStdHandle (STD_ERROR_HANDLE, h);
255 count = __small_vsprintf (buf, fmt, ap);
258 WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, count, &done, NULL);
259 FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
263 static HANDLE NO_COPY console_handle = NULL;
265 console_printf (const char *fmt, ...)
273 console_handle = CreateFileA ("CON", GENERIC_WRITE,
274 FILE_SHARE_READ | FILE_SHARE_WRITE,
275 NULL, OPEN_EXISTING, 0, 0);
277 if (console_handle == INVALID_HANDLE_VALUE)
278 console_handle = GetStdHandle (STD_ERROR_HANDLE);
281 count = __small_vsprintf (buf, fmt, ap);
284 WriteFile (console_handle, buf, count, &done, NULL);
285 FlushFileBuffers (console_handle);
289 #define wrnarg(dst, base, dosign, len, pad) __wrn ((dst), (base), (dosign), va_arg (ap, long), len, pad, LMASK)
290 #define wrnargLL(dst, base, dosign, len, pad) __wrn ((dst), (base), (dosign), va_arg (ap, unsigned long long), len, pad, LLMASK)
292 static PWCHAR __fastcall
293 __wrn (PWCHAR dst, int base, int dosign, long long val, int len, int pad, unsigned long long mask)
295 /* longest number is ULLONG_MAX, 18446744073709551615, 20 digits */
296 unsigned long long uval = 0;
298 static const WCHAR str[] = L"0123456789ABCDEF";
301 if (dosign && val < 0)
306 else if (dosign > 0 && val > 0)
318 res[l++] = str[uval % base];
333 __small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap)
335 WCHAR tmp[NT_MAX_PATH];
339 UNICODE_STRING uw, *us;
341 DWORD err = GetLastError ();
345 unsigned int n = 0x7fff;
377 len = len * 10 + (c - L'0');
384 unsigned int c = va_arg (ap, unsigned int);
385 if (c > L' ' && c <= 127)
391 dst = __wrn (dst, 16, 0, c, len, pad, LMASK);
396 wcscpy (dst, L"Win32 error ");
397 dst = __wrn (dst + sizeof ("Win32 error"), 10, 0, err, len, pad, LMASK);
400 dst = wrnarg (dst, 10, addsign, len, pad);
403 dst = wrnargLL (dst, 10, addsign, len, pad);
406 dst = wrnarg (dst, 10, 0, len, pad);
409 dst = wrnargLL (dst, 10, 0, len, pad);
412 dst = wrnarg (dst, 8, 0, len, pad);
419 dst = wrnarg (dst, 16, 0, len, pad);
422 dst = wrnargLL (dst, 16, 0, len, pad);
425 if (!GetModuleFileNameW (NULL, tmp, NT_MAX_PATH))
426 RtlInitUnicodeString (us = &uw, L"cygwin program");
428 RtlInitUnicodeString (us = &uw, tmp);
431 n = wcstoul (fmt, (wchar_t **) &fmt, 10);
435 s = va_arg (ap, char *);
438 sys_mbstowcs (tmp, NT_MAX_PATH, s, n);
439 RtlInitUnicodeString (us = &uw, tmp);
443 w = va_arg (ap, PWCHAR);
444 RtlInitUnicodeString (us = &uw, w);
447 us = va_arg (ap, PUNICODE_STRING);
449 if (us->Length / sizeof (WCHAR) < n)
450 n = us->Length / sizeof (WCHAR);
452 for (unsigned int i = 0; i < n; i++)
470 __small_swprintf (PWCHAR dst, const WCHAR *fmt, ...)
475 r = __small_vswprintf (dst, fmt, ap);