⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfprintf.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <precomp.h>

extern int __mb_cur_max;
int __vfprintf(FILE*, const char*, va_list);

/*
 * @implemented
 */
int vfprintf(FILE* f, const char* fmt, va_list ap)
{
    int len;
    char localbuf[BUFSIZ];

#if 0
    __fileno_lock(_fileno(f));
#endif
    if (f->_flag & _IONBF) {
        f->_flag &= ~_IONBF;
        f->_ptr = f->_base = localbuf;
        f->_bufsiz = f->_cnt = BUFSIZ;
        len = __vfprintf(f, fmt, ap);
        (void)fflush(f);
        f->_flag |= _IONBF;
        f->_base = NULL;
        f->_bufsiz = 0;
        f->_cnt = 0;
    } else {
        len = __vfprintf(f,fmt, ap);
    }
#if 0
    __fileno_unlock(_fileno(f));
#endif
    return (ferror(f) ? EOF : len);
}


/*
 *  linux/lib/vsprintf.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
 * Wirzenius wrote this portably, Torvalds fucked it up :-)
 */

/*
 * Appropiated for the reactos kernel, March 1998 -- David Welch
 */

#include <stdarg.h>

#include <ctype.h>
#include <string.h>
#include <math.h>
#include <internal/ieee.h>


#define ZEROPAD		1	/* pad with zero */
#define SIGN		2	/* unsigned/signed long */
#define PLUS		4	/* show plus */
#define SPACE		8	/* space if plus */
#define LEFT		16	/* left justified */
#define SPECIAL		32	/* 0x */
#define LARGE		64	/* use 'ABCDEF' instead of 'abcdef' */
#define ZEROTRUNC	128	/* truncate zero 's */


static int skip_atoi(const char **s)
{
	int i=0;

	while (isdigit(**s))
		i = i*10 + *((*s)++) - '0';
	return i;
}


static int do_div(LONGLONG *n,int base)
{
	int __res = ((ULONGLONG) *n) % (unsigned) base;
	*n = ((ULONGLONG) *n) / (unsigned) base;
	return __res;
}


static int number(FILE * f, LONGLONG num, int base, int size, int precision ,int type)
{
	char c,sign,tmp[66];
	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
	int i, done = 0;

	if (type & LARGE)
		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	if (type & LEFT)
		type &= ~ZEROPAD;
	if (base < 2 || base > 36)
		return done;
	c = (type & ZEROPAD) ? '0' : ' ';
	sign = 0;
	if (type & SIGN) {
		if (num < 0) {
			sign = '-';
			num = -num;
			size--;
		} else if (type & PLUS) {
			sign = '+';
			size--;
		} else if (type & SPACE) {
			sign = ' ';
			size--;
		}
	}
	if (type & SPECIAL) {
		if (base == 16)
			size -= 2;
		else if (base == 8)
			size--;
	}
	i = 0;
	if (num == 0)
		tmp[i++]='0';
	else while (num != 0)
		tmp[i++] = digits[do_div(&num,base)];
	if (i > precision)
		precision = i;
	size -= precision;
	if (!(type&(ZEROPAD+LEFT)))
		while(size-->0)
		{
			if (putc(' ',f) == EOF)
				return -1;
			done++;
		}
	if (sign)
	{
		if (putc(sign,f) == EOF)
			return -1;
		done++;
	}
	if (type & SPECIAL) {
		if (base==8) {
			if (putc('0',f) == EOF)
				return -1;
			done++;
		}
		else if (base==16) {
			if (putc('0', f) == EOF)
				return -1;
			done++;
			if (putc(digits[33],f) == EOF)
				return -1;
			done++;
		}
	}
	if (!(type & LEFT))
		while (size-- > 0)
		{
			if (putc(c,f) == EOF)
				return -1;
			done++;
		}
	while (i < precision--)
	{
		if (putc('0', f) == EOF)
			return -1;
		done++;
	}
	while (i-- > 0)
	{
		if (putc(tmp[i],f) == EOF)
			return -1;
		done++;
	}
	while (size-- > 0)
	{
		if (putc(' ', f) == EOF)
			return -1;
		done++;
	}
	return done;
}


