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

📄 sprintf.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
字号:
/*
 * File:    sprintf.c
 */


#if !defined(__SPRINTF_H__)
#include "sprintf.h"
#endif




/*---------------------  Static Definitions  ------------------------*/
enum PAD_ATTRIB {
    PAD_NONE = 0,
    PAD_RIGHT = 1,
    PAD_ZERO = 2
};

// enough for 32-bit integer
#define PRINT_BUF_LEN   12              // 1_signed + 10_digit + 1_EOS

/*---------------------  Static Types  ------------------------------*/

/*---------------------  Static Macros  -----------------------------*/

/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/

/*---------------------  Static Functions  --------------------------*/
static void s_vPrintChar(PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, CHAR c);
static INT s_iPrintStr(PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, PCSTR pszString, INT iWidth, UINT uPadAttr);
static INT s_iPrintInt(PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, INT iSgInt, INT iRadix, BOOL bSigned, INT iWidth, UINT uPadAttr, CHAR cDigitBase);

/*---------------------  Export Variables  --------------------------*/




//
// if output string buffer is not null, then put char into buffer
// if buffer is null, then output to output device
//
static void s_vPrintChar (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, CHAR c)
{
    if (ppszOutStr != NULL) {
        **ppszOutStr = c;
        ++(*ppszOutStr);
    }
    else if (pfnOutput != NULL) {
        pfnOutput(c);
    }
}


static INT s_iPrintStr (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, PCSTR pszString, INT iWidth, UINT uPadAttr)
{
    UINT    uCharCount = 0;
    UINT    uPadLen = 0;
    CHAR    cPadChar = ' ';


    if (iWidth > 0) {
        INT     iLen = 0;
        PCCHAR  pcChar;

        // count string length
        for (pcChar = pszString; *pcChar != '\0'; ++pcChar)
            ++iLen;
        // calculate length to pad
        if (iLen >= iWidth)
            uPadLen = 0;
        else
            uPadLen = iWidth - iLen;
        // decide pad space or zero
        if (uPadAttr & PAD_ZERO)
            cPadChar = '0';
    }

    // default is left padding, padding here
    if (!(uPadAttr & PAD_RIGHT)) {
        for (; uPadLen > 0; --uPadLen) {
            s_vPrintChar(ppszOutStr, pfnOutput, cPadChar);
            ++uCharCount;
        }
    }
    // just print the string
    for (; *pszString != '\0' ; ++pszString) {
        s_vPrintChar(ppszOutStr, pfnOutput, *pszString);
        ++uCharCount;
    }
    // if right padding, padding here
    for (; uPadLen > 0; --uPadLen) {
        s_vPrintChar(ppszOutStr, pfnOutput, cPadChar);
        ++uCharCount;
    }

    return uCharCount;
}


static INT s_iPrintInt (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, INT iSgInt, INT iRadix, BOOL bSigned, INT iWidth, UINT uPadAttr, CHAR cDigitBase)
{
    CHAR    aszPrintBuf[PRINT_BUF_LEN];
    PCHAR   pcResult;
    INT     iRemain;
    UINT    uPadCount = 0;
    BOOL    bNegative = FALSE;
    UINT    uUnsgInt = iSgInt;


    if (iSgInt == 0) {
        aszPrintBuf[0] = '0';
        aszPrintBuf[1] = '\0';
        return s_iPrintStr(ppszOutStr, pfnOutput, aszPrintBuf, iWidth, uPadAttr);
    }

    // check if negative or not
    if (bSigned && (iRadix == 10) && (iSgInt < 0)) {
        bNegative = TRUE;
        uUnsgInt = -iSgInt;
    }

    // point to the end of the print buffer
    pcResult = aszPrintBuf + PRINT_BUF_LEN - 1;
    *pcResult = '\0';

    while (uUnsgInt != 0) {
        iRemain = uUnsgInt % iRadix;
        if (iRemain >= 10)
            iRemain += cDigitBase - '0' - 10;
        --pcResult;
        *pcResult = iRemain + '0';
        uUnsgInt /= iRadix;
    }

    // if nagative, put minus sign
    if (bNegative) {
        if ((iWidth != 0) && (uPadAttr & PAD_ZERO)) {
            s_vPrintChar(ppszOutStr, pfnOutput, '-');
            ++uPadCount;
            --iWidth;
        }
        else {
            --pcResult;
            *pcResult = '-';
        }
    }

    return uPadCount + s_iPrintStr(ppszOutStr, pfnOutput, pcResult, iWidth, uPadAttr);
}


