nRF24 / RF24Log

A nice logging library for Arduino devices

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

add oct, bin, and hex format specifiers

2bndy5 opened this issue · comments

I'm picturing :

  • %o calls print(numb, OCT)
  • %x calls print(numb, HEX)
  • %b calls print(numb, BIN)
  • %d or %i already handle integers in decimal form, so we don't need use the print(numb, DEC). IIRC, I think Print::print(uint numb) actually defaults to calling print(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 %S implication about flash strings though. EDIT: I added a note about %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 new FormatSpecifier::length member
  • the first encountered l would assert bit 5 (0x20) of the new FormatSpecifier::length member (making it signify 32 bit-length)
  • the fist encountered h would assert bit 3 (0x10) of the new FormatSpecifier::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.