Re: [PATCH v2 2/3] lib/vsprintf: Add support for generic FOURCCs by extending %p4cc

From: Aditya Garg
Date: Fri Feb 21 2025 - 15:07:15 EST



> Does this look good now? Made orig a union.

Wait, it's messier. Maybe declare data type of val separately in each case?
>
> 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);
> }
>