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

📄 vfwprint.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
				len++;
		}
		else
		{
			if ((unsigned int)len > (unsigned int)precision)
				len = precision;
		}
	}
	if (!(flags & LEFT))
		while (len < field_width--)
		{
			if (putwc(L' ', f) == WEOF)
				return -1;
			done++;
		}
	for (i = 0; i < len; ++i)
	{
		if (putwc(*s++, f) == WEOF)
			return -1;
		done++;
	}
	while (len < field_width--)
	{
		if (putwc(L' ', f) == WEOF)
			return -1;
		done++;
	}
	return done;
}

static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags)
{
	int i, done = 0;
	if (sw == NULL)
	{
		sw = L"<NULL>";
		len = 6;
	}
	else
	{
		if (len == -1)
		{
			len = 0;
			while ((unsigned int)len < (unsigned int)precision && sw[len])
				len++;
		}
		else
		{
			if ((unsigned int)len > (unsigned int)precision)
				len = precision;
		}
	}
	if (!(flags & LEFT))
		while (len < field_width--)
		{
			if (putwc(L' ', f) == WEOF)
				return -1;
			done++;
		}
	for (i = 0; i < len; ++i)
	{
		if (putwc(*sw++, f) == WEOF)
			return -1;
		done++;
	}
	while (len < field_width--)
	{
		if (putwc(L' ', f) == WEOF)
			return -1;
		done++;
	}
	return done;
}

