📄 sio.c
字号:
#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':
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 + -