]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygserver/smallprint.c
* lib/Makefile: Add missed file to accommodate below changes.
[newlib-cygwin.git] / winsup / cygserver / smallprint.c
CommitLineData
dcd1ef45
CV
1/* smallprint.c: small print routines for WIN32
2
3 Copyright 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
4
5This file is part of Cygwin.
6
7This software is a copyrighted work licensed under the terms of the
8Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9details. */
10
11#include "winsup.h"
12#include <stdarg.h>
13#include <stdlib.h>
14#include <ctype.h>
15#define WIN32_LEAN_AND_MEAN
16#include <windows.h>
17
18int __small_sprintf (char *dst, const char *fmt, ...);
19int __small_vsprintf (char *dst, const char *fmt, va_list ap);
20
21#define LLMASK (0xffffffffffffffffULL)
22#define LMASK (0xffffffff)
23
24#define rnarg(dst, base, dosign, len, pad) __rn ((dst), (base), (dosign), va_arg (ap, long), len, pad, LMASK)
25#define rnargLL(dst, base, dosign, len, pad) __rn ((dst), (base), (dosign), va_arg (ap, unsigned long long), len, pad, LLMASK)
26
27static char __fastcall *
28__rn (char *dst, int base, int dosign, long long val, int len, int pad, unsigned long long mask)
29{
30 /* longest number is ULLONG_MAX, 18446744073709551615, 20 digits */
31 unsigned long long uval = 0;
32 char res[20];
33 static const char str[16] = "0123456789ABCDEF";
34 int l = 0;
35
36 if (dosign && val < 0)
37 {
38 *dst++ = '-';
39 uval = -val;
40 }
41 else if (dosign > 0 && val > 0)
42 {
43 *dst++ = '+';
44 uval = val;
45 }
46 else
47 uval = val;
48
49 uval &= mask;
50
51 do
52 {
53 res[l++] = str[uval % base];
54 uval /= base;
55 }
56 while (uval);
57
58 while (len-- > l)
59 *dst++ = pad;
60
61 while (l > 0)
62 *dst++ = res[--l];
63
64 return dst;
65}
66
67int
68__small_vsprintf (char *dst, const char *fmt, va_list ap)
69{
70 char tmp[CYG_MAX_PATH + 1];
71 char *orig = dst;
72 const char *s;
73
74 DWORD err = GetLastError ();
75
76 while (*fmt)
77 {
78 int i, n = 0x7fff;
79 if (*fmt != '%')
80 *dst++ = *fmt++;
81 else
82 {
83 int len = 0;
84 char pad = ' ';
85 int addsign = -1;
86
87 switch (*++fmt)
88 {
89 case '+':
90 addsign = 1;
91 fmt++;
92 break;
93 case '%':
94 *dst++ = *fmt++;
95 continue;
96 }
97
98 for (;;)
99 {
100 char c = *fmt++;
101 switch (c)
102 {
103 case '0':
104 if (len == 0)
105 {
106 pad = '0';
107 continue;
108 }
109 case '1': case '2': case '3': case '4':
110 case '5': case '6': case '7': case '8': case '9':
111 len = len * 10 + (c - '0');
112 continue;
113 case 'l':
114 continue;
115 case 'c':
116 {
117 int c = va_arg (ap, int);
118 if (c > ' ' && c <= 127)
119 *dst++ = c;
120 else
121 {
122 *dst++ = '0';
123 *dst++ = 'x';
124 dst = __rn (dst, 16, 0, c, len, pad, LMASK);
125 }
126 }
127 break;
128 case 'E':
129 strcpy (dst, "Win32 error ");
130 dst = __rn (dst + sizeof ("Win32 error"), 10, 0, err, len, pad, LMASK);
131 break;
132 case 'd':
133 dst = rnarg (dst, 10, addsign, len, pad);
134 break;
135 case 'D':
136 dst = rnargLL (dst, 10, addsign, len, pad);
137 break;
138 case 'u':
139 dst = rnarg (dst, 10, 0, len, pad);
140 break;
141 case 'U':
142 dst = rnargLL (dst, 10, 0, len, pad);
143 break;
144 case 'o':
145 dst = rnarg (dst, 8, 0, len, pad);
146 break;
147 case 'p':
148 *dst++ = '0';
149 *dst++ = 'x';
150 /* fall through */
151 case 'x':
152 dst = rnarg (dst, 16, 0, len, pad);
153 break;
154 case 'X':
155 dst = rnargLL (dst, 16, 0, len, pad);
156 break;
157 case 'P':
158 if (!GetModuleFileName (NULL, tmp, CYG_MAX_PATH))
159 s = "cygwin program";
160 else
161 s = tmp;
162 goto fillin;
163 case '.':
164 n = strtol (fmt, (char **) &fmt, 10);
165 if (*fmt++ != 's')
166 goto endfor;
167 case 's':
168 s = va_arg (ap, char *);
169 if (s == NULL)
170 s = "(null)";
171 fillin:
172 for (i = 0; *s && i < n; i++)
173 *dst++ = *s++;
174 break;
175 default:
176 *dst++ = '?';
177 *dst++ = fmt[-1];
178 }
179 endfor:
180 break;
181 }
182 }
183 }
184 *dst = 0;
185 SetLastError (err);
186 return dst - orig;
187}
188
189int
190__small_sprintf (char *dst, const char *fmt, ...)
191{
192 int r;
193 va_list ap;
194 va_start (ap, fmt);
195 r = __small_vsprintf (dst, fmt, ap);
196 va_end (ap);
197 return r;
198}
199
200void
201small_printf (const char *fmt, ...)
202{
203 char buf[16384];
204 va_list ap;
205 DWORD done;
206 int count;
207
208#if 0 /* Turn on to force console errors */
209 extern SECURITY_ATTRIBUTES sec_none;
210 HANDLE h = CreateFileA ("CONOUT$", GENERIC_READ|GENERIC_WRITE,
211 FILE_SHARE_WRITE | FILE_SHARE_WRITE, &sec_none,
212 OPEN_EXISTING, 0, 0);
213 if (h)
214 SetStdHandle (STD_ERROR_HANDLE, h);
215#endif
216
217 va_start (ap, fmt);
218 count = __small_vsprintf (buf, fmt, ap);
219 va_end (ap);
220
221 WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, count, &done, NULL);
222 FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
223}
224
225#ifdef DEBUGGING
226static HANDLE NO_COPY console_handle = NULL;
227void
228console_printf (const char *fmt, ...)
229{
230 char buf[16384];
231 va_list ap;
232 DWORD done;
233 int count;
234
235 if (!console_handle)
236 console_handle = CreateFileA ("CON", GENERIC_WRITE,
237 FILE_SHARE_READ | FILE_SHARE_WRITE,
238 NULL, OPEN_EXISTING, 0, 0);
239
240 if (console_handle == INVALID_HANDLE_VALUE)
241 console_handle = GetStdHandle (STD_ERROR_HANDLE);
242
243 va_start (ap, fmt);
244 count = __small_vsprintf (buf, fmt, ap);
245 va_end (ap);
246
247 WriteFile (console_handle, buf, count, &done, NULL);
248 FlushFileBuffers (console_handle);
249}
250#endif
This page took 0.045306 seconds and 5 git commands to generate.