aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSasha Smundak <asmundak@google.com>2022-10-31 12:47:09 -0700
committerSasha Smundak <asmundak@google.com>2022-10-31 12:47:09 -0700
commit7749f2a01f2e83bb8bc1353b22db9919be28b9ee (patch)
tree7a62ab24c367dfd5026c7de9f48345d87072a7bb
parent09dfa26c4e59b15919aaad6986f9b47c883dc4f1 (diff)
downloadkati-7749f2a01f2e83bb8bc1353b22db9919be28b9ee.tar.gz
Add --variable_assignment_trace_filter option
In addition, write assignment event to the trace file.
-rw-r--r--src/eval.cc82
-rw-r--r--src/eval.h6
-rw-r--r--src/flags.cc14
-rw-r--r--src/flags.h2
-rw-r--r--src/strutil.cc3
5 files changed, 80 insertions, 27 deletions
diff --git a/src/eval.cc b/src/eval.cc
index 7f9dc6f..637f373 100644
--- a/src/eval.cc
+++ b/src/eval.cc
@@ -177,7 +177,7 @@ Evaluator::Evaluator()
trace_ = g_flags.dump_variable_assignment_trace || g_flags.dump_include_graph;
assignment_tracefile_ = nullptr;
- assignment_count_ = 0;
+ assignment_sep_ = "\n";
}
Evaluator::~Evaluator() {
@@ -345,6 +345,7 @@ void Evaluator::EvalAssign(const AssignStmt* stmt) {
if (stmt->is_final) {
var->SetReadOnly();
}
+ TraceVariableAssign(lhs, var);
}
// With rule broken into
@@ -709,35 +710,70 @@ Var* Evaluator::LookupVarGlobal(Symbol name) {
return v;
}
-void Evaluator::TraceVariableLookup(const char* operation,
- Symbol name,
- Var* var) {
+bool Evaluator::IsTraced(Symbol& name) const {
if (assignment_tracefile_ == nullptr) {
- return;
+ return false;
}
- if (assignment_count_++ == 0) {
- fprintf(assignment_tracefile_, "\n");
- } else {
- fprintf(assignment_tracefile_, ",\n");
+ bool trace_var = g_flags.traced_variables_pattern.size() == 0;
+ // trace every variable unless filtered
+ if (trace_var) {
+ return true;
+ }
+
+ for (const auto& pat : g_flags.traced_variables_pattern) {
+ if (pat.Match(name.c_str())) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Evaluator::TraceVariableLookup(const char* operation,
+ Symbol& name,
+ Var* var) {
+ if (!IsTraced(name)) {
+ return;
}
- bool has_definition_trace = var->Definition() != nullptr;
- fprintf(assignment_tracefile_, " {\n");
- fprintf(assignment_tracefile_, " \"name\": \"%s\",\n", name.c_str());
- fprintf(assignment_tracefile_, " \"operation\": \"%s\",\n", operation);
- fprintf(assignment_tracefile_, " \"defined\": %s,\n",
- var->IsDefined() ? "true" : "false");
+ fputs(assignment_sep_, assignment_tracefile_);
+ assignment_sep_ = ",\n";
+ fprintf(assignment_tracefile_,
+ " {\n"
+ " \"name\": \"%s\",\n"
+ " \"operation\": \"%s\",\n"
+ " \"defined\": %s,\n",
+ name.c_str(), operation, var->IsDefined() ? "true" : "false");
fprintf(assignment_tracefile_, " \"reference_stack\": [\n");
CurrentFrame()->PrintJSONTrace(assignment_tracefile_, 8);
- fprintf(assignment_tracefile_, " ]%s\n",
- has_definition_trace ? "," : "");
- if (has_definition_trace) {
- fprintf(assignment_tracefile_, " \"value_stack\": [\n");
- var->Definition()->PrintJSONTrace(assignment_tracefile_, 8);
- fprintf(assignment_tracefile_, " ]\n");
- }
- fprintf(assignment_tracefile_, " }");
+ fprintf(assignment_tracefile_,
+ " ]\n"
+ " }");
+}
+
+void Evaluator::TraceVariableAssign(Symbol& name, Var* var) {
+ if (!IsTraced(name)) {
+ return;
+ }
+ fputs(assignment_sep_, assignment_tracefile_);
+ assignment_sep_ = ",\n";
+ fprintf(assignment_tracefile_,
+ " {\n"
+ " \"name\": \"%s\",\n"
+ " \"operation\": \"assign\",\n"
+ " \"value\": \"%s\"",
+ name.c_str(), var->DebugString().c_str());
+ Frame* definition = var->Definition();
+ if (definition != nullptr) {
+ fprintf(assignment_tracefile_,
+ ",\n"
+ " \"value_stack\": [\n");
+ definition->PrintJSONTrace(assignment_tracefile_, 8);
+ fprintf(assignment_tracefile_, " ]");
+ }
+ fprintf(assignment_tracefile_,
+ "\n"
+ " }");
}
Var* Evaluator::LookupVarForEval(Symbol name) {
diff --git a/src/eval.h b/src/eval.h
index 75038ef..fc7fcff 100644
--- a/src/eval.h
+++ b/src/eval.h
@@ -228,7 +228,9 @@ class Evaluator {
bool* needs_assign);
void DoInclude(const string& fname);
- void TraceVariableLookup(const char* operation, Symbol name, Var* var);
+ bool IsTraced(Symbol& name) const;
+ void TraceVariableLookup(const char* operation, Symbol& name, Var* var);
+ void TraceVariableAssign(Symbol& name, Var* var);
Var* LookupVarGlobal(Symbol name);
// Equivalent to LookupVarInCurrentScope, but doesn't mark as used.
@@ -256,7 +258,7 @@ class Evaluator {
bool trace_;
std::vector<Frame*> stack_;
FILE* assignment_tracefile_;
- long int assignment_count_;
+ const char* assignment_sep_;
std::vector<Loc> include_stack_;
diff --git a/src/flags.cc b/src/flags.cc
index e21a541..1bba336 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -53,6 +53,7 @@ void Flags::Parse(int argc, char** argv) {
num_jobs = num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
const char* num_jobs_str;
const char* writable_str;
+ const char* variable_assignment_trace_filter;
if (const char* makeflags = getenv("MAKEFLAGS")) {
for (StringPiece tok : WordScanner(makeflags)) {
@@ -154,6 +155,12 @@ void Flags::Parse(int argc, char** argv) {
} else if (ParseCommandLineOptionWithArg("--dump_variable_assignment_trace",
argv, &i,
&dump_variable_assignment_trace)) {
+ } else if (ParseCommandLineOptionWithArg(
+ "--variable_assignment_trace_filter", argv, &i,
+ &variable_assignment_trace_filter)) {
+ for (StringPiece pat : WordScanner(variable_assignment_trace_filter)) {
+ traced_variables_pattern.push_back(Pattern(pat));
+ }
} else if (ParseCommandLineOptionWithArg("-j", argv, &i, &num_jobs_str)) {
num_jobs = strtol(num_jobs_str, NULL, 10);
if (num_jobs <= 0) {
@@ -202,4 +209,11 @@ void Flags::Parse(int argc, char** argv) {
}
}
}
+
+ if (traced_variables_pattern.size() &&
+ dump_variable_assignment_trace == nullptr) {
+ ERROR(
+ "--variable_assignment_trace_filter is valid only together with "
+ "--dump_variable_assignment_trace");
+ }
}
diff --git a/src/flags.h b/src/flags.h
index 73410d5..e173730 100644
--- a/src/flags.h
+++ b/src/flags.h
@@ -19,6 +19,7 @@
#include <vector>
#include "string_piece.h"
+#include "strutil.h"
#include "symtab.h"
using namespace std;
@@ -80,6 +81,7 @@ struct Flags {
vector<Symbol> targets;
vector<StringPiece> cl_vars;
vector<string> writable;
+ vector<Pattern> traced_variables_pattern;
void Parse(int argc, char** argv);
};
diff --git a/src/strutil.cc b/src/strutil.cc
index 8c4bdc0..4546265 100644
--- a/src/strutil.cc
+++ b/src/strutil.cc
@@ -160,8 +160,7 @@ bool Pattern::MatchImpl(StringPiece str) const {
StringPiece Pattern::Stem(StringPiece str) const {
if (!Match(str))
return "";
- return str.substr(percent_index_,
- str.size() - pat_.size() + 1);
+ return str.substr(percent_index_, str.size() - pat_.size() + 1);
}
void Pattern::AppendSubst(StringPiece str,