From: Linus Torvalds Date: Mon, 16 Dec 2024 18:26:53 +0000 (-0800) Subject: vsprintf: avoid nested switch statement on same variable X-Git-Tag: v6.14-rc1~221^2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=03d23941bf03eecd8560e40238decb1515f264f6;p=thirdparty%2Fkernel%2Flinux.git vsprintf: avoid nested switch statement on same variable Now that we have simplified the number format types, the top-level switch table can easily just handle all the remaining cases, and we don't need to have a case statement with a conditional on the same expression as the switch statement. We do want to fall through to the common 'number()' case, but that's trivially done by making the other case statements use 'continue' instead of 'break'. They are just looping back to the top, after all. Signed-off-by: Linus Torvalds --- diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 4ed9a37b5e168..befd0075113f4 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -2816,16 +2816,16 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) memcpy(str, old_fmt, copy); } str += read; - break; + continue; } case FORMAT_TYPE_WIDTH: set_field_width(&spec, va_arg(args, int)); - break; + continue; case FORMAT_TYPE_PRECISION: set_precision(&spec, va_arg(args, int)); - break; + continue; case FORMAT_TYPE_CHAR: { char c; @@ -2847,25 +2847,25 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) *str = ' '; ++str; } - break; + continue; } case FORMAT_TYPE_STR: str = string(str, end, va_arg(args, char *), spec); - break; + continue; case FORMAT_TYPE_PTR: str = pointer(fmt, str, end, va_arg(args, void *), spec); while (isalnum(*fmt)) fmt++; - break; + continue; case FORMAT_TYPE_PERCENT_CHAR: if (str < end) *str = '%'; ++str; - break; + continue; case FORMAT_TYPE_INVALID: /* @@ -2878,14 +2878,16 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) */ goto out; - default: - if (spec.type == FORMAT_TYPE_8BYTE) - num = va_arg(args, long long); - else - num = convert_num_spec(va_arg(args, int), spec); + case FORMAT_TYPE_8BYTE: + num = va_arg(args, long long); + break; - str = number(str, end, num, spec); + default: + num = convert_num_spec(va_arg(args, int), spec); + break; } + + str = number(str, end, num, spec); } out: @@ -3154,20 +3156,17 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) fmt++; break; + case FORMAT_TYPE_8BYTE: + save_arg(long long); + break; + case FORMAT_TYPE_1BYTE: + save_arg(char); + break; + case FORMAT_TYPE_2BYTE: + save_arg(short); + break; default: - switch (spec.type) { - case FORMAT_TYPE_8BYTE: - save_arg(long long); - break; - case FORMAT_TYPE_1BYTE: - save_arg(char); - break; - case FORMAT_TYPE_2BYTE: - save_arg(short); - break; - default: - save_arg(int); - } + save_arg(int); } } @@ -3235,6 +3234,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) while (*fmt) { const char *old_fmt = fmt; int read = format_decode(fmt, &spec); + unsigned long long num; fmt += read; @@ -3247,16 +3247,16 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) memcpy(str, old_fmt, copy); } str += read; - break; + continue; } case FORMAT_TYPE_WIDTH: set_field_width(&spec, get_arg(int)); - break; + continue; case FORMAT_TYPE_PRECISION: set_precision(&spec, get_arg(int)); - break; + continue; case FORMAT_TYPE_CHAR: { char c; @@ -3277,14 +3277,14 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) *str = ' '; ++str; } - break; + continue; } case FORMAT_TYPE_STR: { const char *str_arg = args; args += strlen(str_arg) + 1; str = string(str, end, (char *)str_arg, spec); - break; + continue; } case FORMAT_TYPE_PTR: { @@ -3319,38 +3319,33 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) while (isalnum(*fmt)) fmt++; - break; + continue; } case FORMAT_TYPE_PERCENT_CHAR: if (str < end) *str = '%'; ++str; - break; + continue; case FORMAT_TYPE_INVALID: goto out; - default: { - unsigned long long num; - - switch (spec.type) { - case FORMAT_TYPE_8BYTE: - num = get_arg(long long); - break; - case FORMAT_TYPE_2BYTE: - num = convert_num_spec(get_arg(short), spec); - break; - case FORMAT_TYPE_1BYTE: - num = convert_num_spec(get_arg(char), spec); - break; - default: - num = convert_num_spec(get_arg(int), spec); - } + case FORMAT_TYPE_8BYTE: + num = get_arg(long long); + break; + case FORMAT_TYPE_2BYTE: + num = convert_num_spec(get_arg(short), spec); + break; + case FORMAT_TYPE_1BYTE: + num = convert_num_spec(get_arg(char), spec); + break; + default: + num = convert_num_spec(get_arg(int), spec); + break; + } - str = number(str, end, num, spec); - } /* default: */ - } /* switch(spec.type) */ + str = number(str, end, num, spec); } /* while(*fmt) */ out: