mirror of
https://github.com/upx/upx
synced 2025-10-05 19:20:23 +08:00
Cleanup snprintf.cpp.
This commit is contained in:
parent
1aa2a6b054
commit
e1a8c932ee
219
src/snprintf.cpp
219
src/snprintf.cpp
|
@ -111,11 +111,12 @@
|
||||||
#define DP_F_UP (1 << 5)
|
#define DP_F_UP (1 << 5)
|
||||||
#define DP_F_UNSIGNED (1 << 6)
|
#define DP_F_UNSIGNED (1 << 6)
|
||||||
|
|
||||||
/* Conversion Flags */
|
/* Length modifier */
|
||||||
#define DP_C_SHORT 1
|
#define DP_C_CHAR 1
|
||||||
#define DP_C_LONG 2
|
#define DP_C_SHORT 2
|
||||||
#define DP_C_LDOUBLE 3
|
#define DP_C_LONG 3
|
||||||
#define DP_C_LLONG 4
|
#define DP_C_LLONG 4
|
||||||
|
#define DP_C_LDOUBLE 5
|
||||||
|
|
||||||
#define char_to_int(p) ((p) - '0')
|
#define char_to_int(p) ((p) - '0')
|
||||||
#undef MAX
|
#undef MAX
|
||||||
|
@ -131,34 +132,32 @@ __acc_static_forceinline void dopr_outch(char *buffer, size_t *currsize, size_t
|
||||||
*currsize += 1;
|
*currsize += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fmtstr(char *buffer, size_t *currsize, size_t maxsize, const char *value, int flags,
|
static void fmtstr(char *buffer, size_t *currsize, size_t maxsize, const char *strvalue, int strln,
|
||||||
int min, int max) {
|
int flags, int min, int max) {
|
||||||
int padlen, strln; /* amount to pad */
|
int padlen; /* amount to pad */
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_SNPRINTF
|
#ifdef DEBUG_SNPRINTF
|
||||||
printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
|
printf("fmtstr min=%d max=%d s=[%s]\n", min, max, strvalue);
|
||||||
#endif
|
#endif
|
||||||
if (value == NULL)
|
assert(strvalue != NULL);
|
||||||
value = "<NULL>";
|
|
||||||
strln = (int) strlen(value);
|
|
||||||
padlen = min - strln;
|
padlen = min - strln;
|
||||||
if (padlen < 0)
|
if (padlen < 0)
|
||||||
padlen = 0;
|
padlen = 0;
|
||||||
if (flags & DP_F_MINUS)
|
if (flags & DP_F_MINUS)
|
||||||
padlen = -padlen; /* Left Justify */
|
padlen = -padlen; /* Left Justify */
|
||||||
|
|
||||||
while (padlen > 0 && cnt < max) {
|
while (cnt < max && padlen > 0) {
|
||||||
dopr_outch(buffer, currsize, maxsize, ' ');
|
dopr_outch(buffer, currsize, maxsize, ' ');
|
||||||
--padlen;
|
--padlen;
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
while (*value && cnt < max) {
|
while (cnt < max && *strvalue) {
|
||||||
dopr_outch(buffer, currsize, maxsize, *value);
|
dopr_outch(buffer, currsize, maxsize, *strvalue);
|
||||||
++value;
|
++strvalue;
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
while (padlen < 0 && cnt < max) {
|
while (cnt < max && padlen < 0) {
|
||||||
dopr_outch(buffer, currsize, maxsize, ' ');
|
dopr_outch(buffer, currsize, maxsize, ' ');
|
||||||
++padlen;
|
++padlen;
|
||||||
++cnt;
|
++cnt;
|
||||||
|
@ -480,7 +479,6 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
#if !(NO_FLOAT)
|
#if !(NO_FLOAT)
|
||||||
LDOUBLE fvalue;
|
LDOUBLE fvalue;
|
||||||
#endif
|
#endif
|
||||||
const char *strvalue;
|
|
||||||
int min;
|
int min;
|
||||||
int max;
|
int max;
|
||||||
int state;
|
int state;
|
||||||
|
@ -494,6 +492,10 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
ch = *format++;
|
ch = *format++;
|
||||||
|
|
||||||
while (state != DP_S_DONE) {
|
while (state != DP_S_DONE) {
|
||||||
|
unsigned base;
|
||||||
|
const char *strvalue;
|
||||||
|
int strln;
|
||||||
|
|
||||||
if (ch == '\0')
|
if (ch == '\0')
|
||||||
state = DP_S_DONE;
|
state = DP_S_DONE;
|
||||||
|
|
||||||
|
@ -543,6 +545,8 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
} else {
|
} else {
|
||||||
state = DP_S_DOT;
|
state = DP_S_DOT;
|
||||||
}
|
}
|
||||||
|
assert(min > 0 - UPX_RSIZE_MAX_STR);
|
||||||
|
assert(min < UPX_RSIZE_MAX_STR);
|
||||||
break;
|
break;
|
||||||
case DP_S_DOT:
|
case DP_S_DOT:
|
||||||
if (ch == '.') {
|
if (ch == '.') {
|
||||||
|
@ -565,21 +569,39 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
} else {
|
} else {
|
||||||
state = DP_S_MOD;
|
state = DP_S_MOD;
|
||||||
}
|
}
|
||||||
|
assert(max > 0 - UPX_RSIZE_MAX_STR);
|
||||||
|
assert(max < UPX_RSIZE_MAX_STR);
|
||||||
break;
|
break;
|
||||||
case DP_S_MOD:
|
case DP_S_MOD:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'h':
|
case 'h':
|
||||||
cflags = DP_C_SHORT;
|
cflags = DP_C_SHORT;
|
||||||
ch = *format++;
|
ch = *format++;
|
||||||
|
if (ch == 'h') {
|
||||||
|
cflags = DP_C_CHAR;
|
||||||
|
ch = *format++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
cflags = DP_C_LONG;
|
cflags = DP_C_LONG;
|
||||||
ch = *format++;
|
ch = *format++;
|
||||||
if (ch == 'l') { /* It's a long long */
|
if (ch == 'l') {
|
||||||
cflags = DP_C_LLONG;
|
cflags = DP_C_LLONG;
|
||||||
ch = *format++;
|
ch = *format++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'j': // intmax_t
|
||||||
|
cflags = DP_C_LLONG;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case 'z': // size_t
|
||||||
|
cflags = sizeof(size_t) == sizeof(LLONG) ? DP_C_LLONG : 0;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case 't': // ptrdiff_t
|
||||||
|
cflags = sizeof(ptrdiff_t) == sizeof(LLONG) ? DP_C_LLONG : 0;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
cflags = DP_C_LDOUBLE;
|
cflags = DP_C_LDOUBLE;
|
||||||
ch = *format++;
|
ch = *format++;
|
||||||
|
@ -593,57 +615,99 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
if (cflags == DP_C_SHORT)
|
if (cflags == DP_C_CHAR)
|
||||||
value = va_arg(args, int);
|
value = (LLONG)(signed char) va_arg(args, int);
|
||||||
|
else if (cflags == DP_C_SHORT)
|
||||||
|
value = (LLONG)(short) va_arg(args, int);
|
||||||
else if (cflags == DP_C_LONG)
|
else if (cflags == DP_C_LONG)
|
||||||
value = va_arg(args, long int);
|
value = (LLONG) va_arg(args, long);
|
||||||
else if (cflags == DP_C_LLONG)
|
else if (cflags == DP_C_LLONG)
|
||||||
value = va_arg(args, LLONG);
|
value = (LLONG) va_arg(args, LLONG);
|
||||||
else
|
else
|
||||||
value = va_arg(args, int);
|
value = (LLONG) va_arg(args, int);
|
||||||
fmtint(buffer, &currsize, maxsize, value, 10, min, max, flags);
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
flags |= DP_F_UNSIGNED;
|
|
||||||
if (cflags == DP_C_SHORT)
|
|
||||||
value = va_arg(args, unsigned int);
|
|
||||||
else if (cflags == DP_C_LONG)
|
|
||||||
value = (long) va_arg(args, unsigned long int);
|
|
||||||
else if (cflags == DP_C_LLONG)
|
|
||||||
value = (LLONG) va_arg(args, ULLONG);
|
|
||||||
else
|
|
||||||
value = (long) va_arg(args, unsigned int);
|
|
||||||
fmtint(buffer, &currsize, maxsize, value, 8, min, max, flags);
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
flags |= DP_F_UNSIGNED;
|
|
||||||
if (cflags == DP_C_SHORT)
|
|
||||||
value = va_arg(args, unsigned int);
|
|
||||||
else if (cflags == DP_C_LONG)
|
|
||||||
value = (long) va_arg(args, unsigned long int);
|
|
||||||
else if (cflags == DP_C_LLONG)
|
|
||||||
value = (LLONG) va_arg(args, ULLONG);
|
|
||||||
else
|
|
||||||
value = (long) va_arg(args, unsigned int);
|
|
||||||
fmtint(buffer, &currsize, maxsize, value, 10, min, max, flags);
|
fmtint(buffer, &currsize, maxsize, value, 10, min, max, flags);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
flags |= DP_F_UP;
|
flags |= DP_F_UP;
|
||||||
|
/*fallthrough*/
|
||||||
case 'x':
|
case 'x':
|
||||||
|
base = 16;
|
||||||
|
l_fmtuint:
|
||||||
flags |= DP_F_UNSIGNED;
|
flags |= DP_F_UNSIGNED;
|
||||||
if (cflags == DP_C_SHORT)
|
if (cflags == DP_C_CHAR)
|
||||||
value = va_arg(args, unsigned int);
|
value = (ULLONG)(unsigned char) va_arg(args, unsigned);
|
||||||
|
else if (cflags == DP_C_SHORT)
|
||||||
|
value = (ULLONG)(unsigned short) va_arg(args, unsigned);
|
||||||
else if (cflags == DP_C_LONG)
|
else if (cflags == DP_C_LONG)
|
||||||
value = (long) va_arg(args, unsigned long int);
|
value = (ULLONG) va_arg(args, unsigned long);
|
||||||
else if (cflags == DP_C_LLONG)
|
else if (cflags == DP_C_LLONG)
|
||||||
value = (LLONG) va_arg(args, ULLONG);
|
value = (ULLONG) va_arg(args, ULLONG);
|
||||||
else
|
else
|
||||||
value = (long) va_arg(args, unsigned int);
|
value = (ULLONG) va_arg(args, unsigned);
|
||||||
fmtint(buffer, &currsize, maxsize, value, 16, min, max, flags);
|
fmtint(buffer, &currsize, maxsize, value, base, min, max, flags);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
base = 10;
|
||||||
|
goto l_fmtuint;
|
||||||
|
case 'o':
|
||||||
|
base = 8;
|
||||||
|
goto l_fmtuint;
|
||||||
|
case 'c':
|
||||||
|
// TODO: wint_t
|
||||||
|
dopr_outch(buffer, &currsize, maxsize, va_arg(args, int));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
// TODO: wchar_t
|
||||||
|
strvalue = va_arg(args, const char *);
|
||||||
|
if (!strvalue)
|
||||||
|
strvalue = "(NULL)";
|
||||||
|
strln = (int) strlen(strvalue);
|
||||||
|
if (max == -1)
|
||||||
|
max = strln;
|
||||||
|
if (min > 0 && max >= 0 && min > max)
|
||||||
|
max = min;
|
||||||
|
fmtstr(buffer, &currsize, maxsize, strvalue, strln, flags, min, max);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
strvalue = (const char *) va_arg(args, const void *);
|
||||||
|
fmtint(buffer, &currsize, maxsize, (LLONG)(upx_uintptr_t) strvalue, 16, min, max,
|
||||||
|
flags);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (cflags == DP_C_CHAR) {
|
||||||
|
signed char *num;
|
||||||
|
num = va_arg(args, signed char *);
|
||||||
|
assert(num != NULL);
|
||||||
|
*num = (signed char) currsize;
|
||||||
|
} else if (cflags == DP_C_SHORT) {
|
||||||
|
short *num;
|
||||||
|
num = va_arg(args, short *);
|
||||||
|
assert(num != NULL);
|
||||||
|
*num = (short) currsize;
|
||||||
|
} else if (cflags == DP_C_LONG) {
|
||||||
|
long *num;
|
||||||
|
num = va_arg(args, long *);
|
||||||
|
assert(num != NULL);
|
||||||
|
*num = (long) currsize;
|
||||||
|
} else if (cflags == DP_C_LLONG) {
|
||||||
|
LLONG *num;
|
||||||
|
num = va_arg(args, LLONG *);
|
||||||
|
assert(num != NULL);
|
||||||
|
*num = (LLONG) currsize;
|
||||||
|
} else {
|
||||||
|
int *num;
|
||||||
|
num = va_arg(args, int *);
|
||||||
|
assert(num != NULL);
|
||||||
|
*num = (int) currsize;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
dopr_outch(buffer, &currsize, maxsize, ch);
|
||||||
break;
|
break;
|
||||||
#if !(NO_FLOAT)
|
#if !(NO_FLOAT)
|
||||||
case 'F':
|
case 'F':
|
||||||
flags |= DP_F_UP;
|
flags |= DP_F_UP;
|
||||||
|
/*fallthrough*/
|
||||||
case 'f':
|
case 'f':
|
||||||
if (cflags == DP_C_LDOUBLE)
|
if (cflags == DP_C_LDOUBLE)
|
||||||
fvalue = va_arg(args, LDOUBLE);
|
fvalue = va_arg(args, LDOUBLE);
|
||||||
|
@ -654,6 +718,7 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
flags |= DP_F_UP;
|
flags |= DP_F_UP;
|
||||||
|
/*fallthrough*/
|
||||||
case 'e':
|
case 'e':
|
||||||
if (cflags == DP_C_LDOUBLE)
|
if (cflags == DP_C_LDOUBLE)
|
||||||
fvalue = va_arg(args, LDOUBLE);
|
fvalue = va_arg(args, LDOUBLE);
|
||||||
|
@ -662,6 +727,7 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
flags |= DP_F_UP;
|
flags |= DP_F_UP;
|
||||||
|
/*fallthrough*/
|
||||||
case 'g':
|
case 'g':
|
||||||
if (cflags == DP_C_LDOUBLE)
|
if (cflags == DP_C_LDOUBLE)
|
||||||
fvalue = va_arg(args, LDOUBLE);
|
fvalue = va_arg(args, LDOUBLE);
|
||||||
|
@ -680,46 +746,6 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
||||||
assert(0);
|
assert(0);
|
||||||
exit(255);
|
exit(255);
|
||||||
#endif /* !(NO_FLOAT) */
|
#endif /* !(NO_FLOAT) */
|
||||||
case 'c':
|
|
||||||
dopr_outch(buffer, &currsize, maxsize, va_arg(args, int));
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
strvalue = va_arg(args, const char *);
|
|
||||||
if (!strvalue)
|
|
||||||
strvalue = "(NULL)";
|
|
||||||
if (max == -1)
|
|
||||||
max = (int) strlen(strvalue);
|
|
||||||
if (min > 0 && max >= 0 && min > max)
|
|
||||||
max = min;
|
|
||||||
fmtstr(buffer, &currsize, maxsize, strvalue, flags, min, max);
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
strvalue = (const char *) va_arg(args, const void *);
|
|
||||||
fmtint(buffer, &currsize, maxsize, (LLONG)(upx_uintptr_t) strvalue, 16, min, max,
|
|
||||||
flags);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
if (cflags == DP_C_SHORT) {
|
|
||||||
short int *num;
|
|
||||||
num = va_arg(args, short int *);
|
|
||||||
*num = (short int) currsize;
|
|
||||||
} else if (cflags == DP_C_LONG) {
|
|
||||||
long int *num;
|
|
||||||
num = va_arg(args, long int *);
|
|
||||||
*num = (long int) currsize;
|
|
||||||
} else if (cflags == DP_C_LLONG) {
|
|
||||||
LLONG *num;
|
|
||||||
num = va_arg(args, LLONG *);
|
|
||||||
*num = (LLONG) currsize;
|
|
||||||
} else {
|
|
||||||
int *num;
|
|
||||||
num = va_arg(args, int *);
|
|
||||||
*num = (int) currsize;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
dopr_outch(buffer, &currsize, maxsize, ch);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* Unknown, skip */
|
/* Unknown, skip */
|
||||||
break;
|
break;
|
||||||
|
@ -783,7 +809,14 @@ int upx_vasprintf(char **ptr, const char *format, va_list ap) {
|
||||||
|
|
||||||
assert(ptr != NULL);
|
assert(ptr != NULL);
|
||||||
*ptr = NULL;
|
*ptr = NULL;
|
||||||
|
#if defined(va_copy)
|
||||||
|
va_list ap_copy;
|
||||||
|
va_copy(ap_copy, ap);
|
||||||
|
len = upx_vsnprintf(NULL, 0, format, ap_copy);
|
||||||
|
va_end(ap_copy);
|
||||||
|
#else
|
||||||
len = upx_vsnprintf(NULL, 0, format, ap);
|
len = upx_vsnprintf(NULL, 0, format, ap);
|
||||||
|
#endif
|
||||||
if (len >= 0) {
|
if (len >= 0) {
|
||||||
*ptr = (char *) malloc(len + 1);
|
*ptr = (char *) malloc(len + 1);
|
||||||
assert(*ptr != NULL);
|
assert(*ptr != NULL);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user