33
44#include  " utils/optional.hpp" 
55#include  " utils/utils.hpp" 
6+ #include  " utils/replace_all.hpp" 
67#include  " snippets/snippet.hpp" 
78
8- #include  < memory> 
99#include  < cstdio> 
1010#include  < string> 
1111#include  < functional> 
1212#include  < iostream> 
1313#include  < sstream> 
14+ #include  < regex> 
1415
1516CPPTRACE_BEGIN_NAMESPACE
17+     std::string basename (const  std::string& path) {
18+         return  internal::basename (path, true );
19+     }
20+ 
21+     std::string prettify_symbol (std::string symbol) {
22+         //  > > -> >> replacement
23+         //  could put in analysis:: but the replacement is basic and this is more convenient for
24+         //  using in the stringifier too
25+         internal::replace_all_dynamic (symbol, " > >" " >>" 
26+         //  "," -> ", " and " ," -> ", "
27+         static  const  std::regex comma_re (R"( \s*,\s*)" 
28+         internal::replace_all (symbol, comma_re, " , " 
29+         //  class C -> C for msvc
30+         static  const  std::regex class_re (R"( \b(class|struct)\s+)" 
31+         internal::replace_all (symbol, class_re, " " 
32+         //  `anonymous namespace' -> (anonymous namespace) for msvc
33+         //  this brings it in-line with other compilers and prevents any tokenization/highlighting issues
34+         static  const  std::regex msvc_anonymous_namespace (" `anonymous namespace'" 
35+         internal::replace_all (symbol, msvc_anonymous_namespace, " (anonymous namespace)" 
36+         //  rules to replace std::basic_string -> std::string and std::basic_string_view -> std::string
37+         //  rule to replace ", std::allocator<whatever>"
38+         static  const  std::pair<std::regex, std::string> basic_string = {
39+             std::regex (R"( std(::[a-zA-Z0-9_]+)?::basic_string<char)" " std::string" 
40+         };
41+         internal::replace_all_template (symbol, basic_string);
42+         static  const  std::pair<std::regex, std::string> basic_string_view = {
43+             std::regex (R"( std(::[a-zA-Z0-9_]+)?::basic_string_view<char)" " std::string_view" 
44+         };
45+         internal::replace_all_template (symbol, basic_string_view);
46+         static  const  std::pair<std::regex, std::string> allocator = {
47+             std::regex (R"( ,\s*std(::[a-zA-Z0-9_]+)?::allocator<)" " " 
48+         };
49+         internal::replace_all_template (symbol, allocator);
50+         static  const  std::pair<std::regex, std::string> default_delete = {
51+             std::regex (R"( ,\s*std(::[a-zA-Z0-9_]+)?::default_delete<)" " " 
52+         };
53+         internal::replace_all_template (symbol, default_delete);
54+         //  replace std::__cxx11 -> std:: for gcc dual abi
55+         //  https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
56+         internal::replace_all_dynamic (symbol, " std::__cxx11::" " std::" 
57+         return  symbol;
58+     }
59+ 
1660    class  formatter ::impl {
1761        struct  {
1862            std::string header = " Stack trace (most recent call first):" 
@@ -22,6 +66,7 @@ CPPTRACE_BEGIN_NAMESPACE
2266            bool  snippets = false ;
2367            int  context_lines = 2 ;
2468            bool  columns = true ;
69+             bool  prettify_symbols = false ;
2570            bool  show_filtered_frames = true ;
2671            std::function<bool (const  stacktrace_frame&)> filter;
2772            std::function<stacktrace_frame(stacktrace_frame)> transform;
@@ -49,6 +94,9 @@ CPPTRACE_BEGIN_NAMESPACE
4994        void  columns (bool  columns) {
5095            options.columns  = columns;
5196        }
97+         void  prettify_symbols (bool  prettify) {
98+             options.prettify_symbols  = prettify;
99+         }
52100        void  filtered_frame_placeholders (bool  show) {
53101            options.show_filtered_frames  = show;
54102        }
@@ -231,7 +279,10 @@ CPPTRACE_BEGIN_NAMESPACE
231279                microfmt::print (stream, " {}0x{>{}:0h}{} " 2  * sizeof (frame_ptr), address, reset);
232280            }
233281            if (!frame.symbol .empty ()) {
234-                 microfmt::print (stream, " in {}{}{}" symbol , reset);
282+                 microfmt::print (
283+                     stream, " in {}{}{}" 
284+                     yellow, options.prettify_symbols  ? prettify_symbol (frame.symbol ) : frame.symbol , reset
285+                 );
235286            }
236287            if (!frame.filename .empty ()) {
237288                microfmt::print (
@@ -302,6 +353,10 @@ CPPTRACE_BEGIN_NAMESPACE
302353        pimpl->columns (columns);
303354        return  *this ;
304355    }
356+     formatter& formatter::prettify_symbols (bool  prettify) {
357+         pimpl->prettify_symbols (prettify);
358+         return  *this ;
359+     }
305360    formatter& formatter::filtered_frame_placeholders (bool  show) {
306361        pimpl->filtered_frame_placeholders (show);
307362        return  *this ;
0 commit comments