static int numberf(FILE * f, double __n, char exp_sign,  int size, int precision, int type)
{
	double exponent = 0.0;
	double e;
	long ie;

	//int x;
	char *buf, *tmp;
	int i = 0;
	int j = 0;
	//int k = 0;

	double frac, intr;
	double p;
	char sign;
	char c;
	char ro = 0;
	int result, done = 0;

	union
	{
		double*  __n;
		double_t*  n;
	} n;

	n.__n = &__n;
 
    if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) 
    {
        if ( 0 == n.n->mantissal && 0 == n.n->mantissah && 0 == n.n->exponent )
        {
            ie = 0;
        }
        else
        {
            ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff);
        }

        exponent = ie/3.321928;
    }


	if ( exp_sign == 'g' || exp_sign == 'G' ) {
		type |= ZEROTRUNC;
		if ( exponent < -4 || fabs(exponent) >= precision )
			 exp_sign -= 2; // g -> e and G -> E
		else
		         exp_sign = 'f';
	}

	if ( exp_sign == 'e' ||  exp_sign == 'E' ) {
		frac = modf(exponent,&e);
		if ( frac > 0.5 )
			e++;
		else if (  frac < -0.5  )
			e--;

		result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
		if (result < 0)
			return -1;
		done += result;
		if (putc( exp_sign,f) == EOF)
			return -1;
		done++;
		size--;
		ie = (long)e;
		type = LEFT | PLUS;
		if ( ie < 0 )
			type |= SIGN;

		result = number(f,ie, 10,2, 2,type );
		if (result < 0)
			return -1;
		done += result;
		return done;
	}

	if ( exp_sign == 'f' ) {
		buf = alloca(4096);
		if (type & LEFT) {
			type &= ~ZEROPAD;
		}

		c = (type & ZEROPAD) ? '0' : ' ';
		sign = 0;
		if (type & SIGN) {
			if (__n < 0) {
				sign = '-';
				__n = fabs(__n);
				size--;
			} else if (type & PLUS) {
				sign = '+';
				size--;
			} else if (type & SPACE) {
				sign = ' ';
				size--;
			}
		}

		frac = modf(__n,&intr);

		// # flags forces a . and prevents trucation of trailing zero's

		if ( precision > 0 ) {
			//frac = modfl(__n,&intr);
			i = precision-1;
			while (  i >= 0  ) {
				frac*=10.0L;
				frac = modf(frac, &p);
				buf[i] = (int)p + '0';
				i--;
			}
			i = precision;
			size -= precision;

			ro = 0;
			if ( frac > 0.5 ) {
				ro = 1;
			}

			if ( precision >= 1 || type & SPECIAL) {
				buf[i++] = '.';
				size--;
			}
		}

		if ( intr == 0.0 ) {
			buf[i++] = '0';
			size--;
		}
		else {
			while ( intr > 0.0 ) {
			        p = intr;
				intr/=10.0L;
				modf(intr, &intr);

				p -= 10.0*intr;

				buf[i++] = (int)p + '0';
				size--;
			}
		}

		j = 0;
		while ( j < i && ro == 1) {
			if ( buf[j] >= '0' && buf[j] <= '8' ) {
				buf[j]++;
				ro = 0;
			}
			else if ( buf[j] == '9' ) {
				buf[j] = '0';
			}
			j++;
		}
		if ( ro == 1 )
			buf[i++] = '1';

		buf[i] = 0;

		size -= precision;
		if (!(type&(ZEROPAD+LEFT)))
			while(size-->0)
			{
				if (putc(' ',f) == EOF)
					return -1;
				done++;
			}
		if (sign)
		{
			if (putc( sign,f) == EOF)
				return -1;
			done++;
		}

		if (!(type&(ZEROPAD+LEFT)))
			while(size-->0)
			{
				if (putc(' ',f) == EOF)
					return -1;
				done++;
			}
		if (type & SPECIAL) {
		}

		if (!(type & LEFT))
			while (size-- > 0)
			{
				if (putc(c,f) == EOF)
					return -1;
				done++;
			}

		tmp = buf;
		
		if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
			j = 0;
			while ( j < i && *tmp == L'0' ) {
					tmp++;
					i--;
			}
			if ( j < i && *tmp == L'.' ) {
					tmp++;
					i--;
			}
		}
		
		
//		else
//			while (i < precision--)
//				putc('0', f);
		while (i-- > 0)
		{
			if (putc(tmp[i],f) == EOF)
				return -1;
			done++;
		}
		while (size-- > 0)
		{
			if (putc(' ', f) == EOF)
				return -1;
			done++;
		}
	}
	return done;
}




static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags)
{
	int i, done = 0;
	if (s == NULL)
	{
		s = "<NULL>";
		len = 6;
	}
	else
	{
		if (len == -1)
		{
			len = 0;
			while ((unsigned int)len < (unsigned int)precision && s[len])
				len++;
		}
		else
		{
			if ((unsigned int)len > (unsigned int)precision)
				len = precision;
		}
	}
	if (!(flags & LEFT))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -