> On 21 Feb 2025, at 8:57 PM, andriy.shevchenko@xxxxxxxxxxxxxxx wrote: > > On Thu, Feb 20, 2025 at 04:39:23PM +0000, Aditya Garg wrote: >> From: Hector Martin <marcan@xxxxxxxxx> >> >> %p4cc is designed for DRM/V4L2 FOURCCs with their specific quirks, but >> it's useful to be able to print generic 4-character codes formatted as >> an integer. Extend it to add format specifiers for printing generic >> 32-bit FOURCCs with various endian semantics: >> >> %p4ch Host-endian >> %p4cl Little-endian >> %p4cb Big-endian >> %p4cr Reverse-endian >> >> The endianness determines how bytes are interpreted as a u32, and the >> FOURCC is then always printed MSByte-first (this is the opposite of >> V4L/DRM FOURCCs). This covers most practical cases, e.g. %p4cr would >> allow printing LSByte-first FOURCCs stored in host endian order >> (other than the hex form being in character order, not the integer >> value). > > ... > >> orig = get_unaligned(fourcc); >> - val = orig & ~BIT(31); >> + switch (fmt[2]) { >> + case 'h': >> + val = orig; >> + break; >> + case 'r': >> + orig = swab32(orig); >> + val = orig; >> + break; >> + case 'l': > >> + orig = le32_to_cpu(orig); >> + val = orig; >> + break; >> + case 'b': >> + orig = be32_to_cpu(orig); > > I do not see that orig is a union of different types. Have you run sparse? > It will definitely complain on this code. Does this look good now? Made orig a union. char *fourcc_string(char *buf, char *end, const u32 *fourcc, const char *fmt, struct printf_spec spec) { char output[sizeof("0123 little-endian (0x01234567)")]; char *p = output; unsigned int i; bool pixel_fmt = false; u32 val; union { u32 raw; __le32 le; __be32 be; } orig; if (fmt[1] != 'c') return error_string(buf, end, "(%p4?)", spec); if (check_pointer(&buf, end, fourcc, spec)) return buf; orig.raw = get_unaligned(fourcc); switch (fmt[2]) { case 'h': val = orig.raw; break; case 'r': val = swab32(orig.raw); break; case 'l': val = le32_to_cpu(orig.le); break; case 'b': val = be32_to_cpu(orig.be); break; case 'c': val = swab32(orig.raw & ~BIT(31)); pixel_fmt = true; break; default: return error_string(buf, end, "(%p4?)", spec); } for (i = 0; i < sizeof(u32); i++) { unsigned char c = val >> ((3 - i) * 8); *p++ = isascii(c) && isprint(c) ? c : '.'; } if (pixel_fmt) { *p++ = ' '; strcpy(p, orig.raw & BIT(31) ? "big-endian" : "little-endian"); p += strlen(p); } *p++ = ' '; *p++ = '('; p += sprintf(p, "0x%08x", orig.raw); *p++ = ')'; *p = '\0'; return string_nocheck(buf, end, output, spec); }