diff options
author | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:38:33 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:38:33 +0000 |
commit | 1fd5e000ace55b323124c7e556a7a864b972a5c4 (patch) | |
tree | dc4fcf1e5e22a040716ef92c496b8d94959b2baa /winsup/cygwin/smallprint.c | |
parent | 369d8a8fd5e887eca547bf34bccfdf755c9e5397 (diff) | |
download | newlib-1fd5e000ace55b323124c7e556a7a864b972a5c4.zip newlib-1fd5e000ace55b323124c7e556a7a864b972a5c4.tar.gz newlib-1fd5e000ace55b323124c7e556a7a864b972a5c4.tar.bz2 |
import winsup-2000-02-17 snapshot
Diffstat (limited to 'winsup/cygwin/smallprint.c')
-rw-r--r-- | winsup/cygwin/smallprint.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/winsup/cygwin/smallprint.c b/winsup/cygwin/smallprint.c new file mode 100644 index 0000000..3bfbda2 --- /dev/null +++ b/winsup/cygwin/smallprint.c @@ -0,0 +1,229 @@ +/* smallprint.c: small print routines for WIN32 + + Copyright 1996, 1998, 2000 Cygnus Solutions. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <windows.h> + +int __small_sprintf (char *dst, const char *fmt,...); +int __small_vsprintf (char *dst, const char *fmt, va_list ap); + +static char * +rn (char *dst, int base, int dosign, int val, int len, int pad) +{ + /* longest number is 4294967295, 10 digits */ + unsigned uval; + char res[10]; + static const char str[16] = "0123456789ABCDEF"; + int l = 0; + + if (dosign && val < 0) + { + *dst++ = '-'; + uval = -val; + } + else if (dosign > 0 && val > 0) + { + *dst++ = '+'; + uval = val; + } + else + { + uval = val; + } + + do + { + res[l++] = str[uval % base]; + uval /= base; + } + while (uval); + + while (len -- > l) + *dst++ = pad; + + while (l > 0) + { + *dst++ = res[--l]; + } + + return dst; +} + +int +__small_vsprintf (char *dst, const char *fmt, va_list ap) +{ + char tmp[MAX_PATH + 1]; + char *orig = dst; + const char *s; + + while (*fmt) + { + int i, n = 0x7fff; + if (*fmt != '%') + *dst++ = *fmt++; + else + { + int len = 0; + char pad = ' '; + int addsign = -1; + + switch (*++fmt) + { + case '+': + addsign = 1; + fmt++; + break; + case '%': + *dst++ = *fmt++; + continue; + } + + for (;;) + { + char c = *fmt++; + switch (c) + { + case '0': + if (len == 0) + { + pad = '0'; + continue; + } + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + len = len * 10 + (c - '0'); + continue; + case 'l': + continue; + case 'c': + { + int c = va_arg (ap,int); + if (c > ' ' && c <= 127) + *dst++ = c; + else + { + *dst++ = '0'; + *dst++ = 'x'; + dst = rn (dst, 16, 0, c, len, pad); + } + } + break; + case 'E': + strcpy (dst, "Win32 error "); + dst = rn (dst + sizeof ("Win32 error"), 10, 0, GetLastError (), len, pad); + break; + case 'd': + dst = rn (dst, 10, addsign, va_arg (ap, int), len, pad); + break; + case 'u': + dst = rn (dst, 10, 0, va_arg (ap, int), len, pad); + break; + case 'p': + *dst++ = '0'; + *dst++ = 'x'; + /* fall through */ + case 'x': + dst = rn (dst, 16, 0, va_arg (ap, int), len, pad); + break; + case 'P': + if (!GetModuleFileName (NULL, tmp, MAX_PATH)) + s = "cygwin program"; + else + s = tmp; + goto fillin; + case '.': + n = strtol (fmt, (char **)&fmt, 10); + if (*fmt++ != 's') + goto endfor; + case 's': + s = va_arg (ap, char *); + if (s == NULL) + s = "(null)"; + fillin: + for (i = 0; *s && i < n; i++) + *dst++ = *s++; + break; + case 'F': + { + const char *p, *pe; + s = va_arg (ap, char *); + for (p = s; (pe = strchr (p, '(')); p = pe + 1) + if (isalnum ((int)pe[-1]) || pe[-1] == '_') + break; + else if (isspace((int)pe[-1])) + { + pe--; + break; + } + if (!pe) + pe = strchr (s, '\0'); + for (p = pe; p > s; p--) + if (p != pe && *p == ' ') + { + p++; + break; + } + if (*p == '*') + p++; + while (p < pe) + *dst++ = *p++; + break; + } + default: + *dst++ = '?'; + *dst++ = fmt[-1]; + } + endfor: + break; + } + } + } + *dst = 0; + return dst - orig; +} + +int +__small_sprintf (char *dst, const char *fmt,...) +{ + int r; + va_list ap; + va_start (ap, fmt); + r = __small_vsprintf (dst, fmt, ap); + va_end (ap); + return r; +} + +void +small_printf (const char *fmt,...) +{ + char buf[2000]; + va_list ap; + DWORD done; + int count; + +#if 0 /* Turn on to force console errors */ + extern SECURITY_ATTRIBUTES sec_none; + HANDLE h = CreateFileA ("CONOUT$", GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_WRITE, &sec_none, + OPEN_EXISTING, 0, 0); + if (h) + SetStdHandle (STD_ERROR_HANDLE, h); +#endif + + va_start (ap, fmt); + count = __small_vsprintf (buf, fmt, ap); + va_end (ap); + + WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, count, &done, 0); + FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE)); +} |