1 #include "config.h"
2 
3 #include "trace.h"
4 
5 #include "common.h"
6 #include "flog.h"
7 #include "parser.h"
8 
9 static const wcstring VAR_fish_trace = L"fish_trace";
10 
trace_enabled(const parser_t & parser)11 bool trace_enabled(const parser_t &parser) {
12     const auto &ld = parser.libdata();
13     if (ld.suppress_fish_trace) return false;
14     // TODO: this variable lookup is somewhat expensive, consider how to make this cheaper.
15     return !parser.vars().get(VAR_fish_trace).missing_or_empty();
16 }
17 
18 /// Trace an "argv": a list of arguments where the first is the command.
trace_argv(const parser_t & parser,const wchar_t * command,const wcstring_list_t & argv)19 void trace_argv(const parser_t &parser, const wchar_t *command, const wcstring_list_t &argv) {
20     // Format into a string to prevent interleaving with flog in other threads.
21     // Add the + prefix.
22     wcstring trace_text(parser.blocks().size() - 1, L'-');
23     trace_text.push_back(L'>');
24 
25     if (command && command[0]) {
26         trace_text.push_back(L' ');
27         trace_text.append(command);
28     }
29     for (const wcstring &arg : argv) {
30         trace_text.push_back(L' ');
31         trace_text.append(escape_string(arg, ESCAPE_ALL));
32     }
33     trace_text.push_back(L'\n');
34     log_extra_to_flog_file(trace_text);
35 }
36 
trace_if_enabled(const parser_t & parser,const wchar_t * command,const wcstring_list_t & argv)37 void trace_if_enabled(const parser_t &parser, const wchar_t *command, const wcstring_list_t &argv) {
38     if (trace_enabled(parser)) trace_argv(parser, command, argv);
39 }
40