While I'm poking about in the bowels of printf, one significant problem I'm facing is figuring out where to store the argument size. FL_LONG isn't enough to distinguish %d, %ld and %lld, and we're out of flag bits!
But ingenuity provides a solution, and I realized that the FL_WIDTH, FL_PREC and FL_LONG bits are assigned in the order in which they are parsed. Once the width is seen, flags are not interpreted any more. Once the precision is seen, digits aren't part of the width any more. And once a long flag is seen, only format characters are valid. But... once FL_LONG is set, FL_WIDTH isn't used any more. So when we see the first l flag, we can set FL_LONG, clear FL_WIDTH, and then use FL_WIDTH for FL_LONGLONG. Yay! Problem solved! Except... Eventually we need a length in bytes. 2, 4 or 8. I have a COPYBIT macro with which I can do this failrly efficiently: #define COPYBIT(dst, dmask, src, smask) \ asm( "bst %2,%3" \ "\n bld %0,%1" \ : "=r" (dst) \ : "I" (ntz(dmask)), \ "r" (src), \ "I" (ntz(smask))) (I could replace that "I" constraint with "LPKC03C04C05C06C07" to express the limit more accurately, but I'm not going to bother; the assembler gives a better error message than the compiler anyway.) bytes = 0; COPYBIT(bytes,2,flags,FL_LONG) COPYBIT(bytes,4,flags,FL_LONGLONG); bytes += 2; However, there's something else I could use FL_WIDTH for. One useful property of ASCII is that 'x' == 'X' | 0x20. _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-libc-dev