int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
{
	int len = 0;
	ULONGLONG num;
	int base;
	double _double;
	const char *s;
	const wchar_t* sw;
	int result, done = 0;

	int flags;		/* flags to number() */

	int field_width;	/* width of output field */
	int precision;		/* min. # of digits for integers; max
				   number of chars for from string */
	int qualifier = 0;	/* 'h', 'l', 'L' or 'I64' for integer fields */

	for (; *fmt ; ++fmt) {
		if (*fmt != L'%') {
			if (putwc(*fmt,f) == WEOF)
				return -1;
			done++;
			continue;
		}

		/* process flags */
		flags = 0;
		repeat:
			++fmt;		/* this also skips first '%' */
			switch (*fmt) {
				case L'-': flags |= LEFT; goto repeat;
				case L'+': flags |= PLUS; goto repeat;
				case L' ': flags |= SPACE; goto repeat;
				case L'#': flags |= SPECIAL; goto repeat;
				case L'0': flags |= ZEROPAD; goto repeat;
				}

		/* get field width */
		field_width = -1;
		if (isxdigit(*fmt))
			field_width = skip_wtoi(&fmt);
		else if (*fmt == L'*') {
			++fmt;
			/* it's the next argument */
			field_width = va_arg(args, int);
			if (field_width < 0) {
				field_width = -field_width;
				flags |= LEFT;
			}
		}

		/* get the precision */
		precision = -1;
		if (*fmt == L'.') {
			++fmt;
			if (iswdigit(*fmt))
				precision = skip_wtoi(&fmt);
			else if (*fmt == L'*') {
				++fmt;
				/* it's the next argument */
				precision = va_arg(args, int);
			}
			if (precision < 0)
				precision = 0;
		}

		/* get the conversion qualifier */
		qualifier=0;
		// %Z can be just stand alone or as size_t qualifier
		if ( *fmt == 'Z' ) {
			qualifier = *fmt;
			switch ( *(fmt+1)) {
				case L'o':
				case L'b':
				case L'X':
				case L'x':
				case L'd':
				case L'i':
				case L'u':
					++fmt;
					break;
				default:
					break;
			}
		} else if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L' || *fmt == L'w') {
			qualifier = *fmt;
			++fmt;
		} else if (*fmt == L'I' && *(fmt+1) == L'6' && *(fmt+2) == L'4') {
			qualifier = *fmt;
			fmt += 3;
		}

		// go fine with ll instead of L
		if ( *fmt == L'l' ) {
			++fmt;
			qualifier = L'L';
		}

		/* default base */
		base = 10;

		switch (*fmt) {
		case L'c': /* finished */
			if (!(flags & LEFT))
				while (--field_width > 0)
				{
					if (putwc(L' ', f) == WEOF)
						return -1;
					done++;
				}
			if (qualifier == L'h')
			{
				if (putwc((wchar_t) va_arg(args, int), f) == WEOF)
					return -1;
			}
			else
			{
				if (putwc((wchar_t) va_arg(args, int), f) == WEOF)
					return -1;
			}
			done++;
			while (--field_width > 0)
			{
				if (putwc(L' ', f) == WEOF)
					return -1;
				done++;
			}
			continue;

		case L'C': /* finished */
			if (!(flags & LEFT))
				while (--field_width > 0)
				{
					if (putwc(L' ', f) == WEOF)
						return -1;
					done++;
				}
			if (qualifier == L'l' || qualifier == L'w')
			{
				if (putwc((unsigned char) va_arg(args, int), f) == WEOF)
					return -1;
			}
			else
			{
				if (putwc((unsigned char) va_arg(args, int), f) == WEOF)
					return -1;
			}
			done++;
			while (--field_width > 0)
			{
				if (putwc(L' ', f) == WEOF)
					return -1;
				done++;
			}
			continue;

		case L's': /* finished */
			if (qualifier == L'h') {
				/* print ascii string */
				s = va_arg(args, char *);
				result = string(f, s, -1, field_width, precision, flags);
			} else {
				/* print unicode string */
				sw = va_arg(args, wchar_t *);
				result = stringw(f, sw, -1, field_width, precision, flags);
			}
			if (result < 0)
				return -1;
			done += result;
			continue;

		case L'S':
			if (qualifier == L'l' || qualifier == L'w') {
				/* print unicode string */
				sw = va_arg(args, wchar_t *);
				result = stringw(f, sw, -1, field_width, precision, flags);
			} else {
				/* print ascii string */
				s = va_arg(args, char *);
				result = string(f, s, -1, field_width, precision, flags);
			}
			if (result < 0)
				return -1;
			done += result;
			continue;

		case L'Z': /* finished */
			if (qualifier == L'w') {
				/* print counted unicode string */
				PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
				if ((pus == NULL) || (pus->Buffer)) {
					sw = NULL;
					len = -1;
				} else {
					sw = pus->Buffer;
				}
				result = stringw(f, sw, len, field_width, precision, flags);
			} else {
				/* print counted ascii string */
				PANSI_STRING pus = va_arg(args, PANSI_STRING);
				if ((pus == NULL) || (pus->Buffer)) {
					s = NULL;
					len = -1;
				} else {
					s = pus->Buffer;
					len = pus->Length;
				}
				result = string(f, s, len, field_width, precision, flags);
			}
			if (result < 0)
				return -1;
			done += result;
			continue;

		case L'e': /* finished */
		case L'E':
		case L'f':
		case L'g':
		case L'G':
         _double = (double)va_arg(args, double);

         if ( _isnan(_double) ) {
            sw = L"Nan";
            len = 3;
            while ( len > 0 ) {
               if (putwc(*sw++,f) == WEOF)
                  return -1;
               done++;
               len --;
            }
         } else if ( _isinf(_double) < 0 ) {
            sw = L"-Inf";
            len = 4;
            while ( len > 0 ) {
               if (putwc(*sw++,f) == WEOF)
                  return -1;
               done++;
               len --;
            }
         } else if ( _isinf(_double) > 0 ) {
            sw = L"+Inf";
            len = 4;
            while ( len > 0 ) {
               if (putwc(*sw++,f) == WEOF)
                  return -1;
               done++;
               len --;
            }
         } else {
            if ( precision == -1 )
               precision = 6;
            result = numberf(f,_double,*fmt,field_width,precision,flags);
            if (result < 0)
               return -1;
            done += result;
         }
			continue;

		case L'p':
			if (field_width == -1) {
				field_width = 2*sizeof(void *);
				flags |= ZEROPAD;
			}
			result = number(f,
				        (unsigned long) va_arg(args, void *), 16,
					field_width, precision, flags);
			if (result < 0)
				return -1;
			done += result;
			continue;

		case L'n':
			if (qualifier == L'l') {
				long * ip = va_arg(args, long *);
				*ip = 0;
			} else {
				int * ip = va_arg(args, int *);
				*ip = 0;
			}
			continue;

		/* integer number formats - set up the flags and "break" */
		case L'o':
			base = 8;
			break;

		case L'b':
			base = 2;
			break;

		case L'X':
			flags |= LARGE;
		case L'x':
			base = 16;
			break;

		case L'd':
		case L'i':
			flags |= SIGN;
		case L'u':
			break;

		default:
			if (*fmt != L'%')
			{
				if (putwc(L'%', f) == WEOF)
					return -1;
				done++;
			}
			if (*fmt)
			{
				if (putwc(*fmt, f) == WEOF)
					return -1;
				done++;
			}
			else
				--fmt;
			continue;
		}

		if (qualifier == L'I')
			num = va_arg(args, ULONGLONG);
		else if (qualifier == L'l') {
			if (flags & SIGN)
				num = va_arg(args, long);
			else
				num = va_arg(args, unsigned long);
		}
		else if (qualifier == L'h') {
			if (flags & SIGN)
				num = va_arg(args, int);
			else
				num = va_arg(args, unsigned int);
		}
		else if (flags & SIGN)
			num = va_arg(args, int);
		else
			num = va_arg(args, unsigned int);
		result = number(f, num, base, field_width, precision, flags);
		if (result < 0)
			return -1;
		done += result;
	}
	//putwc(L'\0',f);
	return done;
}

/* EOF */

⌨️ 快捷键说明

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