add oct, bin, and hex format specifiers
2bndy5 opened this issue · comments
I'm picturing :
%o
callsprint(numb, OCT)
%x
callsprint(numb, HEX)
%b
callsprint(numb, BIN)
%d
or%i
already handle integers in decimal form, so we don't need use theprint(numb, DEC)
. IIRC, I thinkPrint::print(uint numb)
actually defaults to callingprint(numb, DEC)
anyway.
I request this because RF24 lib makes use of %x
in printDetails()
, and we could use a %b
for the printPrettyDetails()
(concerning the auto-ack feature's status).
I was just asking myself if the library should support format specifiers but it looks like this is a nice to have feature which will make the logging easier for the developer.
I think we should create a list of supported formats and post it somewhere. Currently there is one specifier %S
which on avr
platform will read the string from FLASH. This must be also taken into account, especially by #5.
I have a list of supported specifiers here in the docs folder. Is that what you meant?
I left out the EDIT: I added a note about %S
implication about flash strings though.%S
being specific to AVR architecture.
I don't see a way to support fmt specifier like %02x
because all print()
methods don't support adding insignificant zeroes (with the exception of printing a double/float).
I guess we could implement this ourselves instead of solely relying on methods from the Print
class. I'm only mentioning this because RF24::printDetails()
uses %02x
to pad hex digits <= 15 with a zero.
Well I rolled my own logic for padding numbers on the refactor branch. I went further by re-using the new appendChar()
function to output the timestamp and arbitrary log levels (those without a domain) description.
I have other gimics working too, but this line:
RF24Log_log(07, vendorID, "%%%%This is level 0x%2x (0b%8b or%3l)%c", 07, 07, 07, '!');
outputs like
20243;Lvl 7;RF24LogExample;%%This is level 0x07 (0b00000111 or 7)!
I'm not padding the whole number for floats/doubles, but I am using the quantity (if provided) as the decimal places quantity. I'm not sure how much I like it for floats/doubles; I might remove the feature for floats/doubles because not specifying a quantity rounds the float/double to a whole number. EDIT the home-brewed printf parser now uses the printf-standard precision quantity to specify decimal places 😉
I also updated the supported specifiers page
Now that We've got a partially complete home-brewed printf specifier parsing working, do you think its a good idea to add alias specifiers? For example
%B
represents a boolean as "true" or "false".%A
represents a boolean as "enabled" or "disabled".
%A
is used to represent uppercase Hexadecimal floating point. However it looks like ostream
inherits a boolalpha
manipulator that represents booleans as "true" or "false". I don't see %B
reserved for any behavior...
I quickly abandoned the %B
idea to describe boolean values as a string when I realized the user could just use:
RF24Log_info(vendorId, "this option is %s.", (isEnabled ? "on" : "off"));
I'm still trying to find a better way of employing the h
, hh
, l
, ll
length modifier flags. I was able to consolidate the indication of these flags (including the u
specifier) using a single byte:
u
would assert the MSb (0x80) of the newFormatSpecifier::length
member- the first encountered
l
would assert bit 5 (0x20) of the newFormatSpecifier::length
member (making it signify 32 bit-length) - the fist encountered
h
would assert bit 3 (0x10) of the newFormatSpecifier::length
member (making it signify 16 bit-length) - the second encountered
l
would shift bit 5 to the left by 1 (making it signify 64 bit-length) - the second encountered
h
would shift bit 3 to the right by 1 (making it signify 8 bit-length)
I'm using bit shifting to avoid extra if
statements and accept erroneous user input (like %lhi
).
I'm currently fighting ambiguous calls to Print::print()
since the compiler gets confused when trying to assess what overloaded Print::print()
to call. So, the above list of implemented length modifiers hasn't been committed to the refactor branch yet. Keep in mind that not all platforms support ll
specifiers.