OSDN Git Service

Remove unneeded header files from source files throughout.
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / smallprint.cc
1 /* smallprint.cc: small print routines for WIN32
2
3    Copyright 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008
4    Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #include "winsup.h"
13 #include "ntdll.h"
14 #include <stdlib.h>
15 #include <ctype.h>
16 #include <wchar.h>
17
18 #define LLMASK  (0xffffffffffffffffULL)
19 #define LMASK   (0xffffffff)
20
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)
23
24 static char __fastcall *
25 __rn (char *dst, int base, int dosign, long long val, int len, int pad, unsigned long long mask)
26 {
27   /* longest number is ULLONG_MAX, 18446744073709551615, 20 digits */
28   unsigned long long uval = 0;
29   char res[20];
30   static const char str[] = "0123456789ABCDEF";
31   int l = 0;
32
33   if (dosign && val < 0)
34     {
35       *dst++ = '-';
36       uval = -val;
37     }
38   else if (dosign > 0 && val > 0)
39     {
40       *dst++ = '+';
41       uval = val;
42     }
43   else
44     uval = val;
45
46   uval &= mask;
47
48   do
49     {
50       res[l++] = str[uval % base];
51       uval /= base;
52     }
53   while (uval);
54
55   while (len-- > l)
56     *dst++ = pad;
57
58   while (l > 0)
59     *dst++ = res[--l];
60
61   return dst;
62 }
63
64 extern "C" int
65 __small_vsprintf (char *dst, const char *fmt, va_list ap)
66 {
67   char tmp[NT_MAX_PATH];
68   char *orig = dst;
69   const char *s;
70   PWCHAR w;
71   UNICODE_STRING uw, *us;
72
73   DWORD err = GetLastError ();
74
75   while (*fmt)
76     {
77       int i, n = 0x7fff;
78       if (*fmt != '%')
79         *dst++ = *fmt++;
80       else
81         {
82           int len = 0;
83           char pad = ' ';
84           int addsign = -1;
85
86           switch (*++fmt)
87           {
88             case '+':
89               addsign = 1;
90               fmt++;
91               break;
92             case '%':
93               *dst++ = *fmt++;
94               continue;
95           }
96
97           for (;;)
98             {
99               char c = *fmt++;
100               switch (c)
101                 {
102                 case '0':
103                   if (len == 0)
104                     {
105                       pad = '0';
106                       continue;
107                     }
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');
111                   continue;
112                 case 'l':
113                   continue;
114                 case 'c':
115                   {
116                     int c = va_arg (ap, int);
117                     if (c > ' ' && c <= 127)
118                       *dst++ = c;
119                     else
120                       {
121                         *dst++ = '0';
122                         *dst++ = 'x';
123                         dst = __rn (dst, 16, 0, c, len, pad, LMASK);
124                       }
125                   }
126                   break;
127                 case 'C':
128                   {
129                     WCHAR wc = (WCHAR) va_arg (ap, int);
130                     char buf[4], *c;
131                     sys_wcstombs (buf, 4, &wc, 1);
132                     for (c = buf; *c; ++c)
133                       if (isprint (*c))
134                         *dst++ = *c;
135                       else
136                         {
137                           *dst++ = '0';
138                           *dst++ = 'x';
139                           dst = __rn (dst, 16, 0, *c, len, pad, LMASK);
140                         }
141                   }
142                 case 'E':
143                   strcpy (dst, "Win32 error ");
144                   dst = __rn (dst + sizeof ("Win32 error"), 10, 0, err, len, pad, LMASK);
145                   break;
146                 case 'd':
147                   dst = rnarg (dst, 10, addsign, len, pad);
148                   break;
149                 case 'D':
150                   dst = rnargLL (dst, 10, addsign, len, pad);
151                   break;
152                 case 'u':
153                   dst = rnarg (dst, 10, 0, len, pad);
154                   break;
155                 case 'U':
156                   dst = rnargLL (dst, 10, 0, len, pad);
157                   break;
158                 case 'o':
159                   dst = rnarg (dst, 8, 0, len, pad);
160                   break;
161                 case 'p':
162                   *dst++ = '0';
163                   *dst++ = 'x';
164                   /* fall through */
165                 case 'x':
166                   dst = rnarg (dst, 16, 0, len, pad);
167                   break;
168                 case 'X':
169                   dst = rnargLL (dst, 16, 0, len, pad);
170                   break;
171                 case 'P':
172                   if (!GetModuleFileName (NULL, tmp, NT_MAX_PATH))
173                     s = "cygwin program";
174                   else
175                     s = tmp;
176                   goto fillin;
177                 case '.':
178                   n = strtol (fmt, (char **) &fmt, 10);
179                   if (*fmt++ != 's')
180                     goto endfor;
181                 case 's':
182                   s = va_arg (ap, char *);
183                   if (s == NULL)
184                     s = "(null)";
185                 fillin:
186                   for (i = 0; *s && i < n; i++)
187                     *dst++ = *s++;
188                   break;
189                 case 'W':
190                   w = va_arg (ap, PWCHAR);
191                   RtlInitUnicodeString (&uw, w);
192                   us = &uw;
193                   goto wfillin;
194                 case 'S':
195                   us = va_arg (ap, PUNICODE_STRING);
196                 wfillin:
197                   {
198                     char *tmpbuf;
199
200                     if (!sys_wcstombs_alloc (&tmpbuf, HEAP_NOTHEAP, us->Buffer,
201                                              us->Length / sizeof (WCHAR)))
202                       {
203                         s = "invalid UNICODE_STRING";
204                         goto fillin;
205                       }
206                     char *tmp = tmpbuf;
207                     for (i = 0; *tmp && i < n; i++)
208                       *dst++ = *tmp++;
209                     free (tmpbuf);
210                   }
211                   break;
212                 default:
213                   *dst++ = '?';
214                   *dst++ = fmt[-1];
215                 }
216             endfor:
217               break;
218             }
219         }
220     }
221   *dst = 0;
222   SetLastError (err);
223   return dst - orig;
224 }
225
226 extern "C" int
227 __small_sprintf (char *dst, const char *fmt, ...)
228 {
229   int r;
230   va_list ap;
231   va_start (ap, fmt);
232   r = __small_vsprintf (dst, fmt, ap);
233   va_end (ap);
234   return r;
235 }
236
237 extern "C" void
238 small_printf (const char *fmt, ...)
239 {
240   char buf[16384];
241   va_list ap;
242   DWORD done;
243   int count;
244
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);
250   if (h)
251     SetStdHandle (STD_ERROR_HANDLE, h);
252 #endif
253
254   va_start (ap, fmt);
255   count = __small_vsprintf (buf, fmt, ap);
256   va_end (ap);
257
258   WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, count, &done, NULL);
259   FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
260 }
261
262 #ifdef DEBUGGING
263 static HANDLE NO_COPY console_handle = NULL;
264 extern "C" void
265 console_printf (const char *fmt, ...)
266 {
267   char buf[16384];
268   va_list ap;
269   DWORD done;
270   int count;
271
272   if (!console_handle)
273     console_handle = CreateFileA ("CON", GENERIC_WRITE,
274                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
275                                   NULL, OPEN_EXISTING, 0, 0);
276
277   if (console_handle == INVALID_HANDLE_VALUE)
278     console_handle = GetStdHandle (STD_ERROR_HANDLE);
279
280   va_start (ap, fmt);
281   count = __small_vsprintf (buf, fmt, ap);
282   va_end (ap);
283
284   WriteFile (console_handle, buf, count, &done, NULL);
285   FlushFileBuffers (console_handle);
286 }
287 #endif
288
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)
291
292 static PWCHAR __fastcall
293 __wrn (PWCHAR dst, int base, int dosign, long long val, int len, int pad, unsigned long long mask)
294 {
295   /* longest number is ULLONG_MAX, 18446744073709551615, 20 digits */
296   unsigned long long uval = 0;
297   WCHAR res[20];
298   static const WCHAR str[] = L"0123456789ABCDEF";
299   int l = 0;
300
301   if (dosign && val < 0)
302     {
303       *dst++ = L'-';
304       uval = -val;
305     }
306   else if (dosign > 0 && val > 0)
307     {
308       *dst++ = L'+';
309       uval = val;
310     }
311   else
312     uval = val;
313
314   uval &= mask;
315
316   do
317     {
318       res[l++] = str[uval % base];
319       uval /= base;
320     }
321   while (uval);
322
323   while (len-- > l)
324     *dst++ = pad;
325
326   while (l > 0)
327     *dst++ = res[--l];
328
329   return dst;
330 }
331
332 extern "C" int
333 __small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap)
334 {
335   WCHAR tmp[NT_MAX_PATH];
336   PWCHAR orig = dst;
337   const char *s;
338   PWCHAR w;
339   UNICODE_STRING uw, *us;
340
341   DWORD err = GetLastError ();
342
343   while (*fmt)
344     {
345       unsigned int n = 0x7fff;
346       if (*fmt != L'%')
347         *dst++ = *fmt++;
348       else
349         {
350           int len = 0;
351           WCHAR pad = L' ';
352           int addsign = -1;
353
354           switch (*++fmt)
355           {
356             case L'+':
357               addsign = 1;
358               fmt++;
359               break;
360             case L'%':
361               *dst++ = *fmt++;
362               continue;
363           }
364
365           for (;;)
366             {
367               char c = *fmt++;
368               switch (c)
369                 {
370                 case L'0':
371                   if (len == 0)
372                     {
373                       pad = L'0';
374                       continue;
375                     }
376                 case L'1' ... L'9':
377                   len = len * 10 + (c - L'0');
378                   continue;
379                 case L'l':
380                   continue;
381                 case L'c':
382                 case L'C':
383                   {
384                     unsigned int c = va_arg (ap, unsigned int);
385                     if (c > L' ' && c <= 127)
386                       *dst++ = c;
387                     else
388                       {
389                         *dst++ = L'0';
390                         *dst++ = L'x';
391                         dst = __wrn (dst, 16, 0, c, len, pad, LMASK);
392                       }
393                   }
394                   break;
395                 case L'E':
396                   wcscpy (dst, L"Win32 error ");
397                   dst = __wrn (dst + sizeof ("Win32 error"), 10, 0, err, len, pad, LMASK);
398                   break;
399                 case L'd':
400                   dst = wrnarg (dst, 10, addsign, len, pad);
401                   break;
402                 case L'D':
403                   dst = wrnargLL (dst, 10, addsign, len, pad);
404                   break;
405                 case L'u':
406                   dst = wrnarg (dst, 10, 0, len, pad);
407                   break;
408                 case L'U':
409                   dst = wrnargLL (dst, 10, 0, len, pad);
410                   break;
411                 case L'o':
412                   dst = wrnarg (dst, 8, 0, len, pad);
413                   break;
414                 case L'p':
415                   *dst++ = L'0';
416                   *dst++ = L'x';
417                   /* fall through */
418                 case L'x':
419                   dst = wrnarg (dst, 16, 0, len, pad);
420                   break;
421                 case L'X':
422                   dst = wrnargLL (dst, 16, 0, len, pad);
423                   break;
424                 case L'P':
425                   if (!GetModuleFileNameW (NULL, tmp, NT_MAX_PATH))
426                     RtlInitUnicodeString (us = &uw, L"cygwin program");
427                   else
428                     RtlInitUnicodeString (us = &uw, tmp);
429                   goto fillin;
430                 case L'.':
431                   n = wcstoul (fmt, (wchar_t **) &fmt, 10);
432                   if (*fmt++ != L's')
433                     goto endfor;
434                 case L's':
435                   s = va_arg (ap, char *);
436                   if (s == NULL)
437                     s = "(null)";
438                   sys_mbstowcs (tmp, NT_MAX_PATH, s, n);
439                   RtlInitUnicodeString (us = &uw, tmp);
440                   goto fillin;
441                   break;
442                 case L'W':
443                   w = va_arg (ap, PWCHAR);
444                   RtlInitUnicodeString (us = &uw, w);
445                   goto fillin;
446                 case L'S':
447                   us = va_arg (ap, PUNICODE_STRING);
448                 fillin:
449                   if (us->Length / sizeof (WCHAR) < n)
450                     n = us->Length / sizeof (WCHAR);
451                   w = us->Buffer;
452                   for (unsigned int i = 0; i < n; i++)
453                     *dst++ = *w++;
454                   break;
455                 default:
456                   *dst++ = L'?';
457                   *dst++ = fmt[-1];
458                 }
459             endfor:
460               break;
461             }
462         }
463     }
464   *dst = L'\0';
465   SetLastError (err);
466   return dst - orig;
467 }
468
469 extern "C" int
470 __small_swprintf (PWCHAR dst, const WCHAR *fmt, ...)
471 {
472   int r;
473   va_list ap;
474   va_start (ap, fmt);
475   r = __small_vswprintf (dst, fmt, ap);
476   va_end (ap);
477   return r;
478 }