
1. delete some junk files. 2. mqttclient added comments and updated to v1.0.2. 3. update README.md. 4. update the author's own server certificate. 5. minor changes to salof.
288 lines
8.0 KiB
C
288 lines
8.0 KiB
C
/*
|
|
* @Author: jiejie
|
|
* @Github: https://github.com/jiejieTop
|
|
* @Date: 2019-12-25 23:54:19
|
|
* @LastEditTime: 2020-02-25 08:12:02
|
|
* @Description: the code belongs to jiejie, please keep the author information and source code according to the license.
|
|
*/
|
|
#include "format.h"
|
|
#include "salof_defconfig.h"
|
|
|
|
#ifdef USE_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 _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 _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 _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 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;
|
|
}
|
|
_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;
|
|
_format_int(buf, &n, size, num, base, width, flags);
|
|
} else if (c == 's') {
|
|
s = va_arg(ap, char *);
|
|
if (!s)
|
|
s = "(null)";
|
|
_format_str(buf, &n, size, s, width, flags);
|
|
} else if (c == 'c') {
|
|
c = va_arg(ap, int);
|
|
_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
|
|
|
|
|