in acpica/utprint.c [318:555]
int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
{
u8 base;
u8 type;
s32 width;
s32 precision;
char qualifier;
u64 number;
char *pos;
char *end;
char c;
const char *s;
const void *p;
s32 length;
int i;
pos = string;
if (size != ACPI_UINT32_MAX) {
end = string + size;
} else {
end = ACPI_CAST_PTR(char, ACPI_UINT32_MAX);
}
for (; *format; ++format) {
if (*format != '%') {
pos = acpi_ut_bound_string_output(pos, end, *format);
continue;
}
type = 0;
base = 10;
/* Process sign */
do {
++format;
if (*format == '#') {
type |= ACPI_FORMAT_PREFIX;
} else if (*format == '0') {
type |= ACPI_FORMAT_ZERO;
} else if (*format == '+') {
type |= ACPI_FORMAT_SIGN_PLUS;
} else if (*format == ' ') {
type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
} else if (*format == '-') {
type |= ACPI_FORMAT_LEFT;
} else {
break;
}
} while (1);
/* Process width */
width = -1;
if (isdigit((int)*format)) {
format = acpi_ut_scan_number(format, &number);
width = (s32)number;
} else if (*format == '*') {
++format;
width = va_arg(args, int);
if (width < 0) {
width = -width;
type |= ACPI_FORMAT_LEFT;
}
}
/* Process precision */
precision = -1;
if (*format == '.') {
++format;
if (isdigit((int)*format)) {
format = acpi_ut_scan_number(format, &number);
precision = (s32)number;
} else if (*format == '*') {
++format;
precision = va_arg(args, int);
}
if (precision < 0) {
precision = 0;
}
}
/* Process qualifier */
qualifier = -1;
if (*format == 'h' || *format == 'l' || *format == 'L') {
qualifier = *format;
++format;
if (qualifier == 'l' && *format == 'l') {
qualifier = 'L';
++format;
}
}
switch (*format) {
case '%':
pos = acpi_ut_bound_string_output(pos, end, '%');
continue;
case 'c':
if (!(type & ACPI_FORMAT_LEFT)) {
while (--width > 0) {
pos =
acpi_ut_bound_string_output(pos,
end,
' ');
}
}
c = (char)va_arg(args, int);
pos = acpi_ut_bound_string_output(pos, end, c);
while (--width > 0) {
pos =
acpi_ut_bound_string_output(pos, end, ' ');
}
continue;
case 's':
s = va_arg(args, char *);
if (!s) {
s = "<NULL>";
}
length = (s32)acpi_ut_bound_string_length(s, precision);
if (!(type & ACPI_FORMAT_LEFT)) {
while (length < width--) {
pos =
acpi_ut_bound_string_output(pos,
end,
' ');
}
}
for (i = 0; i < length; ++i) {
pos = acpi_ut_bound_string_output(pos, end, *s);
++s;
}
while (length < width--) {
pos =
acpi_ut_bound_string_output(pos, end, ' ');
}
continue;
case 'o':
base = 8;
break;
case 'X':
type |= ACPI_FORMAT_UPPER;
ACPI_FALLTHROUGH;
case 'x':
base = 16;
break;
case 'd':
case 'i':
type |= ACPI_FORMAT_SIGN;
case 'u':
break;
case 'p':
if (width == -1) {
width = 2 * sizeof(void *);
type |= ACPI_FORMAT_ZERO;
}
p = va_arg(args, void *);
pos =
acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
16, width, precision, type);
continue;
default:
pos = acpi_ut_bound_string_output(pos, end, '%');
if (*format) {
pos =
acpi_ut_bound_string_output(pos, end,
*format);
} else {
--format;
}
continue;
}
if (qualifier == 'L') {
number = va_arg(args, u64);
if (type & ACPI_FORMAT_SIGN) {
number = (s64)number;
}
} else if (qualifier == 'l') {
number = va_arg(args, unsigned long);
if (type & ACPI_FORMAT_SIGN) {
number = (s32)number;
}
} else if (qualifier == 'h') {
number = (u16)va_arg(args, int);
if (type & ACPI_FORMAT_SIGN) {
number = (s16)number;
}
} else {
number = va_arg(args, unsigned int);
if (type & ACPI_FORMAT_SIGN) {
number = (signed int)number;
}
}
pos = acpi_ut_format_number(pos, end, number, base,
width, precision, type);
}
if (size > 0) {
if (pos < end) {
*pos = '\0';
} else {
end[-1] = '\0';
}
}
return ((int)ACPI_PTR_DIFF(pos, string));
}