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

📄 fakesnprintf.c

📁 功能强大的ftp服务器源代码
💻 C
字号:
/* * snprintf() / vsnprintf() re-implementation by Frank Denis <j@pureftpd.org> * * These functions understand : * - characters ("%c") . * - space padding ("%3d", "%-3s") . * - zero padding ("%04d") . * - explicit '+' ("%+d", "%+3.2f") . * - length restrictions ("%.30s", "%-42.30s", "%.4d") . * - int, long, long long types ("%lld", "%-3ld", "%i") . * - unsigned int, long, long long types ("%llu", "%-3lu", "%u") . * - hex and octal unsigned types ("%llX", "%04x", "%-3o") . * - double and long double types ("%f", "%Lf") . * - floating point frac restrictions ("%.2f") . * - combinations of everything ("%-8.5llo") . *  * Nothing more. Return value is <size> if an overflow occured, or the * copied size if no overflow occured (mostly compatible with C99 * snprintf() behavior, except that it doesn't return any value larger * than <size>). * * These functions are portable, they are twice faster than their BSD and GNU * implementations, and they don't tamper with errno. But they only know * a limited subset of what a full-implementation is supposed to do. * * It's enough for Pure-FTPd, though. */#include <config.h>#include "ftpd.h"#ifdef WITH_DMALLOC# include <dmalloc.h>#endif#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)/* * add a string to the buffer * \param zero if this is non-zero, we pad with zeroes, else we pad * with a blank. * \param maxlen sets the maximum size of the string to be added */static void fakesnprintf_addstr(char **str, size_t *size, const char *pnt,                                size_t maxlen, size_t padlen,                                unsigned char zero, unsigned char minuspad){    size_t maxlenc;    /* prepare to cut off string if longer than maxlen */    maxlenc = strlen(pnt);    if (maxlen > 0U && maxlen < maxlenc) {        maxlenc = maxlen;    }    if (padlen > 0U && minuspad == 0U && padlen > maxlenc) {        size_t maxlenp = padlen - maxlenc;        if (maxlenp > *size) {            maxlenp = *size;        }        if (maxlenp > 0U) {            memset(*str, zero != 0 ? '0' : ' ', maxlenp);            (*size) -= maxlenp;            (*str) += maxlenp;        }    }    if (maxlenc > *size) {        maxlenc = *size;    }    if (maxlenc > 0U) {        memcpy(*str, pnt, maxlenc);        (*size) -= maxlenc;        (*str) += maxlenc;    }    if (padlen > 0U && minuspad > 0U && padlen > maxlenc) {        size_t maxlenp = padlen - maxlenc;                if (maxlenp > *size) {            maxlenp = *size;        }        if (maxlenp > 0U) {            memset(*str, ' ', maxlenp);            (*size) -= maxlenp;            (*str) += maxlenp;        }    }}int fakesnprintf_vsnprintf(char * const str_, const size_t size_,                           const char *format, va_list va){    char *str;    size_t size;    size_t maxlen;    size_t padlen;        unsigned char longs;    unsigned char zero;    unsigned char minuspad;    unsigned char hasmaxlen;    unsigned char plussign;    str = str_;    size = size_;    str_[size_ - 1U] = 1;    while (size > 0U && *format != 0) {        if (*format != '%') {            *str++ = *format++;            size--;            continue;        }        longs = 0U;        zero = 0U;        minuspad = 0U;        maxlen = 0U;        padlen = 0U;        hasmaxlen = 0U;        plussign = 0U;                for (;;) {            breakpoint_nextspecial_inc:            format++;            breakpoint_nextspecial_noinc:            switch (*format) {            case 0:                goto breakpoint_end;            case '%':                *str++ = '%';                size--;                goto breakpoint_nextspecial_inc;	    case 'c': {		int val;				val = va_arg(va, int);		*str++ = (char) val;		size--;                goto breakpoint_nextspecial_inc;			    }            case 'l': case 'L':                longs++;                goto breakpoint_nextspecial_inc;            case '0':                zero++;                goto breakpoint_nextspecial_inc;            case '.':                format++;                hasmaxlen = 1U;                while ((unsigned char) *format >= '0' &&                        (unsigned char) *format <= '9') {                    maxlen *= 10U;                    maxlen += (*format - '0');                    format++;                }                goto breakpoint_nextspecial_noinc;            case '1': case '2': case '3': case '4': case '5':            case '6': case '7': case '8': case '9':                do {                    padlen *= 10U;                    padlen += *format - '0';                    format++;                } while ((unsigned char) *format >= '0' &&                          (unsigned char) *format <= '9');                goto breakpoint_nextspecial_noinc;            case '-':                minuspad++;                format++;                goto breakpoint_nextspecial_noinc;            case '+':                plussign++;                format++;                goto breakpoint_nextspecial_noinc;                            case 's': {                const char *pnt;                pnt = va_arg(va, const char *);                if (pnt == NULL) {                    pnt = "<NULL>";                }                fakesnprintf_addstr(&str, &size, pnt, maxlen, padlen,                                    zero, minuspad);                goto breakpoint_next;            }            case 'u': case 'o': case 'x': case 'X': {                unsigned long long val;                char vals[256];                char *valspnt = vals + sizeof vals;                const char *basics;                unsigned int base;                switch (longs) {                case 2:                    val = va_arg(va, unsigned long long);                    break;                case 1:                    val = (unsigned long long) va_arg(va, unsigned long);                    break;                default:                    val = (unsigned long long) va_arg(va, unsigned int);                }                basics = "0123456789abcdef";                switch (*format) {                case 'o':                    base = 8U;                    break;                case 'X':                    basics = "0123456789ABCDEF";                case 'x':                    base = 16U;                    break;                default:                    base = 10U;                }                *--valspnt = 0;                do {                    *--valspnt = basics[val % base];                    val /= base;                } while (valspnt != &vals[0] && val > 0ULL);                fakesnprintf_addstr(&str, &size, valspnt, maxlen, padlen,                                    zero, minuspad);                goto breakpoint_next;            }            case 'd': case 'i': {                long long val;                unsigned char minussign = 0U;                char vals[256];                char *valspnt = vals + sizeof vals;                switch (longs) {                case 2:                    val = va_arg(va, long long);                    break;                case 1:                    val = (long long) va_arg(va, long);                    break;                default:                    val = (long long) va_arg(va, int);                }                if (val < 0LL) {                    minussign++;                    val = -val;                }                *--valspnt = 0;                do {                    *--valspnt = "0123456789"[val % 10LL];                    val /= 10LL;                } while (valspnt != &vals[1] && val > 0LL);                if (minussign != 0) {                    *--valspnt = '-';                } else if (plussign != 0) {                    *--valspnt = '+';                }                fakesnprintf_addstr(&str, &size, valspnt, maxlen, padlen,                                    zero, minuspad);                goto breakpoint_next;            }            case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': {                unsigned int nfrac = 6U;                long double val;                unsigned long long vali;                unsigned char minussign = 0U;                char vals[512];                char *valspnt = vals + sizeof vals / 2U;                char *valsleft;                if (longs != 0) {                    val = va_arg(va, long double);                } else {                    val = va_arg(va, double);                }                if (val < 0.0L) {                    minussign++;                    val = -val;                }                vali = (unsigned long long) val;                do {                    *--valspnt = '0' + vali % 10ULL;                    vali /= 10ULL;                } while (valspnt != &vals[1] && vali > 0ULL);                if (minussign != 0) {                    *--valspnt = '-';                } else if (plussign != 0) {                    *--valspnt = '+';                }                valsleft = valspnt;                valspnt = vals + sizeof vals / 2U;                if (maxlen > (sizeof vals / 2U) - 3U) {                    nfrac = (sizeof vals / 2U) - 3U;                } else if (hasmaxlen != 0U) {                    nfrac = maxlen;                }                if (nfrac > 0U) {                    *valspnt++ = '.';                }                                while (nfrac > 0U) {                    nfrac--;                    val *= 10.0L;                    *valspnt++ = '0' + (((unsigned long long) val) % 10U);                }                *valspnt = 0;                fakesnprintf_addstr(&str, &size, valsleft, sizeof vals,                                    padlen, zero, minuspad);                goto breakpoint_next;            }            }        }        breakpoint_next:        format++;    }    breakpoint_end:    if (str_[size_ - 1U] != 1) {        str_[size_ - 1U] = 0;        return (int) size_;    }    *str = 0;    return (int) (size_ - size);}int fakesnprintf_snprintf(char * const str, const size_t size,                          const char * const format, ...){    int ret;    va_list va;    va_start(va, format);    ret = fakesnprintf_vsnprintf(str, size, format, va);    va_end(va);    return ret;}#endif                          /* !HAVE_SNPRINTF */

⌨️ 快捷键说明

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