1 Star 1 Fork 1

Honrun / printf

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
honrun_printf.c 14.17 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
// SPDX-License-Identifier: LGPL-2.1+
/*
* Tiny printf version for SPL
*
* Copied from:
* http://www.sparetimelabs.com/printfrevisited/printfrevisited.php
*
* Copyright (C) 2004,2008 Kustaa Nyholm
*/
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "honrun_printf.h"
int8_t cHonrunItoA(char *pcBuff, int64_t iValue, int8_t cBase, int8_t cWidthLimit, int8_t cLeadingZero, int8_t cLeft)
{
int64_t iDiv = 1;
int8_t cNumber = 0, cLength = 1, cENOB = 0;
/* 计算真实宽度 */
while ((iValue / iDiv) >= cBase)
{
iDiv *= cBase;
++cLength;
}
/* 右对齐 */
if(cLeft == 0)
{
/* 补充到最低宽度 */
while(cLength < cWidthLimit)
{
iDiv *= cBase;
++cLength;
}
}
/* 转换成 strings */
if(pcBuff != NULL)
{
while (iDiv != 0)
{
cNumber = iValue / iDiv;
/* 是否是无意义的 0 */
cENOB = (cNumber != 0) ? 1 : cENOB;
if(cENOB != 0)
{
*pcBuff++ = (cNumber > 9) ? ((cNumber - 10) + 'A') : (cNumber + '0');
}
/* 前导对齐 */
else
{
*pcBuff++ = (cLeadingZero != 0) ? '0' : ' ';
}
iValue %= iDiv;
iDiv /= cBase;
}
}
/* 左对齐 */
if(cLeft != 0)
{
/* 补充到最低宽度 */
while(cLength < cWidthLimit)
{
if(pcBuff != NULL)
{
*pcBuff++ = ' ';
}
++cLength;
}
}
return cLength;
}
int64_t iHonrunAtoI(char *pcBuff, int8_t cBase)
{
int64_t iValue = 0;
int8_t cNumber = 0;
char ch = 0;
if(pcBuff != NULL)
{
while((ch = *pcBuff++) != 0)
{
iValue *= cBase;
if((ch >= '0') && (ch <= '9'))
cNumber = ch - '0';
else if((ch >= 'A') && (ch <= 'Z'))
cNumber = ch - 'A' + 10;
else if((ch >= 'a') && (ch <= 'z'))
cNumber = ch - 'a' + 10;
iValue += cNumber;
}
}
return iValue;
}
static void out(struct printf_info *info, char c)
{
*info->bf++ = c;
}
static void out_dgt(struct printf_info *info, char dgt)
{
out(info, dgt + (dgt < 10 ? '0' : 'a' - 10));
info->zs = 1;
}
static void div_out(struct printf_info *info, unsigned long *num, unsigned long div)
{
unsigned char dgt = 0;
while (*num >= div) {
*num -= div;
dgt++;
}
if (info->zs || dgt > 0)
out_dgt(info, dgt);
}
int32_t honrunVprintfLength(const char *fmt, honrun_va_list va)
{
uint32_t uiValue = 0, uiLength = 0;
int8_t cBase = 0, cShort = 0, cLong = 0, cWidthLimit = 0, cLeadingZero = 0, cLeft = 0, cNegative = 0;
char ch = 0, *pcString = NULL;
while((ch = *fmt++) != 0)
{
if(ch == '%')
{
ch = *fmt++;
cBase = 0, cShort = 0, cLong = 0, cWidthLimit = 0, cLeft = 0, cNegative = 0;
/* 格式的前导 */
switch(ch)
{
case 'h' : cShort = 1; ch = *fmt++; break; /* 短整型 */
case 'l' : cLong = 1; ch = *fmt++; break; /* 长整型、 double */
case '-' : cLeft = 1; ch = *fmt++; break; /* 左对齐 */
default : break;
}
/* 格式的前导 */
cLeadingZero = (ch == '0') ? 1 : 0;
while((ch >= '0') && (ch <= '9'))
{
cWidthLimit = (cWidthLimit * 10) + (ch - '0');
ch = *fmt++;
}
switch(ch)
{
case '%' :
++uiLength;
break;
case 'c' :
__honrun_va_arg(va, uint32_t);
++uiLength;
break;
case 's' :
pcString = __honrun_va_arg(va, char *);
while (*pcString++ != 0)
{
++uiLength;
}
break;
case 'o' :
cBase = (cBase == 0) ? 8 : cBase;
/* 无符号 */
case 'i' :
case 'u' :
cBase = (cBase == 0) ? 10 : cBase;
/* 有符号 */
case 'd' :
cNegative = (cBase == 0) ? 1 : cNegative;
cBase = (cBase == 0) ? 10 : cBase;
/* 以16进制形式,输出指针的值 */
case 'p' :
cWidthLimit = (cBase == 0) ? (sizeof(uint32_t) * 2) : cWidthLimit;
case '#' :
if(cBase == 0)
{
uiLength += 2;
fmt += ((*fmt == 'x') || (*fmt == 'X')) ? 1 : 0;
}
case 'x' :
case 'X' :
cBase = (cBase == 0) ? 16 : cBase;
uiValue = __honrun_va_arg(va, uint32_t);
if(cNegative != 0)
{
if((int32_t)uiValue < 0)
{
++uiLength;
uiValue = 0 - (int32_t)uiValue;
}
}
uiLength += cHonrunItoA(NULL, uiValue, cBase, cWidthLimit, cLeadingZero, cLeft);
break;
default : return 0;
}
}
else
{
++uiLength;
}
}
return uiLength;
}
int32_t honrunVprintfString(printfTypeDef *ptypeHandle, const char *fmt, honrun_va_list va)
{
uint32_t uiValue = 0;
int8_t cBase = 0, cShort = 0, cLong = 0, cWidthLimit = 0, cLeadingZero = 0, cLeft = 0, cNegative = 0;
char cBuff[24] = {0}, ch = 0, *pcString = NULL;
/* 输出到指定缓存 */
if((ptypeHandle == NULL) || (ptypeHandle->cPutChar == NULL) || (ptypeHandle->cPutStrings == NULL))
{
return 1;
}
while((ch = *fmt++) != 0)
{
if(ch == '%')
{
ch = *fmt++;
cBase = 0, cShort = 0, cLong = 0, cWidthLimit = 0, cLeadingZero = 0, cLeft = 0, cNegative = 0;
/* 格式的前导 */
switch(ch)
{
case 'h' : cShort = 1; ch = *fmt++; break; /* 短整型 */
case 'l' : cLong = 1; ch = *fmt++; break; /* 长整型、 double */
case '-' : cLeft = 1; ch = *fmt++; break; /* 左对齐 */
default : break;
}
/* 格式的前导 */
cLeadingZero = (ch == '0') ? 1 : 0;
while((ch >= '0') && (ch <= '9'))
{
cWidthLimit = (cWidthLimit * 10) + (ch - '0');
ch = *fmt++;
}
switch(ch)
{
case '%' :
ptypeHandle->cPutChar(ptypeHandle, ch);
break;
case 'c' :
uiValue = __honrun_va_arg(va, uint32_t);
ptypeHandle->cPutChar(ptypeHandle, uiValue);
break;
case 's' :
pcString = __honrun_va_arg(va, char *);
ptypeHandle->cPutStrings(ptypeHandle, pcString);
break;
case 'o' :
cBase = (cBase == 0) ? 8 : cBase;
/* 无符号 */
case 'i' :
case 'u' :
cBase = (cBase == 0) ? 10 : cBase;
/* 有符号 */
case 'd' :
cNegative = (cBase == 0) ? 1 : cNegative;
cBase = (cBase == 0) ? 10 : cBase;
case '#' :
if(cBase == 0)
{
ptypeHandle->cPutStrings(ptypeHandle, "0x");
fmt += ((*fmt == 'x') || (*fmt == 'X')) ? 1 : 0;
}
/* 以16进制形式,输出指针的值 */
case 'p' :
cWidthLimit = (cBase == 0) ? (sizeof(uint32_t) * 2) : cWidthLimit;
cLeadingZero = (cBase == 0) ? 1 : cLeadingZero;
cLeft = (cBase == 0) ? 0 : cLeft;
case 'x' :
case 'X' :
cBase = (cBase == 0) ? 16 : cBase;
uiValue = __honrun_va_arg(va, uint32_t);
if(cNegative != 0)
{
if((int32_t)uiValue < 0)
{
ptypeHandle->cPutChar(ptypeHandle, '-');
uiValue = 0 - (int32_t)uiValue;
}
}
memset(cBuff, 0, sizeof(cBuff));
cHonrunItoA(cBuff, uiValue, cBase, cWidthLimit, cLeadingZero, cLeft);
ptypeHandle->cPutStrings(ptypeHandle, cBuff);
break;
default : return 1;
}
}
else
{
ptypeHandle->cPutChar(ptypeHandle, ch);
}
}
return 0;
}
static int honrunVprintf(struct printf_info *info, const char *fmt, honrun_va_list va)
{
char ch;
char *p;
unsigned long num;
char buf[12];
unsigned long div;
while ((ch = *(fmt++)))
{
if (ch != '%')
{
info->putc(info, ch);
}
else
{
int8_t lz = 0, islong = 0;
int width = 0;
ch = *(fmt++);
if (ch == '-')
ch = *(fmt++);
if (ch == '0')
{
ch = *(fmt++);
lz = 1;
}
if (ch >= '0' && ch <= '9')
{
width = 0;
while (ch >= '0' && ch <= '9')
{
width = (width * 10) + ch - '0';
ch = *fmt++;
}
}
if (ch == 'l')
{
ch = *(fmt++);
islong = 1;
}
info->bf = buf;
p = info->bf;
info->zs = 0;
switch (ch)
{
case '\0':
goto abort;
case 'u':
case 'd':
case 'i':
div = 1000000000;
if (islong)
{
num = __honrun_va_arg(va, unsigned long);
if (sizeof(long) > 4)
div *= div * 10;
}
else
{
num = __honrun_va_arg(va, unsigned int);
}
if (ch != 'u')
{
if (islong && (long)num < 0)
{
num = -(long)num;
out(info, '-');
}
else if (!islong && (int)num < 0)
{
num = -(int)num;
out(info, '-');
}
}
if (!num)
{
out_dgt(info, 0);
}
else
{
for (; div; div /= 10)
div_out(info, &num, div);
}
break;
case 'p':
islong = 1;
/* no break */
case 'x':
if (islong)
{
num = __honrun_va_arg(va, unsigned long);
div = 1UL << (sizeof(long) * 8 - 4);
}
else
{
num = __honrun_va_arg(va, unsigned int);
div = 0x10000000;
}
if (!num)
{
out_dgt(info, 0);
}
else
{
for (; div; div /= 0x10)
div_out(info, &num, div);
}
break;
case 'c':
out(info, (char)(__honrun_va_arg(va, int)));
break;
case 's':
p = __honrun_va_arg(va, char*);
break;
case '%':
out(info, '%');
default:
break;
}
*info->bf = 0;
info->bf = p;
while (*info->bf++ && width > 0)
width--;
while (width-- > 0)
info->putc(info, lz ? '0' : ' ');
if (p)
{
while ((ch = *p++))
info->putc(info, ch);
}
}
}
abort:
return 0;
}
/* 输出 单个字符 回调函数 */
int8_t cHonrunPutChar(struct printfStruct *ptypeHandle, char ch)
{
if(ptypeHandle->stringsHead != NULL)
{
*ptypeHandle->stringsNow++ = ch;
}
return 0;
}
/* 输出 多个字符 回调函数 */
int8_t cHonrunPutStrings(struct printfStruct *ptypeHandle, char *pcStrings)
{
if(ptypeHandle->stringsHead != NULL)
{
while(*pcStrings != 0)
{
*ptypeHandle->stringsNow++ = *pcStrings++;
}
}
return 0;
}
int32_t honrunSprintfString(const char *fmt, ...)
{
printfTypeDef typePrintf = {0};
honrun_va_list va;
int32_t iLength = 0;
char buff[256] = {0};
__honrun_va_start(va, fmt);
iLength = honrunVprintfLength(fmt, va);
__honrun_va_end(va);
printf("honrunSprintfLength iLength: %d\r\n", iLength);
typePrintf.cPutChar = cHonrunPutChar;
typePrintf.cPutStrings = cHonrunPutStrings;
typePrintf.stringsHead = buff;
typePrintf.stringsNow = buff;
__honrun_va_start(va, fmt);
honrunVprintfString(&typePrintf, fmt, va);
__honrun_va_end(va);
printf("honrunSprintfString buff: %s\r\n", typePrintf.stringsHead);
return iLength;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/honrun_he/printf.git
git@gitee.com:honrun_he/printf.git
honrun_he
printf
printf
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891