HV: cleanup sprintf&string.c MISRA-C issues

main focus on integral issues, and change some functions
interface to unify the params data type; also modify to
simplify the code logic.

Signed-off-by: Minggui Cao <minggui.cao@intel.com>
Reviewed-by: Yonghua Huang <yonghua.huang@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Minggui Cao 2018-07-24 09:25:22 +08:00 committed by lijinxia
parent 88f74b5dbb
commit 10ed599b50
4 changed files with 103 additions and 151 deletions

View File

@ -6,29 +6,24 @@
#include <hypervisor.h> #include <hypervisor.h>
static int charout(int cmd, const char *s, int32_t sz_arg, void *hnd) static int charout(int cmd, const char *s, uint32_t sz, void *hnd)
{ {
/* pointer to an integer to store the number of characters */ /* pointer to an integer to store the number of characters */
int *nchars = (int *)hnd; int *nchars = (int *)hnd;
/* working pointer */ /* working pointer */
const char *p = s; const char *p = s;
int32_t sz = sz_arg;
/* copy mode ? */ /* copy mode ? */
if (cmd == PRINT_CMD_COPY) { if (cmd == PRINT_CMD_COPY) {
/* copy all characters until NUL is found */ if (sz > 0U) { /* copy 'sz' characters */
if (sz < 0) {
s += console_puts(s);
} else { /* copy 'sz' characters */
s += console_write(s, sz); s += console_write(s, sz);
} }
*nchars += (s - p); *nchars += (s - p);
return *nchars;
} else { } else {
/* fill mode */ /* fill mode */
*nchars += sz; *nchars += sz;
while (sz != 0) { while (sz != 0U) {
(void)console_putc(*s); (void)console_putc(*s);
sz--; sz--;
} }

View File

@ -16,7 +16,7 @@
/* Structure used to parse parameters and variables to subroutines. */ /* Structure used to parse parameters and variables to subroutines. */
struct print_param { struct print_param {
/* A pointer to the function that is used to emit characters. */ /* A pointer to the function that is used to emit characters. */
int (*emit)(int, const char *, int, void *); int (*emit)(int, const char *, uint32_t, void *);
/* An opaque pointer that is passed as third argument to the emit /* An opaque pointer that is passed as third argument to the emit
* function. * function.
*/ */
@ -26,9 +26,9 @@ struct print_param {
/* A bitfield with the parsed format flags. */ /* A bitfield with the parsed format flags. */
uint32_t flags; uint32_t flags;
/* The parsed format width. */ /* The parsed format width. */
int width; uint32_t width;
/* The parsed format precision. */ /* The parsed format precision. */
int precision; uint32_t precision;
/* The bitmask for unsigned values. */ /* The bitmask for unsigned values. */
uint64_t mask; uint64_t mask;
/* A pointer to the preformated value. */ /* A pointer to the preformated value. */
@ -56,8 +56,7 @@ int do_print(const char *fmt, struct print_param *param,
* @return The number of bytes which would be written, even if the destination * @return The number of bytes which would be written, even if the destination
* is smaller. On error a negative number is returned. * is smaller. On error a negative number is returned.
*/ */
int vsnprintf(char *dst, size_t sz, const char *fmt, va_list args);
int vsnprintf(char *dst, int32_t sz_arg, const char *fmt, va_list args);
/** The well known snprintf() function. /** The well known snprintf() function.
* *

View File

@ -52,9 +52,9 @@ struct snprint_param {
/** The destination buffer. */ /** The destination buffer. */
char *dst; char *dst;
/** The size of the destination buffer. */ /** The size of the destination buffer. */
int sz; uint32_t sz;
/** Counter for written chars. */ /** Counter for written chars. */
int wrtn; uint32_t wrtn;
}; };
/** The characters to use for upper case hexadecimal conversion. /** The characters to use for upper case hexadecimal conversion.
@ -83,28 +83,22 @@ static const char lower_hex_digits[] = {
'a', 'b', 'c', 'd', 'e', 'f', 'x' 'a', 'b', 'c', 'd', 'e', 'f', 'x'
}; };
static const char *get_int(const char *s, int *x) static const char *get_param(const char *s, uint32_t *x)
{ {
int negative = 0; *x = 0U;
*x = 0;
/* evaluate leading '-' for negative numbers */ /* ignore '-' for negative numbers, it will be handled in flags*/
if (*s == '-') { if (*s == '-') {
negative = 1;
++s; ++s;
} }
/* parse uint32_teger */ /* parse uint32_teger */
while ((*s >= '0') && (*s <= '9')) { while ((*s >= '0') && (*s <= '9')) {
*x = (*x * 10) + (*s - '0'); char delta = *s - '0';
*x = *x * 10U + (uint32_t)delta;
s++; s++;
} }
/* apply sign to result */
if (negative != 0) {
*x = -*x;
}
return s; return s;
} }
@ -195,26 +189,21 @@ static int format_number(struct print_param *param)
/* effective width of the result */ /* effective width of the result */
uint32_t width; uint32_t width;
/* number of characters to insert for width (w) and precision (p) */ /* number of characters to insert for width (w) and precision (p) */
uint32_t p, w; uint32_t p = 0U, w = 0U;
/* the result */ /* the result */
int res; int res = 0;
/* initialize variables */ /* initialize variables */
p = 0U;
w = 0U;
res = 0;
width = param->vars.valuelen + param->vars.prefixlen; width = param->vars.valuelen + param->vars.prefixlen;
/* calculate additional characters for precision */ /* calculate additional characters for precision */
p = (uint32_t)(param->vars.precision); if (param->vars.precision > width) {
if (p > width) { p = param->vars.precision - width;
p = p - width;
} }
/* calculate additional characters for width */ /* calculate additional characters for width */
w = (uint32_t)(param->vars.width); if (param->vars.width > (width + p)) {
if (w > (width + p)) { w = param->vars.width - (width + p);
w = w - (width + p);
} }
/* handle case of right justification */ /* handle case of right justification */
@ -421,33 +410,25 @@ static int print_decimal(struct print_param *param, int64_t value)
static int print_string(struct print_param *param, const char *s) static int print_string(struct print_param *param, const char *s)
{ {
/* the length of the string (-1) if unknown */ /* the length of the string (-1) if unknown */
int len; uint32_t len;
/* the number of additional characters to insert to reach the required /* the number of additional characters to insert to reach the required
* width * width
*/ */
uint32_t w; uint32_t w = 0U;
/* the last result of the emit function */ /* the last result of the emit function */
int res; int res;
w = 0U; len = strnlen_s(s, PRINT_STRING_MAX_LEN);
len = -1;
/* we need the length of the string if either width or precision is
* given
*/
if ((param->vars.precision != 0)|| (param->vars.width != 0)) {
len = strnlen_s(s, PRINT_STRING_MAX_LEN);
}
/* precision gives the max. number of characters to emit. */ /* precision gives the max. number of characters to emit. */
if ((param->vars.precision != 0) && (len > param->vars.precision)) { if ((param->vars.precision != 0U) && (len > param->vars.precision)) {
len = param->vars.precision; len = param->vars.precision;
} }
/* calculate the number of additional characters to get the required /* calculate the number of additional characters to get the required
* width * width
*/ */
if (param->vars.width > 0 && param->vars.width > len) { if (param->vars.width > 0U && param->vars.width > len) {
w = param->vars.width - len; w = param->vars.width - len;
} }
@ -461,7 +442,6 @@ static int print_string(struct print_param *param, const char *s)
} }
} }
/* emit the string, return early if an error occurred */
res = param->emit(PRINT_CMD_COPY, s, len, param->data); res = param->emit(PRINT_CMD_COPY, s, len, param->data);
if (res < 0) { if (res < 0) {
return res; return res;
@ -527,14 +507,11 @@ int do_print(const char *fmt, struct print_param *param,
* - get the length modifier * - get the length modifier
*/ */
fmt = get_flags(fmt, &(param->vars.flags)); fmt = get_flags(fmt, &(param->vars.flags));
fmt = get_int(fmt, &(param->vars.width)); fmt = get_param(fmt, &(param->vars.width));
if (*fmt == '.') { if (*fmt == '.') {
fmt++; fmt++;
fmt = get_int(fmt, &(param->vars.precision)); fmt = get_param(fmt, &(param->vars.precision));
if (param->vars.precision < 0) {
param->vars.precision = 0;
}
} }
fmt = get_length_modifier(fmt, &(param->vars.flags), fmt = get_length_modifier(fmt, &(param->vars.flags),
@ -544,57 +521,61 @@ int do_print(const char *fmt, struct print_param *param,
/* a single '%'? => print out a single '%' */ /* a single '%'? => print out a single '%' */
if (ch == '%') { if (ch == '%') {
res = param->emit(PRINT_CMD_COPY, &ch, 1, res = param->emit(PRINT_CMD_COPY, &ch, 1U,
param->data); param->data);
} else if ((ch == 'd') || (ch == 'i')) { } else if ((ch == 'd') || (ch == 'i')) {
/* decimal number */ /* decimal number */
res = print_decimal(param, if ((param->vars.flags &
((param->vars.flags & PRINT_FLAG_LONG_LONG) != 0U) {
PRINT_FLAG_LONG_LONG) != 0U) ? res = print_decimal(param,
__builtin_va_arg(args, __builtin_va_arg(args, long));
long long) } else {
: (long long) res = print_decimal(param,
__builtin_va_arg(args, __builtin_va_arg(args, int));
int)); }
} }
/* unsigned decimal number */ /* unsigned decimal number */
else if (ch == 'u') { else if (ch == 'u') {
param->vars.flags |= PRINT_FLAG_UINT32; param->vars.flags |= PRINT_FLAG_UINT32;
res = print_decimal(param, if ((param->vars.flags &
((param->vars.flags & PRINT_FLAG_LONG_LONG) != 0U) {
PRINT_FLAG_LONG_LONG) != 0U) ? res = print_decimal(param,
__builtin_va_arg(args, (int64_t)__builtin_va_arg(args,
unsigned long long) uint64_t));
: (unsigned long long) } else {
__builtin_va_arg(args, res = print_decimal(param,
unsigned int)); (int64_t)__builtin_va_arg(args,
uint32_t));
}
} }
/* octal number */ /* octal number */
else if (ch == 'o') { else if (ch == 'o') {
res = print_pow2(param, if ((param->vars.flags &
((param->vars.flags & PRINT_FLAG_LONG_LONG) != 0U) {
PRINT_FLAG_LONG_LONG) != 0U) ? res = print_pow2(param,
__builtin_va_arg(args, __builtin_va_arg(args,
unsigned long long) uint64_t), 3U);
: (unsigned long long) } else {
res = print_pow2(param,
__builtin_va_arg(args, __builtin_va_arg(args,
uint32_t), uint32_t), 3U);
3U); }
} }
/* hexadecimal number */ /* hexadecimal number */
else if ((ch == 'X') || (ch == 'x')) { else if ((ch == 'X') || (ch == 'x')) {
if (ch == 'X') { if (ch == 'X') {
param->vars.flags |= PRINT_FLAG_UPPER; param->vars.flags |= PRINT_FLAG_UPPER;
} }
res = print_pow2(param, if ((param->vars.flags &
((param->vars.flags & PRINT_FLAG_LONG_LONG) != 0U) {
PRINT_FLAG_LONG_LONG) != 0U) ? res = print_pow2(param,
__builtin_va_arg(args, __builtin_va_arg(args,
unsigned long long) uint64_t), 4U);
: (unsigned long long) } else {
res = print_pow2(param,
__builtin_va_arg(args, __builtin_va_arg(args,
uint32_t), uint32_t), 4U);
4U); }
} }
/* string argument */ /* string argument */
else if (ch == 's') { else if (ch == 's') {
@ -635,28 +616,18 @@ int do_print(const char *fmt, struct print_param *param,
return res; return res;
} }
static int charmem(int cmd, const char *s, int sz, void *hnd) static int charmem(int cmd, const char *s, uint32_t sz, void *hnd)
{ {
/* pointer to the snprint parameter list */ /* pointer to the snprint parameter list */
struct snprint_param *param = (struct snprint_param *) hnd; struct snprint_param *param = (struct snprint_param *) hnd;
/* pointer to the destination */ /* pointer to the destination */
char *p = param->dst + param->wrtn; char *p = param->dst + param->wrtn;
/* characters actually written */ /* characters actually written */
int n = 0; uint32_t n = 0U;
/* copy mode ? */ /* copy mode ? */
if (cmd == PRINT_CMD_COPY) { if (cmd == PRINT_CMD_COPY) {
if (sz < 0) { if (sz > 0U) {
while ((*s) != '\0') {
if (n < (param->sz - param->wrtn)) {
*p = *s;
}
p++;
s++;
n++;
}
} else if (sz > 0) {
while (((*s) != '\0') && n < sz) { while (((*s) != '\0') && n < sz) {
if (n < (param->sz - param->wrtn)) { if (n < (param->sz - param->wrtn)) {
*p = *s; *p = *s;
@ -665,33 +636,26 @@ static int charmem(int cmd, const char *s, int sz, void *hnd)
s++; s++;
n++; n++;
} }
} else {
/* sz == 0, no copy needed. */
} }
param->wrtn += n; param->wrtn += n;
return n;
} }
/* fill mode */ /* fill mode */
else { else {
n = (sz < (param->sz - param->wrtn)) ? sz : 0; n = (sz < param->sz - param->wrtn) ? sz : 0U;
param->wrtn += sz; param->wrtn += sz;
(void)memset(p, *s, n); (void)memset(p, (uint8_t)*s, n);
} }
return n; return (int)n;
} }
int vsnprintf(char *dst, int32_t sz_arg, const char *fmt, va_list args) int vsnprintf(char *dst, size_t sz, const char *fmt, va_list args)
{ {
char c[1];
/* the result of this function */
int32_t sz = sz_arg;
int res = 0; int res = 0;
if (sz <= 0 || (dst == NULL)) { if (sz == 0U || (dst == NULL)) {
dst = c; return -1;
sz = 1;
} }
/* struct to store all necessary parameters */ /* struct to store all necessary parameters */
@ -722,7 +686,7 @@ int vsnprintf(char *dst, int32_t sz_arg, const char *fmt, va_list args)
} }
/* return the number of chars which would be written */ /* return the number of chars which would be written */
res = snparam.wrtn; res = (int)snparam.wrtn;
/* done */ /* done */
return res; return res;
@ -738,7 +702,7 @@ int snprintf(char *dest, int sz, const char *fmt, ...)
va_start(args, fmt); va_start(args, fmt);
/* execute the printf() */ /* execute the printf() */
res = vsnprintf(dest, sz, fmt, args); res = vsnprintf(dest, (size_t)sz, fmt, args);
/* destroy parameter list */ /* destroy parameter list */
va_end(args); va_end(args);

View File

@ -6,8 +6,8 @@
#include <hypervisor.h> #include <hypervisor.h>
#define ULONG_MAX ((uint64_t)(~0UL)) /* 0xFFFFFFFF */ #define ULONG_MAX ((uint64_t)(~0UL)) /* 0xFFFFFFFF */
#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */ #define LONG_MAX (ULONG_MAX >> 1U) /* 0x7FFFFFFF */
#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */ #define LONG_MIN (~LONG_MAX) /* 0x80000000 */
#define ISSPACE(c) ((c == ' ') || (c == '\t')) #define ISSPACE(c) ((c == ' ') || (c == '\t'))
@ -17,11 +17,10 @@
long strtol_deci(const char *nptr) long strtol_deci(const char *nptr)
{ {
const char *s = nptr; const char *s = nptr;
uint64_t acc;
char c; char c;
uint64_t cutoff; uint64_t acc, cutoff, cutlim;
int neg = 0, any, cutlim; int neg = 0, any;
int base = 10; uint64_t base = 10UL;
/* /*
* Skip white space and pick up leading +/- sign if any. * Skip white space and pick up leading +/- sign if any.
@ -30,6 +29,7 @@ long strtol_deci(const char *nptr)
c = *s; c = *s;
s++; s++;
} while (ISSPACE(c)); } while (ISSPACE(c));
if (c == '-') { if (c == '-') {
neg = 1; neg = 1;
c = *s; c = *s;
@ -58,41 +58,36 @@ long strtol_deci(const char *nptr)
* Set any if any `digits' consumed; make it negative to indicate * Set any if any `digits' consumed; make it negative to indicate
* overflow. * overflow.
*/ */
cutoff = (neg != 0) ? -(uint64_t)LONG_MIN : LONG_MAX; cutoff = (neg != 0) ? LONG_MIN : LONG_MAX;
cutlim = cutoff % (uint64_t)base; cutlim = cutoff % base;
cutoff /= (uint64_t)base; cutoff /= base;
acc = 0U; acc = 0UL;
any = 0; any = 0;
do {
if (c >= '0' && c <= '9') { while (c >= '0' && c <= '9') {
c -= '0'; c -= '0';
} else { if ((acc > cutoff) ||
break; (acc == cutoff && (uint64_t)c > cutlim)) {
}
if (c >= base) {
break;
}
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1; any = -1;
break;
} else { } else {
any = 1;
acc *= base; acc *= base;
acc += c; acc += c;
} }
c = *s; c = *s;
s++; s++;
} while (true); }
if (any < 0) { if (any < 0) {
acc = (neg != 0) ? LONG_MIN : LONG_MAX; acc = (neg != 0) ? LONG_MIN : LONG_MAX;
} else if (neg != 0) { } else if (neg != 0) {
acc = -acc; acc = ~acc + 1UL;
} else { } else {
/* There is no overflow and no leading '-' exists. In such case /* There is no overflow and no leading '-' exists. In such case
* acc already holds the right number. No action required. */ * acc already holds the right number. No action required. */
} }
return acc; return (long)acc;
} }
/* /*
@ -101,10 +96,10 @@ long strtol_deci(const char *nptr)
uint64_t strtoul_hex(const char *nptr) uint64_t strtoul_hex(const char *nptr)
{ {
const char *s = nptr; const char *s = nptr;
uint64_t acc;
char c; char c;
uint64_t cutoff; uint64_t acc, cutoff, cutlim;
int base = 16, any, cutlim; uint64_t base = 16UL;
int any;
/* /*
* See strtol for comments as to the logic used. * See strtol for comments as to the logic used.
@ -119,9 +114,9 @@ uint64_t strtoul_hex(const char *nptr)
s += 2; s += 2;
} }
cutoff = (uint64_t)ULONG_MAX / (uint64_t)base; cutoff = ULONG_MAX / base;
cutlim = (uint64_t)ULONG_MAX % (uint64_t)base; cutlim = ULONG_MAX % base;
acc = 0U; acc = 0UL;
any = 0; any = 0;
do { do {
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
@ -133,13 +128,12 @@ uint64_t strtoul_hex(const char *nptr)
} else { } else {
break; break;
} }
if (c >= base) {
break; if ((acc > cutoff) ||
} (acc == cutoff && (uint64_t)c > cutlim)) {
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1; any = -1;
break;
} else { } else {
any = 1;
acc *= base; acc *= base;
acc += c; acc += c;
} }
@ -148,7 +142,7 @@ uint64_t strtoul_hex(const char *nptr)
s++; s++;
} while (true); } while (true);
if (any <= 0) { if (any < 0) {
acc = ULONG_MAX; acc = ULONG_MAX;
} }
return acc; return acc;