123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*
- * @Author: jiejie
- * @Github: https://github.com/jiejieTop
- * @Date: 2019-12-25 23:54:19
- * @LastEditTime: 2020-06-17 15:23:09
- * @Description: the code belongs to jiejie, please keep the author insalof_formation and source code according to the license.
- */
- #include "format.h"
- #include "salof_defconfig.h"
- #ifdef SALOF_USING_LOG
- static int _get_atoi(const char **str)
- {
- int n;
- for (n = 0; is_digit(**str); (*str)++)
- n = n * 10 + **str - '0';
- return n;
- }
- static void _buff_put_char(char *buf, unsigned int *pos, unsigned int max, char c)
- {
- if (*pos < max)
- buf[(*pos)] = c;
- (*pos)++;
- }
- /**
- * Formats an integer number
- * buf - buffer to print into
- * len - current position in buffer
- * maxlen - last valid position in buf
- * num - number to print
- * base - it's base
- * width - how many spaces this should have; padding
- * flags - above F flags
- */
- static void _salof_format_int(char *buf, unsigned int *len, unsigned int maxlen,
- signed long long num, int base, int width, int flags)
- {
- char nbuf[64], sign = 0;
- char altb[8]; // small buf for sign and #
- int n = num;
- int npad; // number of pads
- char pchar = ' '; // padding character
- char *digits = "0123456789ABCDEF";
- char *ldigits = "0123456789abcdef";
- int i, j;
- if (base < 2 || base > 16)
- return;
- if (flags & F_SMALL) digits = ldigits;
- if (flags & F_LEFT) flags &= ~F_ZEROPAD;
- if ((flags & F_SIGNED) && num < 0) {
- n = -num;
- sign = '-';
- } else if (flags & F_PLUS) {
- sign = '+';
- } else if (flags & F_SPACE)
- sign = ' ';
- i = 0;
- do {
- nbuf[i++] = digits[n % base];
- n = n / base;
- } while (n > 0);
-
- j = 0;
- if (sign) altb[j++] = sign;
- if (flags & F_ALTERNATE) {
- if (base == 8 || base == 16) {
- altb[j++] = '0';
- if (base == 16)
- altb[j++] = (flags & F_SMALL) ? 'x' : 'X';
- }
- }
- altb[j] = 0;
- npad = width > i + j ? width - i - j : 0;
- if (width > i + j)
- npad = width - i - j;
- if (npad > 0 && ((flags & F_LEFT) == 0)) {
- if (flags & F_ZEROPAD) {
- for (j = 0; altb[j]; j++)
- _buff_put_char(buf, len, maxlen, altb[j]);
- altb[0] = 0;
- }
- while (npad-- > 0)
- _buff_put_char(buf, len, maxlen, (flags & F_ZEROPAD) ? '0' : ' ');
- }
- for (j = 0; altb[j]; j++)
- _buff_put_char(buf, len, maxlen, altb[j]);
- while (i-- > 0)
- _buff_put_char(buf, len, maxlen, nbuf[i]);
- if (npad > 0 && (flags & F_LEFT))
- while(npad-- > 0)
- _buff_put_char(buf, len, maxlen, pchar);
- }
- static void _salof_format_char(char *buf, unsigned int *pos, unsigned int max, char c,
- int width, int flags)
- {
- int npad = 0;
- if (width > 0) npad = width - 1;
- if (npad < 0) npad = 0;
- if (npad && ((flags & F_LEFT) == 0))
- while (npad-- > 0)
- _buff_put_char(buf, pos, max, ' ');
- _buff_put_char(buf, pos, max, c);
- if (npad && (flags & F_LEFT))
- while (npad-- > 0)
- _buff_put_char(buf, pos, max, ' ');
- }
- /**
- * strlen()
- */
- static unsigned int _str_len(char *s)
- {
- unsigned int i;
- for (i = 0; *s; i++, s++)
- ;
- return i;
- }
- static void _salof_format_str(char *buf, unsigned int *pos, unsigned int max, char *s,
- int width, int flags)
- {
- int npad = 0;
- if (width > 0) npad = width - _str_len(s);
- if (npad < 0) npad = 0;
- if (npad && ((flags & F_LEFT) == 0))
- while (npad-- > 0)
- _buff_put_char(buf, pos, max, ' ');
- while (*s)
- _buff_put_char(buf, pos, max, *s++);
- if (npad && (flags & F_LEFT))
- while (npad-- > 0)
- _buff_put_char(buf, pos, max, ' ');
- }
- /***********************************************************************************************************************/
- /**
- * Shrinked down, vsnprintf implementation.
- * This will not handle floating numbers (yet).
- */
- int salof_format_nstr(char *buf, unsigned int size, const char *fmt, va_list ap)
- {
- unsigned int n = 0;
- char c, *s;
- char state = 0;
- signed long long num;
- int base;
- int flags, width, precision, lflags;
- if (!buf) size = 0;
- for (;;) {
- c = *fmt++;
- if (state == S_DEFAULT) {
- if (c == '%') {
- state = S_FLAGS;
- flags = 0;
- } else {
- _buff_put_char(buf, &n, size, c);
- }
- } else if (state == S_FLAGS) {
- switch (c) {
- case '#': flags |= F_ALTERNATE; break;
- case '0': flags |= F_ZEROPAD; break;
- case '-': flags |= F_LEFT; break;
- case ' ': flags |= F_SPACE; break;
- case '+': flags |= F_PLUS; break;
- case '\'':
- case 'I' : break; // not yet used
- default: fmt--; width = 0; state = S_WIDTH;
- }
- } else if (state == S_WIDTH) {
- if (c == '*') {
- width = va_arg(ap, int);
- if (width < 0) {
- width = -width;
- flags |= F_LEFT;
- }
- } else if (is_digit(c) && c > '0') {
- fmt--;
- width = _get_atoi(&fmt);
- } else {
- fmt--;
- precision = -1;
- state = S_PRECIS;
- }
- } else if (state == S_PRECIS) {
- // Ignored for now, but skip it
- if (c == '.') {
- if (is_digit(*fmt))
- precision = _get_atoi(&fmt);
- else if (*fmt == '*')
- precision = va_arg(ap, int);
- precision = precision < 0 ? 0 : precision;
- } else
- fmt--;
- lflags = 0;
- state = S_LENGTH;
- } else if (state == S_LENGTH) {
- switch(c) {
- case 'h': lflags = lflags == L_CHAR ? L_SHORT : L_CHAR; break;
- case 'l': lflags = lflags == L_LONG ? L_LLONG : L_LONG; break;
- case 'L': lflags = L_DOUBLE; break;
- default: fmt--; state = S_CONV;
- }
- } else if (state == S_CONV) {
- if (c == 'd' || c == 'i' || c == 'o' || c == 'b' || c == 'u'
- || c == 'x' || c == 'X') {
- if (lflags == L_LONG)
- num = va_arg(ap, int);
- else if (lflags & (L_LLONG | L_DOUBLE))
- num = va_arg(ap, signed long long);
- else if (c == 'd' || c == 'i')
- num = va_arg(ap, int);
- else
- num = (unsigned int) va_arg(ap, int);
- base = 10;
- if (c == 'd' || c == 'i') {
- flags |= F_SIGNED;
- } else if (c == 'x' || c == 'X') {
- flags |= c == 'x' ? F_SMALL : 0;
- base = 16;
- } else if (c == 'o') {
- base = 8;
- } else if (c == 'b') {
- base = 2;
- }
- _salof_format_int(buf, &n, size, num, base, width, flags);
- } else if (c == 'p') {
- num = (size_t) va_arg(ap, void *);
- base = 16;
- flags |= F_SMALL | F_ALTERNATE;
- _salof_format_int(buf, &n, size, num, base, width, flags);
- } else if (c == 's') {
- s = va_arg(ap, char *);
- if (!s)
- s = "(null)";
- _salof_format_str(buf, &n, size, s, width, flags);
- } else if (c == 'c') {
- c = va_arg(ap, int);
- _salof_format_char(buf, &n, size, c, width, flags);
- } else if (c == '%') {
- _buff_put_char(buf, &n, size, c);
- } else {
- _buff_put_char(buf, &n, size, '%');
- _buff_put_char(buf, &n, size, c);
- }
- state = S_DEFAULT;
- }
- if (c == 0)
- break;
- }
- n--;
- if (n < size)
- buf[n] = 0;
- else if (size > 0)
- buf[size - 1] = 0;
- return n;
- }
- #endif
|