> 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); > } >