RobotLocomotion / drake

Model-based design and verification for robotics.
https://drake.mit.edu
Other
3.35k stars 1.27k forks source link

[common] Add fmt_debug_string polyfill #22150

Closed jwnimmer-tri closed 1 week ago

jwnimmer-tri commented 1 week ago

Towards #22078.


Sometimes we want to print or log a string. Imagine this function:

void DoFoo(const std::string& arg);

For logging, we might try:

void DoFoo(const std::string& arg) {
  if (condition) {
    drake::log()->warn("Suspicious arg = {}", arg);
  }
  ...
}

That would print e.g.

WARNING Suspicious arg = Hello, world!

However, we'll usually want to print the quoted string value, so that the user can see e.g. if they have training whitespace:

void DoFoo(const std::string& arg) {
  if (condition) {
    drake::log()->warn("Suspicious arg = \"{}\"", arg);
  }
  ...
}

That would print e.g.

WARNING Suspicious arg = "Hello, world!"

That's great! But what if the string itself has double quotes inside of it? The output would be confusing. Or, some strings might contain non-printable characters like 0x08, or awkwardly-printable characters like a tab (\t).

Format has a solution for that:

void DoFoo(const std::string& arg) {
  if (condition) {
    drake::log()->warn("Suspicious arg = {:?}", arg);
  }
  ...
}

The ? presentation type is the "debug string" format, which not only double-quotes the string but also converts non-printable characters into their \xNN hex code, so that the output is a string literal that can be pasted back into either C++ or Python.

Unfortunately, our Jammy copy of fmt is just slightly too old to contain this feature, so we need to polyfill it until we drop jammy.

void DoFoo(const std::string& arg) {
  if (condition) {
    drake::log()->warn("Suspicious arg = {}", fmt_debug_string(arg));
  }
  ...
}

This change is Reviewable

jwnimmer-tri commented 1 week ago

+@SeanCurtis-TRI for feature review, please. Low priority.