Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-03-14 23:43:28 +0300
committerCorinna Vinschen <corinna@vinschen.de>2008-03-14 23:43:28 +0300
commitd63c2da552bc89c6748c31af651699b77fc1efe6 (patch)
tree60b0f22bcb42139330c8c68e425e3539c49904fb /winsup/cygwin/smallprint.cc
parent56f19ae0e933794e899fe7833a812c5d96730fcf (diff)
* fcntl.cc (fcntl_worker): Protect with a 'myfault'.
* path.cc (normalize_posix_path): Treat X:/ as Win32 path, too. * smallprint.cc (__wrn): New static function. (__small_vswprintf): New function to generate WCHAR strings. (__small_swprintf): Ditto. * winsup.h (__small_swprintf): Declare. (__small_vswprintf): Declare.
Diffstat (limited to 'winsup/cygwin/smallprint.cc')
-rw-r--r--winsup/cygwin/smallprint.cc193
1 files changed, 193 insertions, 0 deletions
diff --git a/winsup/cygwin/smallprint.cc b/winsup/cygwin/smallprint.cc
index 2a7810c50..eead3716f 100644
--- a/winsup/cygwin/smallprint.cc
+++ b/winsup/cygwin/smallprint.cc
@@ -14,6 +14,8 @@ details. */
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
+#include <wctype.h>
+#include <wchar.h>
#include <limits.h>
#define LLMASK (0xffffffffffffffffULL)
@@ -286,3 +288,194 @@ console_printf (const char *fmt, ...)
FlushFileBuffers (console_handle);
}
#endif
+
+#define wrnarg(dst, base, dosign, len, pad) __wrn ((dst), (base), (dosign), va_arg (ap, long), len, pad, LMASK)
+#define wrnargLL(dst, base, dosign, len, pad) __wrn ((dst), (base), (dosign), va_arg (ap, unsigned long long), len, pad, LLMASK)
+
+static PWCHAR __fastcall
+__wrn (PWCHAR dst, int base, int dosign, long long val, int len, int pad, unsigned long long mask)
+{
+ /* longest number is ULLONG_MAX, 18446744073709551615, 20 digits */
+ unsigned long long uval = 0;
+ WCHAR res[20];
+ static const WCHAR str[] = L"0123456789ABCDEF";
+ int l = 0;
+
+ if (dosign && val < 0)
+ {
+ *dst++ = L'-';
+ uval = -val;
+ }
+ else if (dosign > 0 && val > 0)
+ {
+ *dst++ = L'+';
+ uval = val;
+ }
+ else
+ uval = val;
+
+ uval &= mask;
+
+ do
+ {
+ res[l++] = str[uval % base];
+ uval /= base;
+ }
+ while (uval);
+
+ while (len-- > l)
+ *dst++ = pad;
+
+ while (l > 0)
+ *dst++ = res[--l];
+
+ return dst;
+}
+
+extern "C" int
+__small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap)
+{
+ WCHAR tmp[NT_MAX_PATH];
+ PWCHAR orig = dst;
+ const char *s;
+ PWCHAR w;
+ UNICODE_STRING uw, *us;
+
+ DWORD err = GetLastError ();
+
+ while (*fmt)
+ {
+ unsigned int n = 0x7fff;
+ if (*fmt != L'%')
+ *dst++ = *fmt++;
+ else
+ {
+ int len = 0;
+ WCHAR pad = L' ';
+ int addsign = -1;
+
+ switch (*++fmt)
+ {
+ case L'+':
+ addsign = 1;
+ fmt++;
+ break;
+ case L'%':
+ *dst++ = *fmt++;
+ continue;
+ }
+
+ for (;;)
+ {
+ char c = *fmt++;
+ switch (c)
+ {
+ case L'0':
+ if (len == 0)
+ {
+ pad = L'0';
+ continue;
+ }
+ case L'1' ... L'9':
+ len = len * 10 + (c - L'0');
+ continue;
+ case L'l':
+ continue;
+ case L'c':
+ case L'C':
+ {
+ unsigned int c = va_arg (ap, unsigned int);
+ if (c > L' ' && c <= 127)
+ *dst++ = c;
+ else
+ {
+ *dst++ = L'0';
+ *dst++ = L'x';
+ dst = __wrn (dst, 16, 0, c, len, pad, LMASK);
+ }
+ }
+ break;
+ case L'E':
+ wcscpy (dst, L"Win32 error ");
+ dst = __wrn (dst + sizeof ("Win32 error"), 10, 0, err, len, pad, LMASK);
+ break;
+ case L'd':
+ dst = wrnarg (dst, 10, addsign, len, pad);
+ break;
+ case L'D':
+ dst = wrnargLL (dst, 10, addsign, len, pad);
+ break;
+ case L'u':
+ dst = wrnarg (dst, 10, 0, len, pad);
+ break;
+ case L'U':
+ dst = wrnargLL (dst, 10, 0, len, pad);
+ break;
+ case L'o':
+ dst = wrnarg (dst, 8, 0, len, pad);
+ break;
+ case L'p':
+ *dst++ = L'0';
+ *dst++ = L'x';
+ /* fall through */
+ case L'x':
+ dst = wrnarg (dst, 16, 0, len, pad);
+ break;
+ case L'X':
+ dst = wrnargLL (dst, 16, 0, len, pad);
+ break;
+ case L'P':
+ if (!GetModuleFileNameW (NULL, tmp, NT_MAX_PATH))
+ RtlInitUnicodeString (us = &uw, L"cygwin program");
+ else
+ RtlInitUnicodeString (us = &uw, tmp);
+ goto fillin;
+ case L'.':
+ n = wcstoul (fmt, (wchar_t **) &fmt, 10);
+ if (*fmt++ != L's')
+ goto endfor;
+ case L's':
+ s = va_arg (ap, char *);
+ if (s == NULL)
+ s = "(null)";
+ sys_mbstowcs (tmp, NT_MAX_PATH, s, n);
+ RtlInitUnicodeString (us = &uw, tmp);
+ goto fillin;
+ break;
+ case L'W':
+ w = va_arg (ap, PWCHAR);
+ RtlInitUnicodeString (us = &uw, w);
+ goto fillin;
+ case L'S':
+ us = va_arg (ap, PUNICODE_STRING);
+ fillin:
+ if (us->Length / sizeof (WCHAR) < n)
+ n = us->Length / sizeof (WCHAR);
+
+ for (unsigned int i = 0; i < n; i++)
+ *dst++ = *w++;
+ break;
+ default:
+ *dst++ = L'?';
+ *dst++ = fmt[-1];
+ }
+ endfor:
+ break;
+ }
+ }
+ }
+ *dst = L'\0';
+ SetLastError (err);
+ return dst - orig;
+}
+
+extern "C" int
+__small_swprintf (PWCHAR dst, const WCHAR *fmt, ...)
+{
+ int r;
+ va_list ap;
+ va_start (ap, fmt);
+ r = __small_vswprintf (dst, fmt, ap);
+ va_end (ap);
+ return r;
+}