Perl script for de-obfuscating C++ error messages

If you've compiled C++, you've probably seen something like this:
std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, SystemData>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, SystemData> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, SystemData> > >::find(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const
If you stretched that out end-to-end, it would encircle the earth... Now, "true" C++ programmers will tell you that they filter all the junk out automatically and just see the basics of what's being said, i.e. something about a find routine. But if you're like me you don't do it that quickly. In fact, you probably waste valuable time wading through all those template parameters. There is nothing fancy about the script, and "true" Perl programmers will probably chuckle and do the same thing in a one-liner. But when I couldn't figure it out by myself, I thought a bunch of other people might not be able to figure it out either. So I posted it below:
#!/usr/bin/perl while(<>) { # Strip out all angled bracket pairs while (/[<>]/) { s/<[^<>]*>//g; } }
The result of the script is quite simple to understand:
_Rb_tree::find(basic_string const&) const
It's something about finding a string in a map of strings. Of course there's no such thing as a map of strings (maps are made up of pairs) but combined with the line numbers most compilers emit during error messages, it should clue you in that something about a map which you are using is messed up. Note that this message was emitted by the GCC compiler, which implements maps using red-black trees (_Rb_tree). Your compiler may say something different, but at least now you'll be able to strip out all the template parameters.
Thanks to the people who told me how to do this:
  • Wolfgang Bangerth
  • Bill Barth
  • Damien Warman




Update suggested by John Saalwaechter: The script above has two deficiencies:
  1. It has no print statement.
  2. It fails whenever pairs of angle brackets occur without a matched pair, e.g. std::cout << "Hello World.";
The following corrected version suggested by John Saalwaechter fixes the problem.
#!/usr/bin/perl while(<>) { 1 while s/<[^<>]*>//g; print; }