Skip to content

Commit 03d2394

Browse files
committed
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 <[email protected]>
1 parent be503db commit 03d2394

File tree

1 file changed

+47
-52
lines changed

1 file changed

+47
-52
lines changed

lib/vsprintf.c

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2816,16 +2816,16 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
28162816
memcpy(str, old_fmt, copy);
28172817
}
28182818
str += read;
2819-
break;
2819+
continue;
28202820
}
28212821

28222822
case FORMAT_TYPE_WIDTH:
28232823
set_field_width(&spec, va_arg(args, int));
2824-
break;
2824+
continue;
28252825

28262826
case FORMAT_TYPE_PRECISION:
28272827
set_precision(&spec, va_arg(args, int));
2828-
break;
2828+
continue;
28292829

28302830
case FORMAT_TYPE_CHAR: {
28312831
char c;
@@ -2847,25 +2847,25 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
28472847
*str = ' ';
28482848
++str;
28492849
}
2850-
break;
2850+
continue;
28512851
}
28522852

28532853
case FORMAT_TYPE_STR:
28542854
str = string(str, end, va_arg(args, char *), spec);
2855-
break;
2855+
continue;
28562856

28572857
case FORMAT_TYPE_PTR:
28582858
str = pointer(fmt, str, end, va_arg(args, void *),
28592859
spec);
28602860
while (isalnum(*fmt))
28612861
fmt++;
2862-
break;
2862+
continue;
28632863

28642864
case FORMAT_TYPE_PERCENT_CHAR:
28652865
if (str < end)
28662866
*str = '%';
28672867
++str;
2868-
break;
2868+
continue;
28692869

28702870
case FORMAT_TYPE_INVALID:
28712871
/*
@@ -2878,14 +2878,16 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
28782878
*/
28792879
goto out;
28802880

2881-
default:
2882-
if (spec.type == FORMAT_TYPE_8BYTE)
2883-
num = va_arg(args, long long);
2884-
else
2885-
num = convert_num_spec(va_arg(args, int), spec);
2881+
case FORMAT_TYPE_8BYTE:
2882+
num = va_arg(args, long long);
2883+
break;
28862884

2887-
str = number(str, end, num, spec);
2885+
default:
2886+
num = convert_num_spec(va_arg(args, int), spec);
2887+
break;
28882888
}
2889+
2890+
str = number(str, end, num, spec);
28892891
}
28902892

28912893
out:
@@ -3154,20 +3156,17 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
31543156
fmt++;
31553157
break;
31563158

3159+
case FORMAT_TYPE_8BYTE:
3160+
save_arg(long long);
3161+
break;
3162+
case FORMAT_TYPE_1BYTE:
3163+
save_arg(char);
3164+
break;
3165+
case FORMAT_TYPE_2BYTE:
3166+
save_arg(short);
3167+
break;
31573168
default:
3158-
switch (spec.type) {
3159-
case FORMAT_TYPE_8BYTE:
3160-
save_arg(long long);
3161-
break;
3162-
case FORMAT_TYPE_1BYTE:
3163-
save_arg(char);
3164-
break;
3165-
case FORMAT_TYPE_2BYTE:
3166-
save_arg(short);
3167-
break;
3168-
default:
3169-
save_arg(int);
3170-
}
3169+
save_arg(int);
31713170
}
31723171
}
31733172

@@ -3235,6 +3234,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
32353234
while (*fmt) {
32363235
const char *old_fmt = fmt;
32373236
int read = format_decode(fmt, &spec);
3237+
unsigned long long num;
32383238

32393239
fmt += read;
32403240

@@ -3247,16 +3247,16 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
32473247
memcpy(str, old_fmt, copy);
32483248
}
32493249
str += read;
3250-
break;
3250+
continue;
32513251
}
32523252

32533253
case FORMAT_TYPE_WIDTH:
32543254
set_field_width(&spec, get_arg(int));
3255-
break;
3255+
continue;
32563256

32573257
case FORMAT_TYPE_PRECISION:
32583258
set_precision(&spec, get_arg(int));
3259-
break;
3259+
continue;
32603260

32613261
case FORMAT_TYPE_CHAR: {
32623262
char c;
@@ -3277,14 +3277,14 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
32773277
*str = ' ';
32783278
++str;
32793279
}
3280-
break;
3280+
continue;
32813281
}
32823282

32833283
case FORMAT_TYPE_STR: {
32843284
const char *str_arg = args;
32853285
args += strlen(str_arg) + 1;
32863286
str = string(str, end, (char *)str_arg, spec);
3287-
break;
3287+
continue;
32883288
}
32893289

32903290
case FORMAT_TYPE_PTR: {
@@ -3319,38 +3319,33 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
33193319

33203320
while (isalnum(*fmt))
33213321
fmt++;
3322-
break;
3322+
continue;
33233323
}
33243324

33253325
case FORMAT_TYPE_PERCENT_CHAR:
33263326
if (str < end)
33273327
*str = '%';
33283328
++str;
3329-
break;
3329+
continue;
33303330

33313331
case FORMAT_TYPE_INVALID:
33323332
goto out;
33333333

3334-
default: {
3335-
unsigned long long num;
3336-
3337-
switch (spec.type) {
3338-
case FORMAT_TYPE_8BYTE:
3339-
num = get_arg(long long);
3340-
break;
3341-
case FORMAT_TYPE_2BYTE:
3342-
num = convert_num_spec(get_arg(short), spec);
3343-
break;
3344-
case FORMAT_TYPE_1BYTE:
3345-
num = convert_num_spec(get_arg(char), spec);
3346-
break;
3347-
default:
3348-
num = convert_num_spec(get_arg(int), spec);
3349-
}
3334+
case FORMAT_TYPE_8BYTE:
3335+
num = get_arg(long long);
3336+
break;
3337+
case FORMAT_TYPE_2BYTE:
3338+
num = convert_num_spec(get_arg(short), spec);
3339+
break;
3340+
case FORMAT_TYPE_1BYTE:
3341+
num = convert_num_spec(get_arg(char), spec);
3342+
break;
3343+
default:
3344+
num = convert_num_spec(get_arg(int), spec);
3345+
break;
3346+
}
33503347

3351-
str = number(str, end, num, spec);
3352-
} /* default: */
3353-
} /* switch(spec.type) */
3348+
str = number(str, end, num, spec);
33543349
} /* while(*fmt) */
33553350

33563351
out:

0 commit comments

Comments
 (0)