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

📄 sio.c

📁 代码有点长,需细心阅读,仅供影音视听类产品的开发人员参考
💻 C
字号:
/*
** FILE
** sio.c
**
** DESCRIPTION
** Local standard string formatting function.
**
** NOTE:
** provide psprintf, an analog of sprintf.
*/

#include <stdarg.h>

/*
** TABLE
** radix_table
*/
static const char radix_table[] = "0123456789abcdefghijklmnopqrstuvwxyz";

#define	utoa(dest, num, base)	__ltoa__(dest, num, base, 0)
#define	dtoa(dest, num, base)	__ltoa__(dest, num, base, CONVERT_SIGN)

#define	CONVERT_SIGN		(1<<0)
#define	CONVERT_LONG		(1<<1)
#define	CONVERT_LONGLONG	(1<<2)
#define	CONVERT_WIDTH		(1<<3)
#define	CONVERT_LEADING_ZERO	(1<<4)
#define	CONVERT_LEFT_ADJUST	(1<<5)
#define	CONVERT_START		(1<<15)

/*
** Some definitions to help.
*/
#define	INT32	int
#define	INT64	long long
#define	UINT32	unsigned
#define	UINT64	unsigned long long

#include <stdio.h>

#include "sio.h"

typedef union
{
	INT64   i64;
	INT32   i32;
	UINT64  u64;
	UINT32  u32;
}
t_num;


/*
** FUNCTION
** __ltoa16__
** 
** DESCRIPTION
** Transform a number into base-16 string.
*/
static char *__ltoa16__(char *dest, t_num * X, unsigned conversion, int width)
{
	int     size = 0;
	char   *src, *src2;
	char    c;

	/* check long */
	if(conversion & CONVERT_LONGLONG)
	{
		UINT64  num = X->u64;

		/* generating bytes. */
		src = dest;
		do
		{
			int     frac;

			frac = (int)(num & 0x0f);
			num = num >> 4;
			src2 = dest;
			*dest++ = radix_table[frac];
			size++;
		} while(num);
	}
	else
	{
		UINT32  num = X->u32;

		/* generating bytes. */
		src = dest;
		do
		{
			int     frac;

			frac = (int)(num & 0x0f);
			num = num >> 4;
			src2 = dest;
			*dest++ = radix_table[frac];
			size++;
		} while(num);
	}

	/* Now fill leadings (or trailing) ZEROs or SPACEs */
	c = (conversion & CONVERT_LEADING_ZERO) ? '0' : ' ';
	while(width > size)
	{
		src2 = dest;
		*dest++ = c;
		size++;
	}

	/* reverse bytes */
	while(src < src2)
	{
		c = *src2;
		*src2 = *src;
		*src = c;
		src++;
		src2--;
	}
	return dest;
}


/*
** FUNCTION
** __ltoa__
**
** DESCRIPTION
** transform a number in base specified
*/
static char *__ltoa__(char *dest, t_num * X, unsigned base, int conversion,
											int width)
{
	int     size = 0;
	char   *src, *src2;
	char    c;

	/* check long */
	if(conversion & CONVERT_LONGLONG)
	{
		UINT64  num = X->u64;

		/* conversion sign */
		if(conversion & CONVERT_SIGN)
		{
			if(((INT64) num) < 0)
			{
				num = (UINT64) (-(INT64) num);
				*dest++ = '-';
				size++;
			}
		}
		/* generating bytes. */
		src = dest;
		do
		{
			int     frac;

			frac = num % base;
			num = num / base;
			src2 = dest;
			*dest++ = radix_table[frac];
			size++;
		} while(num);
	}
	else
	{
		UINT32  num = X->u32;

		/* conversion sign */
		if(conversion & CONVERT_SIGN)
		{
			if(((INT32) num) < 0)
			{
				num = (UINT32) (-(INT32) num);
				*dest++ = '-';
				size++;
			}
		}
		/* generating bytes. */
		src = dest;
		do
		{
			int     frac;

			frac = num % base;
			num = num / base;
			src2 = dest;
			*dest++ = radix_table[frac];
			size++;
		} while(num);
	}

	/* Now fill leadings (or trailing) ZEROs or SPACEs */
	c =
		((conversion & (CONVERT_LEADING_ZERO | CONVERT_LEFT_ADJUST)) ==
		 CONVERT_LEADING_ZERO) ? '0' : ' ';
	while(width > size)
	{
		if((conversion & CONVERT_LEFT_ADJUST) == 0)
			src2 = dest;
		*dest++ = c;
		size++;
	}

	/* reverse bytes */
	while(src < src2)
	{
		c = *src2;
		*src2 = *src;
		*src = c;
		src++;
		src2--;
	}
	return dest;
}


/*
** FUNCTION
** psprintf
**
** DESCRIPTION
** emulation of sprintf function
*/
int psprintf(char *dest, const char *format, ...)
{
	va_list ap;
	int     width = 0;
	unsigned conversion = 0;

	va_start(ap, format);

	while(1)
	{
		int     c = *format++;

		*dest = c;
		if(c == '\0')
			break;
		if(conversion & CONVERT_START)
		{
			if(c >= '0' && c <= '9')
			{
				if(width == 0 && c == '0')
				{
					conversion |= CONVERT_LEADING_ZERO;
				}
				else
				{
					conversion |= CONVERT_WIDTH;
					width = width * 10 + (c - '0');
				}
			}
			else if(c == 'l')
			{
				if(conversion & CONVERT_LONG)
					conversion |= CONVERT_LONGLONG;
				conversion |= CONVERT_LONG;
			}
			else if(c == '-')
			{
				conversion =
					(conversion & (~CONVERT_LEADING_ZERO)) | CONVERT_LEFT_ADJUST;
			}
			else
			{
				t_num   X;

				if(conversion & CONVERT_LONGLONG)
					X.u64 = va_arg(ap, UINT64);
				else
					X.u32 = va_arg(ap, UINT32);
				switch (c)
				{
					case 'd':
						dest = __ltoa__(dest, &X, 10, conversion, width);
						break;
					case 'u':
						dest = __ltoa__(dest, &X, 10, conversion, width);
						break;
					case 'x':
						dest = __ltoa16__(dest, &X, conversion, width);
						break;
					case 's':
					{
						char   *src = (char *)(X.u32);

						while(*src)
							*dest++ = *src++;
						break;
					}
					case 'c':
						*dest++ = (char)X.u32;
						break;
				}
				/* reset conversion */
				conversion = 0;
			}
		}
		else if(c == '%')
		{
			conversion = CONVERT_START;
			width = 0;
		}
		else
		{
			dest++;
		}
	}

	va_end(ap);
	return 0;
}


#ifdef	TEST
#include <stdio.h>
main()
{
	int     x = 123;
	long long AAA = 0x123456789abcd;
	char    fmt[128], buf[128];

	strcpy(fmt, "Pic %04x %c STC %llx %s %d");
	psprintf(buf, fmt, x, 'c', AAA, "SSXxz", 0);
	printf("[%s]\n[%s]\n", fmt, buf);

	strcpy(fmt, "\t\t\t\t\t\t\tPICEND %04x (%04x)\n");
	psprintf(buf, fmt, 25, 26);
	printf("[%s]\n[%s]\n\n", fmt, buf);

	strcpy(fmt, "<%x> <%4x> <%04x> <%-04x>");
	x = 0x123;
	psprintf(buf, fmt, x, x, x, x);
	printf("[%s]\n[%s]\n", fmt, buf);
}
#endif

⌨️ 快捷键说明

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