win-pvdrivers

changeset 365:2dfaca251422

move mingw_extras.[ch] to a common directory
author Andy Grover <andy.grover@oracle.com>
date Wed Jul 09 00:09:25 2008 -0700 (2008-07-09)
parents c85311cc1aec
children 884c65eed184
files mingw/mingw_extras.c mingw/mingw_extras.h xenpci/mingw_extras.c xenpci/mingw_extras.h
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mingw/mingw_extras.c	Wed Jul 09 00:09:25 2008 -0700
     1.3 @@ -0,0 +1,597 @@
     1.4 +/*
     1.5 + * Provide missing std functions needed by the driver but not provided by
     1.6 + * MinGW. Code mostly taken from Linux or as noted.
     1.7 + *
     1.8 + * Remaining code is
     1.9 + * Copyright Andy Grover <andy.grover@oracle.com> 
    1.10 + * and licensed under the GPLv2.
    1.11 + */
    1.12 +
    1.13 +#include <ntddk.h>
    1.14 +#include "mingw_extras.h"
    1.15 +
    1.16 +NTSTATUS
    1.17 +RtlStringCbPrintfW(
    1.18 +  win_wchar_t *dest_str,
    1.19 +  size_t dest_size,
    1.20 +  win_wchar_t *format,
    1.21 +  ...)
    1.22 +{
    1.23 +  va_list args;
    1.24 +  int len;
    1.25 +  int i;
    1.26 +  char tmp_buf[512];
    1.27 +  NTSTATUS status = STATUS_SUCCESS;
    1.28 +
    1.29 +  if (dest_size > sizeof(tmp_buf))
    1.30 +    dest_size = sizeof(tmp_buf);
    1.31 +
    1.32 +  /* we don't have a 2-byte version of vsnprintf, so write it to a single-byte
    1.33 +     array using vsnprintf() and then copy result to the wchar buffer.
    1.34 +     This should be seldom executed, so this inefficiency should be ok. */
    1.35 +  va_start(args, format);
    1.36 +  len = vsnprintf(tmp_buf, sizeof(tmp_buf), (char *)format, args);
    1.37 +  va_end(args);
    1.38 +
    1.39 +  if (len >= (dest_size * sizeof(win_wchar_t))) {
    1.40 +    /* output buffer truncated */
    1.41 +    status = STATUS_BUFFER_OVERFLOW;
    1.42 +    len = sizeof(tmp_buf) - 1;
    1.43 +    tmp_buf[len] = '\0';
    1.44 +  }
    1.45 +
    1.46 +  /* copy byte-string to short_string, incl NULL */
    1.47 +  for (i = 0; i < (len + 1); i++)
    1.48 +  {
    1.49 +    dest_str[i] = tmp_buf[i];
    1.50 +  }
    1.51 +
    1.52 +  return status;
    1.53 +}
    1.54 +
    1.55 +/* ----- BEGIN Other people's code --------- */
    1.56 +
    1.57 +/* from arch/x86/boot/string.c, used under GPLv2 */
    1.58 +/* Copyright (C) 1991, 1992 Linus Torvalds
    1.59 + * Copyright 2007 rPath, Inc. - All Rights Reserved
    1.60 + */
    1.61 +size_t strnlen(const char *s, size_t maxlen)
    1.62 +{
    1.63 +  const char *es = s;
    1.64 +  while (*es && maxlen) {
    1.65 +    es++;
    1.66 +    maxlen--;
    1.67 +  }
    1.68 +
    1.69 +  return (es - s);
    1.70 +}
    1.71 +
    1.72 +/* from arch/x86/boot/boot.h, used under GPLv2 */
    1.73 +/* Copyright (C) 1991, 1992 Linus Torvalds
    1.74 + * Copyright 2007 rPath, Inc. - All Rights Reserved
    1.75 + */
    1.76 +static int isdigit(int ch)
    1.77 +{
    1.78 +        return (ch >= '0') && (ch <= '9');
    1.79 +}
    1.80 +
    1.81 +/* from K&Rv2 p. 43 */
    1.82 +int atoi(const char s[])
    1.83 +{
    1.84 +  int i, n;
    1.85 +
    1.86 +  n = 0;
    1.87 +  for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
    1.88 +    n = 10 * n + (s[i] - '0');
    1.89 +  return n;
    1.90 +}
    1.91 +
    1.92 +/* from linux/lib/vsprintf.c, used under GPLv2 */
    1.93 +/* Copyright (C) 1991, 1992  Linus Torvalds
    1.94 + * Wirzenius wrote this portably, Torvalds fucked it up :-)
    1.95 + */
    1.96 +static int skip_atoi(const char **s)
    1.97 +{
    1.98 +	int i=0;
    1.99 +
   1.100 +	while (isdigit(**s))
   1.101 +		i = i*10 + *((*s)++) - '0';
   1.102 +	return i;
   1.103 +}
   1.104 +
   1.105 +int snprintf(char * buf, size_t size, const char *fmt, ...)
   1.106 +{
   1.107 +  va_list args;
   1.108 +  int i;
   1.109 +
   1.110 +  va_start(args, fmt);
   1.111 +  i = vsnprintf(buf,size,fmt,args);
   1.112 +  va_end(args);
   1.113 +  return i;
   1.114 +}
   1.115 +
   1.116 +#define do_div(n,base) ({ \
   1.117 +int __res; \
   1.118 +__res = ((unsigned long) n) % (unsigned) base; \
   1.119 +n = ((unsigned long) n) / (unsigned) base; \
   1.120 +__res; })
   1.121 +
   1.122 +
   1.123 +/* Decimal conversion is by far the most typical, and is used
   1.124 + * for /proc and /sys data. This directly impacts e.g. top performance
   1.125 + * with many processes running. We optimize it for speed
   1.126 + * using code from
   1.127 + * http://www.cs.uiowa.edu/~jones/bcd/decimal.html
   1.128 + * (with permission from the author, Douglas W. Jones). */
   1.129 +
   1.130 +/* Formats correctly any integer in [0,99999].
   1.131 + * Outputs from one to five digits depending on input.
   1.132 + * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
   1.133 +static char* put_dec_trunc(char *buf, unsigned q)
   1.134 +{
   1.135 +	unsigned d3, d2, d1, d0;
   1.136 +	d1 = (q>>4) & 0xf;
   1.137 +	d2 = (q>>8) & 0xf;
   1.138 +	d3 = (q>>12);
   1.139 +
   1.140 +	d0 = 6*(d3 + d2 + d1) + (q & 0xf);
   1.141 +	q = (d0 * 0xcd) >> 11;
   1.142 +	d0 = d0 - 10*q;
   1.143 +	*buf++ = d0 + '0'; /* least significant digit */
   1.144 +	d1 = q + 9*d3 + 5*d2 + d1;
   1.145 +	if (d1 != 0) {
   1.146 +		q = (d1 * 0xcd) >> 11;
   1.147 +		d1 = d1 - 10*q;
   1.148 +		*buf++ = d1 + '0'; /* next digit */
   1.149 +
   1.150 +		d2 = q + 2*d2;
   1.151 +		if ((d2 != 0) || (d3 != 0)) {
   1.152 +			q = (d2 * 0xd) >> 7;
   1.153 +			d2 = d2 - 10*q;
   1.154 +			*buf++ = d2 + '0'; /* next digit */
   1.155 +
   1.156 +			d3 = q + 4*d3;
   1.157 +			if (d3 != 0) {
   1.158 +				q = (d3 * 0xcd) >> 11;
   1.159 +				d3 = d3 - 10*q;
   1.160 +				*buf++ = d3 + '0';  /* next digit */
   1.161 +				if (q != 0)
   1.162 +					*buf++ = q + '0';  /* most sign. digit */
   1.163 +			}
   1.164 +		}
   1.165 +	}
   1.166 +	return buf;
   1.167 +}
   1.168 +/* Same with if's removed. Always emits five digits */
   1.169 +static char* put_dec_full(char *buf, unsigned q)
   1.170 +{
   1.171 +	/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
   1.172 +	/* but anyway, gcc produces better code with full-sized ints */
   1.173 +	unsigned d3, d2, d1, d0;
   1.174 +	d1 = (q>>4) & 0xf;
   1.175 +	d2 = (q>>8) & 0xf;
   1.176 +	d3 = (q>>12);
   1.177 +
   1.178 +	/* Possible ways to approx. divide by 10 */
   1.179 +	/* gcc -O2 replaces multiply with shifts and adds */
   1.180 +	// (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
   1.181 +	// (x * 0x67) >> 10:  1100111
   1.182 +	// (x * 0x34) >> 9:    110100 - same
   1.183 +	// (x * 0x1a) >> 8:     11010 - same
   1.184 +	// (x * 0x0d) >> 7:      1101 - same, shortest code (on i386)
   1.185 +
   1.186 +	d0 = 6*(d3 + d2 + d1) + (q & 0xf);
   1.187 +	q = (d0 * 0xcd) >> 11;
   1.188 +	d0 = d0 - 10*q;
   1.189 +	*buf++ = d0 + '0';
   1.190 +	d1 = q + 9*d3 + 5*d2 + d1;
   1.191 +		q = (d1 * 0xcd) >> 11;
   1.192 +		d1 = d1 - 10*q;
   1.193 +		*buf++ = d1 + '0';
   1.194 +
   1.195 +		d2 = q + 2*d2;
   1.196 +			q = (d2 * 0xd) >> 7;
   1.197 +			d2 = d2 - 10*q;
   1.198 +			*buf++ = d2 + '0';
   1.199 +
   1.200 +			d3 = q + 4*d3;
   1.201 +				q = (d3 * 0xcd) >> 11; /* - shorter code */
   1.202 +				/* q = (d3 * 0x67) >> 10; - would also work */
   1.203 +				d3 = d3 - 10*q;
   1.204 +				*buf++ = d3 + '0';
   1.205 +					*buf++ = q + '0';
   1.206 +	return buf;
   1.207 +}
   1.208 +
   1.209 +static char* put_dec(char *buf, unsigned long long num)
   1.210 +{
   1.211 +	while (1) {
   1.212 +		unsigned rem;
   1.213 +		if (num < 100000)
   1.214 +			return put_dec_trunc(buf, num);
   1.215 +		rem = do_div(num, 100000);
   1.216 +		buf = put_dec_full(buf, rem);
   1.217 +	}
   1.218 +}
   1.219 +
   1.220 +
   1.221 +#define ZEROPAD	1		/* pad with zero */
   1.222 +#define SIGN	2		/* unsigned/signed long */
   1.223 +#define PLUS	4		/* show plus */
   1.224 +#define SPACE	8		/* space if plus */
   1.225 +#define LEFT	16		/* left justified */
   1.226 +#define SMALL	32		/* Must be 32 == 0x20 */
   1.227 +#define SPECIAL	64		/* 0x */
   1.228 +
   1.229 +static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
   1.230 +{
   1.231 +	/* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
   1.232 +	static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
   1.233 +
   1.234 +	char tmp[66];
   1.235 +	char sign;
   1.236 +	char locase;
   1.237 +	int need_pfx = ((type & SPECIAL) && base != 10);
   1.238 +	int i;
   1.239 +
   1.240 +	/* locase = 0 or 0x20. ORing digits or letters with 'locase'
   1.241 +	 * produces same digits or (maybe lowercased) letters */
   1.242 +	locase = (type & SMALL);
   1.243 +	if (type & LEFT)
   1.244 +		type &= ~ZEROPAD;
   1.245 +	sign = 0;
   1.246 +	if (type & SIGN) {
   1.247 +		if ((signed long long) num < 0) {
   1.248 +			sign = '-';
   1.249 +			num = - (signed long long) num;
   1.250 +			size--;
   1.251 +		} else if (type & PLUS) {
   1.252 +			sign = '+';
   1.253 +			size--;
   1.254 +		} else if (type & SPACE) {
   1.255 +			sign = ' ';
   1.256 +			size--;
   1.257 +		}
   1.258 +	}
   1.259 +	if (need_pfx) {
   1.260 +		size--;
   1.261 +		if (base == 16)
   1.262 +			size--;
   1.263 +	}
   1.264 +
   1.265 +	/* generate full string in tmp[], in reverse order */
   1.266 +	i = 0;
   1.267 +	if (num == 0)
   1.268 +		tmp[i++] = '0';
   1.269 +	/* Generic code, for any base:
   1.270 +	else do {
   1.271 +		tmp[i++] = (digits[do_div(num,base)] | locase);
   1.272 +	} while (num != 0);
   1.273 +	*/
   1.274 +	else if (base != 10) { /* 8 or 16 */
   1.275 +		int mask = base - 1;
   1.276 +		int shift = 3;
   1.277 +		if (base == 16) shift = 4;
   1.278 +		do {
   1.279 +			tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
   1.280 +			num >>= shift;
   1.281 +		} while (num);
   1.282 +	} else { /* base 10 */
   1.283 +		i = put_dec(tmp, num) - tmp;
   1.284 +	}
   1.285 +
   1.286 +	/* printing 100 using %2d gives "100", not "00" */
   1.287 +	if (i > precision)
   1.288 +		precision = i;
   1.289 +	/* leading space padding */
   1.290 +	size -= precision;
   1.291 +	if (!(type & (ZEROPAD+LEFT))) {
   1.292 +		while(--size >= 0) {
   1.293 +			if (buf < end)
   1.294 +				*buf = ' ';
   1.295 +			++buf;
   1.296 +		}
   1.297 +	}
   1.298 +	/* sign */
   1.299 +	if (sign) {
   1.300 +		if (buf < end)
   1.301 +			*buf = sign;
   1.302 +		++buf;
   1.303 +	}
   1.304 +	/* "0x" / "0" prefix */
   1.305 +	if (need_pfx) {
   1.306 +		if (buf < end)
   1.307 +			*buf = '0';
   1.308 +		++buf;
   1.309 +		if (base == 16) {
   1.310 +			if (buf < end)
   1.311 +				*buf = ('X' | locase);
   1.312 +			++buf;
   1.313 +		}
   1.314 +	}
   1.315 +	/* zero or space padding */
   1.316 +	if (!(type & LEFT)) {
   1.317 +		char c = (type & ZEROPAD) ? '0' : ' ';
   1.318 +		while (--size >= 0) {
   1.319 +			if (buf < end)
   1.320 +				*buf = c;
   1.321 +			++buf;
   1.322 +		}
   1.323 +	}
   1.324 +	/* hmm even more zero padding? */
   1.325 +	while (i <= --precision) {
   1.326 +		if (buf < end)
   1.327 +			*buf = '0';
   1.328 +		++buf;
   1.329 +	}
   1.330 +	/* actual digits of result */
   1.331 +	while (--i >= 0) {
   1.332 +		if (buf < end)
   1.333 +			*buf = tmp[i];
   1.334 +		++buf;
   1.335 +	}
   1.336 +	/* trailing space padding */
   1.337 +	while (--size >= 0) {
   1.338 +		if (buf < end)
   1.339 +			*buf = ' ';
   1.340 +		++buf;
   1.341 +	}
   1.342 +	return buf;
   1.343 +}
   1.344 +
   1.345 +/**
   1.346 + * vsnprintf - Format a string and place it in a buffer
   1.347 + * @buf: The buffer to place the result into
   1.348 + * @size: The size of the buffer, including the trailing null space
   1.349 + * @fmt: The format string to use
   1.350 + * @args: Arguments for the format string
   1.351 + *
   1.352 + * The return value is the number of characters which would
   1.353 + * be generated for the given input, excluding the trailing
   1.354 + * '\0', as per ISO C99. If you want to have the exact
   1.355 + * number of characters written into @buf as return value
   1.356 + * (not including the trailing '\0'), use vscnprintf(). If the
   1.357 + * return is greater than or equal to @size, the resulting
   1.358 + * string is truncated.
   1.359 + *
   1.360 + * Call this function if you are already dealing with a va_list.
   1.361 + * You probably want snprintf() instead.
   1.362 + */
   1.363 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
   1.364 +{
   1.365 +	int len;
   1.366 +	unsigned long long num;
   1.367 +	int i, base;
   1.368 +	char *str, *end, c;
   1.369 +	const char *s;
   1.370 +
   1.371 +	int flags;		/* flags to number() */
   1.372 +
   1.373 +	int field_width;	/* width of output field */
   1.374 +	int precision;		/* min. # of digits for integers; max
   1.375 +				   number of chars for from string */
   1.376 +	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
   1.377 +				/* 'z' support added 23/7/1999 S.H.    */
   1.378 +				/* 'z' changed to 'Z' --davidm 1/25/99 */
   1.379 +				/* 't' added for ptrdiff_t */
   1.380 +
   1.381 +	/* Reject out-of-range values early.  Large positive sizes are
   1.382 +	   used for unknown buffer sizes. */
   1.383 +	if ((int) size < 0)
   1.384 +		return 0;
   1.385 +
   1.386 +	str = buf;
   1.387 +	end = buf + size;
   1.388 +
   1.389 +	/* Make sure end is always >= buf */
   1.390 +	if (end < buf) {
   1.391 +		end = ((void *)-1);
   1.392 +		size = end - buf;
   1.393 +	}
   1.394 +
   1.395 +	for (; *fmt ; ++fmt) {
   1.396 +		if (*fmt != '%') {
   1.397 +			if (str < end)
   1.398 +				*str = *fmt;
   1.399 +			++str;
   1.400 +			continue;
   1.401 +		}
   1.402 +
   1.403 +		/* process flags */
   1.404 +		flags = 0;
   1.405 +		repeat:
   1.406 +			++fmt;		/* this also skips first '%' */
   1.407 +			switch (*fmt) {
   1.408 +				case '-': flags |= LEFT; goto repeat;
   1.409 +				case '+': flags |= PLUS; goto repeat;
   1.410 +				case ' ': flags |= SPACE; goto repeat;
   1.411 +				case '#': flags |= SPECIAL; goto repeat;
   1.412 +				case '0': flags |= ZEROPAD; goto repeat;
   1.413 +			}
   1.414 +
   1.415 +		/* get field width */
   1.416 +		field_width = -1;
   1.417 +		if (isdigit(*fmt))
   1.418 +			field_width = skip_atoi(&fmt);
   1.419 +		else if (*fmt == '*') {
   1.420 +			++fmt;
   1.421 +			/* it's the next argument */
   1.422 +			field_width = va_arg(args, int);
   1.423 +			if (field_width < 0) {
   1.424 +				field_width = -field_width;
   1.425 +				flags |= LEFT;
   1.426 +			}
   1.427 +		}
   1.428 +
   1.429 +		/* get the precision */
   1.430 +		precision = -1;
   1.431 +		if (*fmt == '.') {
   1.432 +			++fmt;	
   1.433 +			if (isdigit(*fmt))
   1.434 +				precision = skip_atoi(&fmt);
   1.435 +			else if (*fmt == '*') {
   1.436 +				++fmt;
   1.437 +				/* it's the next argument */
   1.438 +				precision = va_arg(args, int);
   1.439 +			}
   1.440 +			if (precision < 0)
   1.441 +				precision = 0;
   1.442 +		}
   1.443 +
   1.444 +		/* get the conversion qualifier */
   1.445 +		qualifier = -1;
   1.446 +		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
   1.447 +		    *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
   1.448 +			qualifier = *fmt;
   1.449 +			++fmt;
   1.450 +			if (qualifier == 'l' && *fmt == 'l') {
   1.451 +				qualifier = 'L';
   1.452 +				++fmt;
   1.453 +			}
   1.454 +		}
   1.455 +
   1.456 +		/* default base */
   1.457 +		base = 10;
   1.458 +
   1.459 +		switch (*fmt) {
   1.460 +			case 'c':
   1.461 +				if (!(flags & LEFT)) {
   1.462 +					while (--field_width > 0) {
   1.463 +						if (str < end)
   1.464 +							*str = ' ';
   1.465 +						++str;
   1.466 +					}
   1.467 +				}
   1.468 +				c = (unsigned char) va_arg(args, int);
   1.469 +				if (str < end)
   1.470 +					*str = c;
   1.471 +				++str;
   1.472 +				while (--field_width > 0) {
   1.473 +					if (str < end)
   1.474 +						*str = ' ';
   1.475 +					++str;
   1.476 +				}
   1.477 +				continue;
   1.478 +
   1.479 +			case 's':
   1.480 +				s = va_arg(args, char *);
   1.481 +				if ((unsigned long)s < PAGE_SIZE)
   1.482 +					s = "<NULL>";
   1.483 +
   1.484 +				len = strnlen(s, precision);
   1.485 +
   1.486 +				if (!(flags & LEFT)) {
   1.487 +					while (len < field_width--) {
   1.488 +						if (str < end)
   1.489 +							*str = ' ';
   1.490 +						++str;
   1.491 +					}
   1.492 +				}
   1.493 +				for (i = 0; i < len; ++i) {
   1.494 +					if (str < end)
   1.495 +						*str = *s;
   1.496 +					++str; ++s;
   1.497 +				}
   1.498 +				while (len < field_width--) {
   1.499 +					if (str < end)
   1.500 +						*str = ' ';
   1.501 +					++str;
   1.502 +				}
   1.503 +				continue;
   1.504 +
   1.505 +			case 'p':
   1.506 +				flags |= SMALL;
   1.507 +				if (field_width == -1) {
   1.508 +					field_width = 2*sizeof(void *);
   1.509 +					flags |= ZEROPAD;
   1.510 +				}
   1.511 +				str = number(str, end,
   1.512 +						(unsigned long) va_arg(args, void *),
   1.513 +						16, field_width, precision, flags);
   1.514 +				continue;
   1.515 +
   1.516 +
   1.517 +			case 'n':
   1.518 +				/* FIXME:
   1.519 +				* What does C99 say about the overflow case here? */
   1.520 +				if (qualifier == 'l') {
   1.521 +					long * ip = va_arg(args, long *);
   1.522 +					*ip = (str - buf);
   1.523 +				} else if (qualifier == 'Z' || qualifier == 'z') {
   1.524 +					size_t * ip = va_arg(args, size_t *);
   1.525 +					*ip = (str - buf);
   1.526 +				} else {
   1.527 +					int * ip = va_arg(args, int *);
   1.528 +					*ip = (str - buf);
   1.529 +				}
   1.530 +				continue;
   1.531 +
   1.532 +			case '%':
   1.533 +				if (str < end)
   1.534 +					*str = '%';
   1.535 +				++str;
   1.536 +				continue;
   1.537 +
   1.538 +				/* integer number formats - set up the flags and "break" */
   1.539 +			case 'o':
   1.540 +				base = 8;
   1.541 +				break;
   1.542 +
   1.543 +			case 'x':
   1.544 +				flags |= SMALL;
   1.545 +			case 'X':
   1.546 +				base = 16;
   1.547 +				break;
   1.548 +
   1.549 +			case 'd':
   1.550 +			case 'i':
   1.551 +				flags |= SIGN;
   1.552 +			case 'u':
   1.553 +				break;
   1.554 +
   1.555 +			default:
   1.556 +				if (str < end)
   1.557 +					*str = '%';
   1.558 +				++str;
   1.559 +				if (*fmt) {
   1.560 +					if (str < end)
   1.561 +						*str = *fmt;
   1.562 +					++str;
   1.563 +				} else {
   1.564 +					--fmt;
   1.565 +				}
   1.566 +				continue;
   1.567 +		}
   1.568 +		if (qualifier == 'L')
   1.569 +			num = va_arg(args, long long);
   1.570 +		else if (qualifier == 'l') {
   1.571 +			num = va_arg(args, unsigned long);
   1.572 +			if (flags & SIGN)
   1.573 +				num = (signed long) num;
   1.574 +		} else if (qualifier == 'Z' || qualifier == 'z') {
   1.575 +			num = va_arg(args, size_t);
   1.576 +		} else if (qualifier == 't') {
   1.577 +			num = va_arg(args, ptrdiff_t);
   1.578 +		} else if (qualifier == 'h') {
   1.579 +			num = (unsigned short) va_arg(args, int);
   1.580 +			if (flags & SIGN)
   1.581 +				num = (signed short) num;
   1.582 +		} else {
   1.583 +			num = va_arg(args, unsigned int);
   1.584 +			if (flags & SIGN)
   1.585 +				num = (signed int) num;
   1.586 +		}
   1.587 +		str = number(str, end, num, base,
   1.588 +				field_width, precision, flags);
   1.589 +	}
   1.590 +	if (size > 0) {
   1.591 +		if (str < end)
   1.592 +			*str = '\0';
   1.593 +		else
   1.594 +			end[-1] = '\0';
   1.595 +	}
   1.596 +	/* the trailing null byte doesn't count towards the total */
   1.597 +	return str-buf;
   1.598 +}
   1.599 +/* ----- END Other people's code --------- */
   1.600 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/mingw/mingw_extras.h	Wed Jul 09 00:09:25 2008 -0700
     2.3 @@ -0,0 +1,17 @@
     2.4 +#include <stdio.h>
     2.5 +
     2.6 +/* windows wchar 2 bytes, Linux's is 4! */
     2.7 +typedef unsigned short win_wchar_t;
     2.8 +
     2.9 +NTSTATUS
    2.10 +RtlStringCbPrintfW(
    2.11 +  win_wchar_t *dest_str,
    2.12 +  size_t dest_size,
    2.13 +  win_wchar_t *format,
    2.14 +  ...);
    2.15 +
    2.16 +/* stuff needed for xennet */
    2.17 +#include <ndis.h>
    2.18 +
    2.19 +//#define GCCNOANON u.s2.
    2.20 +
     3.1 --- a/xenpci/mingw_extras.c	Wed Jul 02 11:40:56 2008 -0700
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,596 +0,0 @@
     3.4 -/*
     3.5 - * Provide missing std functions needed by the driver but not provided by
     3.6 - * MinGW. Code mostly taken from Linux or as noted.
     3.7 - *
     3.8 - * Remaining code is
     3.9 - * Copyright Andy Grover <andy.grover@oracle.com> 
    3.10 - * and licensed under the GPLv2.
    3.11 - */
    3.12 -
    3.13 -#include "xenpci.h"
    3.14 -
    3.15 -NTSTATUS
    3.16 -RtlStringCbPrintfW(
    3.17 -  win_wchar_t *dest_str,
    3.18 -  size_t dest_size,
    3.19 -  win_wchar_t *format,
    3.20 -  ...)
    3.21 -{
    3.22 -  va_list args;
    3.23 -  int len;
    3.24 -  int i;
    3.25 -  char tmp_buf[512];
    3.26 -  NTSTATUS status = STATUS_SUCCESS;
    3.27 -
    3.28 -  if (dest_size > sizeof(tmp_buf))
    3.29 -    dest_size = sizeof(tmp_buf);
    3.30 -
    3.31 -  /* we don't have a 2-byte version of vsnprintf, so write it to a single-byte
    3.32 -     array using vsnprintf() and then copy result to the wchar buffer.
    3.33 -     This should be seldom executed, so this inefficiency should be ok. */
    3.34 -  va_start(args, format);
    3.35 -  len = vsnprintf(tmp_buf, sizeof(tmp_buf), (char *)format, args);
    3.36 -  va_end(args);
    3.37 -
    3.38 -  if (len >= (dest_size * sizeof(win_wchar_t))) {
    3.39 -    /* output buffer truncated */
    3.40 -    status = STATUS_BUFFER_OVERFLOW;
    3.41 -    len = sizeof(tmp_buf) - 1;
    3.42 -    tmp_buf[len] = '\0';
    3.43 -  }
    3.44 -
    3.45 -  /* copy byte-string to short_string, incl NULL */
    3.46 -  for (i = 0; i < (len + 1); i++)
    3.47 -  {
    3.48 -    dest_str[i] = tmp_buf[i];
    3.49 -  }
    3.50 -
    3.51 -  return status;
    3.52 -}
    3.53 -
    3.54 -/* ----- BEGIN Other people's code --------- */
    3.55 -
    3.56 -/* from arch/x86/boot/string.c, used under GPLv2 */
    3.57 -/* Copyright (C) 1991, 1992 Linus Torvalds
    3.58 - * Copyright 2007 rPath, Inc. - All Rights Reserved
    3.59 - */
    3.60 -size_t strnlen(const char *s, size_t maxlen)
    3.61 -{
    3.62 -  const char *es = s;
    3.63 -  while (*es && maxlen) {
    3.64 -    es++;
    3.65 -    maxlen--;
    3.66 -  }
    3.67 -
    3.68 -  return (es - s);
    3.69 -}
    3.70 -
    3.71 -/* from arch/x86/boot/boot.h, used under GPLv2 */
    3.72 -/* Copyright (C) 1991, 1992 Linus Torvalds
    3.73 - * Copyright 2007 rPath, Inc. - All Rights Reserved
    3.74 - */
    3.75 -static int isdigit(int ch)
    3.76 -{
    3.77 -        return (ch >= '0') && (ch <= '9');
    3.78 -}
    3.79 -
    3.80 -/* from K&Rv2 p. 43 */
    3.81 -int atoi(const char s[])
    3.82 -{
    3.83 -  int i, n;
    3.84 -
    3.85 -  n = 0;
    3.86 -  for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
    3.87 -    n = 10 * n + (s[i] - '0');
    3.88 -  return n;
    3.89 -}
    3.90 -
    3.91 -/* from linux/lib/vsprintf.c, used under GPLv2 */
    3.92 -/* Copyright (C) 1991, 1992  Linus Torvalds
    3.93 - * Wirzenius wrote this portably, Torvalds fucked it up :-)
    3.94 - */
    3.95 -static int skip_atoi(const char **s)
    3.96 -{
    3.97 -	int i=0;
    3.98 -
    3.99 -	while (isdigit(**s))
   3.100 -		i = i*10 + *((*s)++) - '0';
   3.101 -	return i;
   3.102 -}
   3.103 -
   3.104 -int snprintf(char * buf, size_t size, const char *fmt, ...)
   3.105 -{
   3.106 -  va_list args;
   3.107 -  int i;
   3.108 -
   3.109 -  va_start(args, fmt);
   3.110 -  i = vsnprintf(buf,size,fmt,args);
   3.111 -  va_end(args);
   3.112 -  return i;
   3.113 -}
   3.114 -
   3.115 -#define do_div(n,base) ({ \
   3.116 -int __res; \
   3.117 -__res = ((unsigned long) n) % (unsigned) base; \
   3.118 -n = ((unsigned long) n) / (unsigned) base; \
   3.119 -__res; })
   3.120 -
   3.121 -
   3.122 -/* Decimal conversion is by far the most typical, and is used
   3.123 - * for /proc and /sys data. This directly impacts e.g. top performance
   3.124 - * with many processes running. We optimize it for speed
   3.125 - * using code from
   3.126 - * http://www.cs.uiowa.edu/~jones/bcd/decimal.html
   3.127 - * (with permission from the author, Douglas W. Jones). */
   3.128 -
   3.129 -/* Formats correctly any integer in [0,99999].
   3.130 - * Outputs from one to five digits depending on input.
   3.131 - * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
   3.132 -static char* put_dec_trunc(char *buf, unsigned q)
   3.133 -{
   3.134 -	unsigned d3, d2, d1, d0;
   3.135 -	d1 = (q>>4) & 0xf;
   3.136 -	d2 = (q>>8) & 0xf;
   3.137 -	d3 = (q>>12);
   3.138 -
   3.139 -	d0 = 6*(d3 + d2 + d1) + (q & 0xf);
   3.140 -	q = (d0 * 0xcd) >> 11;
   3.141 -	d0 = d0 - 10*q;
   3.142 -	*buf++ = d0 + '0'; /* least significant digit */
   3.143 -	d1 = q + 9*d3 + 5*d2 + d1;
   3.144 -	if (d1 != 0) {
   3.145 -		q = (d1 * 0xcd) >> 11;
   3.146 -		d1 = d1 - 10*q;
   3.147 -		*buf++ = d1 + '0'; /* next digit */
   3.148 -
   3.149 -		d2 = q + 2*d2;
   3.150 -		if ((d2 != 0) || (d3 != 0)) {
   3.151 -			q = (d2 * 0xd) >> 7;
   3.152 -			d2 = d2 - 10*q;
   3.153 -			*buf++ = d2 + '0'; /* next digit */
   3.154 -
   3.155 -			d3 = q + 4*d3;
   3.156 -			if (d3 != 0) {
   3.157 -				q = (d3 * 0xcd) >> 11;
   3.158 -				d3 = d3 - 10*q;
   3.159 -				*buf++ = d3 + '0';  /* next digit */
   3.160 -				if (q != 0)
   3.161 -					*buf++ = q + '0';  /* most sign. digit */
   3.162 -			}
   3.163 -		}
   3.164 -	}
   3.165 -	return buf;
   3.166 -}
   3.167 -/* Same with if's removed. Always emits five digits */
   3.168 -static char* put_dec_full(char *buf, unsigned q)
   3.169 -{
   3.170 -	/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
   3.171 -	/* but anyway, gcc produces better code with full-sized ints */
   3.172 -	unsigned d3, d2, d1, d0;
   3.173 -	d1 = (q>>4) & 0xf;
   3.174 -	d2 = (q>>8) & 0xf;
   3.175 -	d3 = (q>>12);
   3.176 -
   3.177 -	/* Possible ways to approx. divide by 10 */
   3.178 -	/* gcc -O2 replaces multiply with shifts and adds */
   3.179 -	// (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
   3.180 -	// (x * 0x67) >> 10:  1100111
   3.181 -	// (x * 0x34) >> 9:    110100 - same
   3.182 -	// (x * 0x1a) >> 8:     11010 - same
   3.183 -	// (x * 0x0d) >> 7:      1101 - same, shortest code (on i386)
   3.184 -
   3.185 -	d0 = 6*(d3 + d2 + d1) + (q & 0xf);
   3.186 -	q = (d0 * 0xcd) >> 11;
   3.187 -	d0 = d0 - 10*q;
   3.188 -	*buf++ = d0 + '0';
   3.189 -	d1 = q + 9*d3 + 5*d2 + d1;
   3.190 -		q = (d1 * 0xcd) >> 11;
   3.191 -		d1 = d1 - 10*q;
   3.192 -		*buf++ = d1 + '0';
   3.193 -
   3.194 -		d2 = q + 2*d2;
   3.195 -			q = (d2 * 0xd) >> 7;
   3.196 -			d2 = d2 - 10*q;
   3.197 -			*buf++ = d2 + '0';
   3.198 -
   3.199 -			d3 = q + 4*d3;
   3.200 -				q = (d3 * 0xcd) >> 11; /* - shorter code */
   3.201 -				/* q = (d3 * 0x67) >> 10; - would also work */
   3.202 -				d3 = d3 - 10*q;
   3.203 -				*buf++ = d3 + '0';
   3.204 -					*buf++ = q + '0';
   3.205 -	return buf;
   3.206 -}
   3.207 -
   3.208 -static char* put_dec(char *buf, unsigned long long num)
   3.209 -{
   3.210 -	while (1) {
   3.211 -		unsigned rem;
   3.212 -		if (num < 100000)
   3.213 -			return put_dec_trunc(buf, num);
   3.214 -		rem = do_div(num, 100000);
   3.215 -		buf = put_dec_full(buf, rem);
   3.216 -	}
   3.217 -}
   3.218 -
   3.219 -
   3.220 -#define ZEROPAD	1		/* pad with zero */
   3.221 -#define SIGN	2		/* unsigned/signed long */
   3.222 -#define PLUS	4		/* show plus */
   3.223 -#define SPACE	8		/* space if plus */
   3.224 -#define LEFT	16		/* left justified */
   3.225 -#define SMALL	32		/* Must be 32 == 0x20 */
   3.226 -#define SPECIAL	64		/* 0x */
   3.227 -
   3.228 -static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
   3.229 -{
   3.230 -	/* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
   3.231 -	static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
   3.232 -
   3.233 -	char tmp[66];
   3.234 -	char sign;
   3.235 -	char locase;
   3.236 -	int need_pfx = ((type & SPECIAL) && base != 10);
   3.237 -	int i;
   3.238 -
   3.239 -	/* locase = 0 or 0x20. ORing digits or letters with 'locase'
   3.240 -	 * produces same digits or (maybe lowercased) letters */
   3.241 -	locase = (type & SMALL);
   3.242 -	if (type & LEFT)
   3.243 -		type &= ~ZEROPAD;
   3.244 -	sign = 0;
   3.245 -	if (type & SIGN) {
   3.246 -		if ((signed long long) num < 0) {
   3.247 -			sign = '-';
   3.248 -			num = - (signed long long) num;
   3.249 -			size--;
   3.250 -		} else if (type & PLUS) {
   3.251 -			sign = '+';
   3.252 -			size--;
   3.253 -		} else if (type & SPACE) {
   3.254 -			sign = ' ';
   3.255 -			size--;
   3.256 -		}
   3.257 -	}
   3.258 -	if (need_pfx) {
   3.259 -		size--;
   3.260 -		if (base == 16)
   3.261 -			size--;
   3.262 -	}
   3.263 -
   3.264 -	/* generate full string in tmp[], in reverse order */
   3.265 -	i = 0;
   3.266 -	if (num == 0)
   3.267 -		tmp[i++] = '0';
   3.268 -	/* Generic code, for any base:
   3.269 -	else do {
   3.270 -		tmp[i++] = (digits[do_div(num,base)] | locase);
   3.271 -	} while (num != 0);
   3.272 -	*/
   3.273 -	else if (base != 10) { /* 8 or 16 */
   3.274 -		int mask = base - 1;
   3.275 -		int shift = 3;
   3.276 -		if (base == 16) shift = 4;
   3.277 -		do {
   3.278 -			tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
   3.279 -			num >>= shift;
   3.280 -		} while (num);
   3.281 -	} else { /* base 10 */
   3.282 -		i = put_dec(tmp, num) - tmp;
   3.283 -	}
   3.284 -
   3.285 -	/* printing 100 using %2d gives "100", not "00" */
   3.286 -	if (i > precision)
   3.287 -		precision = i;
   3.288 -	/* leading space padding */
   3.289 -	size -= precision;
   3.290 -	if (!(type & (ZEROPAD+LEFT))) {
   3.291 -		while(--size >= 0) {
   3.292 -			if (buf < end)
   3.293 -				*buf = ' ';
   3.294 -			++buf;
   3.295 -		}
   3.296 -	}
   3.297 -	/* sign */
   3.298 -	if (sign) {
   3.299 -		if (buf < end)
   3.300 -			*buf = sign;
   3.301 -		++buf;
   3.302 -	}
   3.303 -	/* "0x" / "0" prefix */
   3.304 -	if (need_pfx) {
   3.305 -		if (buf < end)
   3.306 -			*buf = '0';
   3.307 -		++buf;
   3.308 -		if (base == 16) {
   3.309 -			if (buf < end)
   3.310 -				*buf = ('X' | locase);
   3.311 -			++buf;
   3.312 -		}
   3.313 -	}
   3.314 -	/* zero or space padding */
   3.315 -	if (!(type & LEFT)) {
   3.316 -		char c = (type & ZEROPAD) ? '0' : ' ';
   3.317 -		while (--size >= 0) {
   3.318 -			if (buf < end)
   3.319 -				*buf = c;
   3.320 -			++buf;
   3.321 -		}
   3.322 -	}
   3.323 -	/* hmm even more zero padding? */
   3.324 -	while (i <= --precision) {
   3.325 -		if (buf < end)
   3.326 -			*buf = '0';
   3.327 -		++buf;
   3.328 -	}
   3.329 -	/* actual digits of result */
   3.330 -	while (--i >= 0) {
   3.331 -		if (buf < end)
   3.332 -			*buf = tmp[i];
   3.333 -		++buf;
   3.334 -	}
   3.335 -	/* trailing space padding */
   3.336 -	while (--size >= 0) {
   3.337 -		if (buf < end)
   3.338 -			*buf = ' ';
   3.339 -		++buf;
   3.340 -	}
   3.341 -	return buf;
   3.342 -}
   3.343 -
   3.344 -/**
   3.345 - * vsnprintf - Format a string and place it in a buffer
   3.346 - * @buf: The buffer to place the result into
   3.347 - * @size: The size of the buffer, including the trailing null space
   3.348 - * @fmt: The format string to use
   3.349 - * @args: Arguments for the format string
   3.350 - *
   3.351 - * The return value is the number of characters which would
   3.352 - * be generated for the given input, excluding the trailing
   3.353 - * '\0', as per ISO C99. If you want to have the exact
   3.354 - * number of characters written into @buf as return value
   3.355 - * (not including the trailing '\0'), use vscnprintf(). If the
   3.356 - * return is greater than or equal to @size, the resulting
   3.357 - * string is truncated.
   3.358 - *
   3.359 - * Call this function if you are already dealing with a va_list.
   3.360 - * You probably want snprintf() instead.
   3.361 - */
   3.362 -int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
   3.363 -{
   3.364 -	int len;
   3.365 -	unsigned long long num;
   3.366 -	int i, base;
   3.367 -	char *str, *end, c;
   3.368 -	const char *s;
   3.369 -
   3.370 -	int flags;		/* flags to number() */
   3.371 -
   3.372 -	int field_width;	/* width of output field */
   3.373 -	int precision;		/* min. # of digits for integers; max
   3.374 -				   number of chars for from string */
   3.375 -	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
   3.376 -				/* 'z' support added 23/7/1999 S.H.    */
   3.377 -				/* 'z' changed to 'Z' --davidm 1/25/99 */
   3.378 -				/* 't' added for ptrdiff_t */
   3.379 -
   3.380 -	/* Reject out-of-range values early.  Large positive sizes are
   3.381 -	   used for unknown buffer sizes. */
   3.382 -	if ((int) size < 0)
   3.383 -		return 0;
   3.384 -
   3.385 -	str = buf;
   3.386 -	end = buf + size;
   3.387 -
   3.388 -	/* Make sure end is always >= buf */
   3.389 -	if (end < buf) {
   3.390 -		end = ((void *)-1);
   3.391 -		size = end - buf;
   3.392 -	}
   3.393 -
   3.394 -	for (; *fmt ; ++fmt) {
   3.395 -		if (*fmt != '%') {
   3.396 -			if (str < end)
   3.397 -				*str = *fmt;
   3.398 -			++str;
   3.399 -			continue;
   3.400 -		}
   3.401 -
   3.402 -		/* process flags */
   3.403 -		flags = 0;
   3.404 -		repeat:
   3.405 -			++fmt;		/* this also skips first '%' */
   3.406 -			switch (*fmt) {
   3.407 -				case '-': flags |= LEFT; goto repeat;
   3.408 -				case '+': flags |= PLUS; goto repeat;
   3.409 -				case ' ': flags |= SPACE; goto repeat;
   3.410 -				case '#': flags |= SPECIAL; goto repeat;
   3.411 -				case '0': flags |= ZEROPAD; goto repeat;
   3.412 -			}
   3.413 -
   3.414 -		/* get field width */
   3.415 -		field_width = -1;
   3.416 -		if (isdigit(*fmt))
   3.417 -			field_width = skip_atoi(&fmt);
   3.418 -		else if (*fmt == '*') {
   3.419 -			++fmt;
   3.420 -			/* it's the next argument */
   3.421 -			field_width = va_arg(args, int);
   3.422 -			if (field_width < 0) {
   3.423 -				field_width = -field_width;
   3.424 -				flags |= LEFT;
   3.425 -			}
   3.426 -		}
   3.427 -
   3.428 -		/* get the precision */
   3.429 -		precision = -1;
   3.430 -		if (*fmt == '.') {
   3.431 -			++fmt;	
   3.432 -			if (isdigit(*fmt))
   3.433 -				precision = skip_atoi(&fmt);
   3.434 -			else if (*fmt == '*') {
   3.435 -				++fmt;
   3.436 -				/* it's the next argument */
   3.437 -				precision = va_arg(args, int);
   3.438 -			}
   3.439 -			if (precision < 0)
   3.440 -				precision = 0;
   3.441 -		}
   3.442 -
   3.443 -		/* get the conversion qualifier */
   3.444 -		qualifier = -1;
   3.445 -		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
   3.446 -		    *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
   3.447 -			qualifier = *fmt;
   3.448 -			++fmt;
   3.449 -			if (qualifier == 'l' && *fmt == 'l') {
   3.450 -				qualifier = 'L';
   3.451 -				++fmt;
   3.452 -			}
   3.453 -		}
   3.454 -
   3.455 -		/* default base */
   3.456 -		base = 10;
   3.457 -
   3.458 -		switch (*fmt) {
   3.459 -			case 'c':
   3.460 -				if (!(flags & LEFT)) {
   3.461 -					while (--field_width > 0) {
   3.462 -						if (str < end)
   3.463 -							*str = ' ';
   3.464 -						++str;
   3.465 -					}
   3.466 -				}
   3.467 -				c = (unsigned char) va_arg(args, int);
   3.468 -				if (str < end)
   3.469 -					*str = c;
   3.470 -				++str;
   3.471 -				while (--field_width > 0) {
   3.472 -					if (str < end)
   3.473 -						*str = ' ';
   3.474 -					++str;
   3.475 -				}
   3.476 -				continue;
   3.477 -
   3.478 -			case 's':
   3.479 -				s = va_arg(args, char *);
   3.480 -				if ((unsigned long)s < PAGE_SIZE)
   3.481 -					s = "<NULL>";
   3.482 -
   3.483 -				len = strnlen(s, precision);
   3.484 -
   3.485 -				if (!(flags & LEFT)) {
   3.486 -					while (len < field_width--) {
   3.487 -						if (str < end)
   3.488 -							*str = ' ';
   3.489 -						++str;
   3.490 -					}
   3.491 -				}
   3.492 -				for (i = 0; i < len; ++i) {
   3.493 -					if (str < end)
   3.494 -						*str = *s;
   3.495 -					++str; ++s;
   3.496 -				}
   3.497 -				while (len < field_width--) {
   3.498 -					if (str < end)
   3.499 -						*str = ' ';
   3.500 -					++str;
   3.501 -				}
   3.502 -				continue;
   3.503 -
   3.504 -			case 'p':
   3.505 -				flags |= SMALL;
   3.506 -				if (field_width == -1) {
   3.507 -					field_width = 2*sizeof(void *);
   3.508 -					flags |= ZEROPAD;
   3.509 -				}
   3.510 -				str = number(str, end,
   3.511 -						(unsigned long) va_arg(args, void *),
   3.512 -						16, field_width, precision, flags);
   3.513 -				continue;
   3.514 -
   3.515 -
   3.516 -			case 'n':
   3.517 -				/* FIXME:
   3.518 -				* What does C99 say about the overflow case here? */
   3.519 -				if (qualifier == 'l') {
   3.520 -					long * ip = va_arg(args, long *);
   3.521 -					*ip = (str - buf);
   3.522 -				} else if (qualifier == 'Z' || qualifier == 'z') {
   3.523 -					size_t * ip = va_arg(args, size_t *);
   3.524 -					*ip = (str - buf);
   3.525 -				} else {
   3.526 -					int * ip = va_arg(args, int *);
   3.527 -					*ip = (str - buf);
   3.528 -				}
   3.529 -				continue;
   3.530 -
   3.531 -			case '%':
   3.532 -				if (str < end)
   3.533 -					*str = '%';
   3.534 -				++str;
   3.535 -				continue;
   3.536 -
   3.537 -				/* integer number formats - set up the flags and "break" */
   3.538 -			case 'o':
   3.539 -				base = 8;
   3.540 -				break;
   3.541 -
   3.542 -			case 'x':
   3.543 -				flags |= SMALL;
   3.544 -			case 'X':
   3.545 -				base = 16;
   3.546 -				break;
   3.547 -
   3.548 -			case 'd':
   3.549 -			case 'i':
   3.550 -				flags |= SIGN;
   3.551 -			case 'u':
   3.552 -				break;
   3.553 -
   3.554 -			default:
   3.555 -				if (str < end)
   3.556 -					*str = '%';
   3.557 -				++str;
   3.558 -				if (*fmt) {
   3.559 -					if (str < end)
   3.560 -						*str = *fmt;
   3.561 -					++str;
   3.562 -				} else {
   3.563 -					--fmt;
   3.564 -				}
   3.565 -				continue;
   3.566 -		}
   3.567 -		if (qualifier == 'L')
   3.568 -			num = va_arg(args, long long);
   3.569 -		else if (qualifier == 'l') {
   3.570 -			num = va_arg(args, unsigned long);
   3.571 -			if (flags & SIGN)
   3.572 -				num = (signed long) num;
   3.573 -		} else if (qualifier == 'Z' || qualifier == 'z') {
   3.574 -			num = va_arg(args, size_t);
   3.575 -		} else if (qualifier == 't') {
   3.576 -			num = va_arg(args, ptrdiff_t);
   3.577 -		} else if (qualifier == 'h') {
   3.578 -			num = (unsigned short) va_arg(args, int);
   3.579 -			if (flags & SIGN)
   3.580 -				num = (signed short) num;
   3.581 -		} else {
   3.582 -			num = va_arg(args, unsigned int);
   3.583 -			if (flags & SIGN)
   3.584 -				num = (signed int) num;
   3.585 -		}
   3.586 -		str = number(str, end, num, base,
   3.587 -				field_width, precision, flags);
   3.588 -	}
   3.589 -	if (size > 0) {
   3.590 -		if (str < end)
   3.591 -			*str = '\0';
   3.592 -		else
   3.593 -			end[-1] = '\0';
   3.594 -	}
   3.595 -	/* the trailing null byte doesn't count towards the total */
   3.596 -	return str-buf;
   3.597 -}
   3.598 -/* ----- END Other people's code --------- */
   3.599 -
     4.1 --- a/xenpci/mingw_extras.h	Wed Jul 02 11:40:56 2008 -0700
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,43 +0,0 @@
     4.4 -#include <stdio.h>
     4.5 -#include <stdlib.h>
     4.6 -
     4.7 -#define KeMemoryBarrier() asm("mfence;")
     4.8 -/* mingw-runtime 3.13 is buggy #1 */
     4.9 -#undef KeGetCurrentProcessorNumber
    4.10 -#define KeGetCurrentProcessorNumber() \
    4.11 -  ((ULONG)KeGetCurrentKPCR()->Number)
    4.12 -
    4.13 -/* mingw-runtime 3.13 is buggy #2 */
    4.14 -#undef KeRaiseIrql
    4.15 -#undef KeLowerIrql
    4.16 -
    4.17 -NTOSAPI
    4.18 -VOID
    4.19 -DDKAPI
    4.20 -KeRaiseIrql(IN KIRQL new_irql, OUT PKIRQL old_irql);
    4.21 -
    4.22 -NTOSAPI
    4.23 -VOID
    4.24 -DDKAPI
    4.25 -KeLowerIrql(IN KIRQL irql);
    4.26 -
    4.27 -extern NTOSAPI CCHAR KeNumberProcessors;
    4.28 -
    4.29 -NTOSAPI
    4.30 -VOID
    4.31 -DDKAPI
    4.32 -KeFlushQueuedDpcs(VOID);
    4.33 -
    4.34 -#define RtlStringCbCopyA(dst, dst_len, src) strncpy(dst, src, dst_len)
    4.35 -#define RtlStringCbPrintfA(args...) snprintf(args)
    4.36 -#define RtlStringCbVPrintfA(args...) vsnprintf(args)
    4.37 -
    4.38 -/* windows wchar 2 bytes, Linux's is 4! */
    4.39 -typedef unsigned short win_wchar_t;
    4.40 -
    4.41 -NTSTATUS
    4.42 -RtlStringCbPrintfW(
    4.43 -  win_wchar_t *dest_str,
    4.44 -  size_t dest_size,
    4.45 -  win_wchar_t *format,
    4.46 -  ...);