@@ -407,40 +407,34 @@ int num_to_str(char *buf, int size, unsigned long long num, unsigned int width)
407407 return len + width ;
408408}
409409
410- #define SIGN 1 /* unsigned/signed, must be 1 */
410+ #define SIGN 1 /* unsigned/signed */
411411#define LEFT 2 /* left justified */
412412#define PLUS 4 /* show plus */
413413#define SPACE 8 /* space if plus */
414414#define ZEROPAD 16 /* pad with zero, must be 16 == '0' - ' ' */
415415#define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */
416416#define SPECIAL 64 /* prefix hex with "0x", octal with "0" */
417417
418- static_assert (SIGN == 1 );
419418static_assert (ZEROPAD == ('0' - ' ' ));
420419static_assert (SMALL == ('a' ^ 'A' ));
421420
422421enum format_type {
423422 FORMAT_TYPE_NONE , /* Just a string part */
423+ FORMAT_TYPE_1BYTE = 1 , /* char/short/int are their own sizes */
424+ FORMAT_TYPE_2BYTE = 2 ,
425+ FORMAT_TYPE_8BYTE = 3 ,
426+ FORMAT_TYPE_4BYTE = 4 ,
424427 FORMAT_TYPE_WIDTH ,
425428 FORMAT_TYPE_PRECISION ,
426429 FORMAT_TYPE_CHAR ,
427430 FORMAT_TYPE_STR ,
428431 FORMAT_TYPE_PTR ,
429432 FORMAT_TYPE_PERCENT_CHAR ,
430433 FORMAT_TYPE_INVALID ,
431- FORMAT_TYPE_LONG_LONG ,
432- FORMAT_TYPE_ULONG ,
433- FORMAT_TYPE_LONG ,
434- FORMAT_TYPE_UBYTE ,
435- FORMAT_TYPE_BYTE ,
436- FORMAT_TYPE_USHORT ,
437- FORMAT_TYPE_SHORT ,
438- FORMAT_TYPE_UINT ,
439- FORMAT_TYPE_INT ,
440- FORMAT_TYPE_SIZE_T ,
441- FORMAT_TYPE_PTRDIFF
442434};
443435
436+ #define FORMAT_TYPE_SIZE (type ) (sizeof(type) <= 4 ? sizeof(type) : FORMAT_TYPE_8BYTE)
437+
444438struct printf_spec {
445439 unsigned int type :8 ; /* format_type enum */
446440 signed int field_width :24 ; /* width of output field */
@@ -2707,23 +2701,19 @@ int format_decode(const char *fmt, struct printf_spec *spec)
27072701 }
27082702
27092703 if (qualifier == 'L' )
2710- spec -> type = FORMAT_TYPE_LONG_LONG ;
2704+ spec -> type = FORMAT_TYPE_SIZE ( long long ) ;
27112705 else if (qualifier == 'l' ) {
2712- BUILD_BUG_ON (FORMAT_TYPE_ULONG + SIGN != FORMAT_TYPE_LONG );
2713- spec -> type = FORMAT_TYPE_ULONG + (spec -> flags & SIGN );
2706+ spec -> type = FORMAT_TYPE_SIZE (long );
27142707 } else if (qualifier == 'z' ) {
2715- spec -> type = FORMAT_TYPE_SIZE_T ;
2708+ spec -> type = FORMAT_TYPE_SIZE ( size_t ) ;
27162709 } else if (qualifier == 't' ) {
2717- spec -> type = FORMAT_TYPE_PTRDIFF ;
2710+ spec -> type = FORMAT_TYPE_SIZE ( ptrdiff_t ) ;
27182711 } else if (qualifier == 'H' ) {
2719- BUILD_BUG_ON (FORMAT_TYPE_UBYTE + SIGN != FORMAT_TYPE_BYTE );
2720- spec -> type = FORMAT_TYPE_UBYTE + (spec -> flags & SIGN );
2712+ spec -> type = FORMAT_TYPE_SIZE (char );
27212713 } else if (qualifier == 'h' ) {
2722- BUILD_BUG_ON (FORMAT_TYPE_USHORT + SIGN != FORMAT_TYPE_SHORT );
2723- spec -> type = FORMAT_TYPE_USHORT + (spec -> flags & SIGN );
2714+ spec -> type = FORMAT_TYPE_SIZE (short );
27242715 } else {
2725- BUILD_BUG_ON (FORMAT_TYPE_UINT + SIGN != FORMAT_TYPE_INT );
2726- spec -> type = FORMAT_TYPE_UINT + (spec -> flags & SIGN );
2716+ spec -> type = FORMAT_TYPE_SIZE (int );
27272717 }
27282718
27292719 return ++ fmt - start ;
@@ -2747,6 +2737,22 @@ set_precision(struct printf_spec *spec, int prec)
27472737 }
27482738}
27492739
2740+ /*
2741+ * Turn a 1/2/4-byte value into a 64-bit one for printing: truncate
2742+ * as necessary and deal with signedness.
2743+ *
2744+ * The 'spec.type' is the size of the value in bytes.
2745+ */
2746+ static unsigned long long convert_num_spec (unsigned int val , struct printf_spec spec )
2747+ {
2748+ unsigned int shift = 32 - spec .type * 8 ;
2749+
2750+ val <<= shift ;
2751+ if (!(spec .flags & SIGN ))
2752+ return val >> shift ;
2753+ return (int )val >> shift ;
2754+ }
2755+
27502756/**
27512757 * vsnprintf - Format a string and place it in a buffer
27522758 * @buf: The buffer to place the result into
@@ -2873,43 +2879,10 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
28732879 goto out ;
28742880
28752881 default :
2876- switch (spec .type ) {
2877- case FORMAT_TYPE_LONG_LONG :
2882+ if (spec .type == FORMAT_TYPE_8BYTE )
28782883 num = va_arg (args , long long );
2879- break ;
2880- case FORMAT_TYPE_ULONG :
2881- num = va_arg (args , unsigned long );
2882- break ;
2883- case FORMAT_TYPE_LONG :
2884- num = va_arg (args , long );
2885- break ;
2886- case FORMAT_TYPE_SIZE_T :
2887- if (spec .flags & SIGN )
2888- num = va_arg (args , ssize_t );
2889- else
2890- num = va_arg (args , size_t );
2891- break ;
2892- case FORMAT_TYPE_PTRDIFF :
2893- num = va_arg (args , ptrdiff_t );
2894- break ;
2895- case FORMAT_TYPE_UBYTE :
2896- num = (unsigned char ) va_arg (args , int );
2897- break ;
2898- case FORMAT_TYPE_BYTE :
2899- num = (signed char ) va_arg (args , int );
2900- break ;
2901- case FORMAT_TYPE_USHORT :
2902- num = (unsigned short ) va_arg (args , int );
2903- break ;
2904- case FORMAT_TYPE_SHORT :
2905- num = (short ) va_arg (args , int );
2906- break ;
2907- case FORMAT_TYPE_INT :
2908- num = (int ) va_arg (args , int );
2909- break ;
2910- default :
2911- num = va_arg (args , unsigned int );
2912- }
2884+ else
2885+ num = convert_num_spec (va_arg (args , int ), spec );
29132886
29142887 str = number (str , end , num , spec );
29152888 }
@@ -3183,26 +3156,13 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
31833156
31843157 default :
31853158 switch (spec .type ) {
3186-
3187- case FORMAT_TYPE_LONG_LONG :
3159+ case FORMAT_TYPE_8BYTE :
31883160 save_arg (long long ) ;
31893161 break ;
3190- case FORMAT_TYPE_ULONG :
3191- case FORMAT_TYPE_LONG :
3192- save_arg (unsigned long ) ;
3193- break ;
3194- case FORMAT_TYPE_SIZE_T :
3195- save_arg (size_t );
3196- break ;
3197- case FORMAT_TYPE_PTRDIFF :
3198- save_arg (ptrdiff_t );
3199- break ;
3200- case FORMAT_TYPE_UBYTE :
3201- case FORMAT_TYPE_BYTE :
3162+ case FORMAT_TYPE_1BYTE :
32023163 save_arg (char );
32033164 break ;
3204- case FORMAT_TYPE_USHORT :
3205- case FORMAT_TYPE_SHORT :
3165+ case FORMAT_TYPE_2BYTE :
32063166 save_arg (short );
32073167 break ;
32083168 default :
@@ -3375,37 +3335,17 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
33753335 unsigned long long num ;
33763336
33773337 switch (spec .type ) {
3378-
3379- case FORMAT_TYPE_LONG_LONG :
3338+ case FORMAT_TYPE_8BYTE :
33803339 num = get_arg (long long );
33813340 break ;
3382- case FORMAT_TYPE_ULONG :
3383- case FORMAT_TYPE_LONG :
3384- num = get_arg (unsigned long );
3385- break ;
3386- case FORMAT_TYPE_SIZE_T :
3387- num = get_arg (size_t );
3388- break ;
3389- case FORMAT_TYPE_PTRDIFF :
3390- num = get_arg (ptrdiff_t );
3391- break ;
3392- case FORMAT_TYPE_UBYTE :
3393- num = get_arg (unsigned char );
3394- break ;
3395- case FORMAT_TYPE_BYTE :
3396- num = get_arg (signed char );
3397- break ;
3398- case FORMAT_TYPE_USHORT :
3399- num = get_arg (unsigned short );
3400- break ;
3401- case FORMAT_TYPE_SHORT :
3402- num = get_arg (short );
3341+ case FORMAT_TYPE_2BYTE :
3342+ num = convert_num_spec (get_arg (short ), spec );
34033343 break ;
3404- case FORMAT_TYPE_UINT :
3405- num = get_arg (unsigned int );
3344+ case FORMAT_TYPE_1BYTE :
3345+ num = convert_num_spec ( get_arg (char ), spec );
34063346 break ;
34073347 default :
3408- num = get_arg (int );
3348+ num = convert_num_spec ( get_arg (int ), spec );
34093349 }
34103350
34113351 str = number (str , end , num , spec );
0 commit comments