INT PRNT_iPrintFmt (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, PINT piVarg)
{
    INT     iWidth;
    UINT    uPadAttr;
    UINT    uCharCount = 0;
    PCHAR   pcFormat = (PSTR)(*(piVarg++));
    CHAR    aszChar[2];


    for (; *pcFormat != '\0'; ++pcFormat) {
        if (*pcFormat == '%') {
            ++pcFormat;
            iWidth = 0;
            uPadAttr = PAD_NONE;

            if (*pcFormat == '\0') {
                break;
            }
            if (*pcFormat == '%') {
                s_vPrintChar(ppszOutStr, pfnOutput, *pcFormat);
                ++uCharCount;
                continue;
            }

            if (*pcFormat == '-') {
                ++pcFormat;
                uPadAttr = PAD_RIGHT;
            }
            while (*pcFormat == '0') {
                ++pcFormat;
                uPadAttr |= PAD_ZERO;
            }
            for (; ('0' <= *pcFormat) && (*pcFormat <= '9'); ++pcFormat) {
                iWidth *= 10;
                iWidth += *pcFormat - '0';
            }

            if (*pcFormat == 'c') {
                aszChar[0] = *(piVarg++);
                aszChar[1] = '\0';
                uCharCount += s_iPrintStr(ppszOutStr, pfnOutput, aszChar, iWidth, uPadAttr);
                continue;
            }
            if (*pcFormat == 's') {
                PSTR pszStr = *((PSTR*)(piVarg++));
                uCharCount += s_iPrintStr(ppszOutStr, pfnOutput, (pszStr != NULL) ? pszStr : "(null)", iWidth, uPadAttr);
                continue;
            }
            if (*pcFormat == 'p') {
                iWidth = 8;
                uPadAttr |= PAD_ZERO;
                uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'a');
                continue;
            }
            if (*pcFormat == 'x') {
                uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'a');
                continue;
            }
            if (*pcFormat == 'X') {
                uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'A');
                continue;
            }
            if (*pcFormat == 'u') {
                uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, FALSE, iWidth, uPadAttr, 'a');
                continue;
            }
            if ((*pcFormat == 'd') || (*pcFormat == 'i')) {
                uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, TRUE, iWidth, uPadAttr, 'a');
                continue;
            }

            if (*pcFormat == 'l') {
                ++pcFormat;
                if (*pcFormat == 'x') {
                    uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'a');
                    continue;
                }
                if (*pcFormat == 'X') {
                    uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'A');
                    continue;
                }
                if (*pcFormat == 'u') {
                    uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, FALSE, iWidth, uPadAttr, 'a');
                    continue;
                }
                if ((*pcFormat == 'd') || (*pcFormat == 'i')) {
                    uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, TRUE, iWidth, uPadAttr, 'a');
                    continue;
                }
            }
        }
        else {
            s_vPrintChar(ppszOutStr, pfnOutput, *pcFormat);
            ++uCharCount;
        }
    }

    // finally, put a zero at the end of string
    if (ppszOutStr != NULL)
        **ppszOutStr = '\0';

    return uCharCount;
}


INT PRNT_iSprintf (PSTR pszBuffer, PCSTR pszFormat, ...)
{
    PSTR piVarg = (PSTR)&pszFormat;
    return PRNT_iPrintFmt(&pszBuffer, NULL, (PINT)piVarg);
}


⌨️ 快捷键说明

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