Merge "traceconv: fix end_state printing for traceconv"
diff --git a/src/trace_processor/ftrace_utils.cc b/src/trace_processor/ftrace_utils.cc
index c0f0e96..081ba94 100644
--- a/src/trace_processor/ftrace_utils.cc
+++ b/src/trace_processor/ftrace_utils.cc
@@ -111,7 +111,7 @@
   }
 }
 
-TaskState::TaskStateStr TaskState::ToString() const {
+TaskState::TaskStateStr TaskState::ToString(char separator) const {
   PERFETTO_CHECK(is_valid());
 
   char buffer[32];
@@ -124,26 +124,56 @@
   } else {
     if (state_ & Atom::kInterruptibleSleep)
       buffer[pos++] = 'S';
-    if (state_ & Atom::kUninterruptibleSleep)
+    if (state_ & Atom::kUninterruptibleSleep) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'D';  // D for (D)isk sleep
-    if (state_ & Atom::kStopped)
+    }
+    if (state_ & Atom::kStopped) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'T';
-    if (state_ & Atom::kTraced)
+    }
+    if (state_ & Atom::kTraced) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 't';
-    if (state_ & Atom::kExitDead)
+    }
+    if (state_ & Atom::kExitDead) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'X';
-    if (state_ & Atom::kExitZombie)
+    }
+    if (state_ & Atom::kExitZombie) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'Z';
-    if (state_ & Atom::kTaskDead)
+    }
+    if (state_ & Atom::kTaskDead) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'x';
-    if (state_ & Atom::kWakeKill)
+    }
+    if (state_ & Atom::kWakeKill) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'K';
-    if (state_ & Atom::kWaking)
+    }
+    if (state_ & Atom::kWaking) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'W';
-    if (state_ & Atom::kParked)
+    }
+    if (state_ & Atom::kParked) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'P';
-    if (state_ & Atom::kNoLoad)
+    }
+    if (state_ & Atom::kNoLoad) {
+      if (separator && pos != 0)
+        buffer[pos++] = separator;
       buffer[pos++] = 'N';
+    }
   }
 
   if (is_kernel_preempt())
diff --git a/src/trace_processor/ftrace_utils.h b/src/trace_processor/ftrace_utils.h
index bb6ba4c..fa8d48f 100644
--- a/src/trace_processor/ftrace_utils.h
+++ b/src/trace_processor/ftrace_utils.h
@@ -68,9 +68,10 @@
   bool is_valid() const { return state_ & kValid; }
 
   // Returns the string representation of this (valid) TaskState. This array
-  // is null terminated.
+  // is null terminated. |seperator| specifies if a separator should be printed
+  // between the atoms (default: \0 meaning no separator).
   // Note: This function CHECKs that |is_valid()| is true.
-  TaskStateStr ToString() const;
+  TaskStateStr ToString(char separator = '\0') const;
 
   // Returns the raw state this class was created from.
   uint16_t raw_state() const {
diff --git a/src/trace_processor/raw_table.cc b/src/trace_processor/raw_table.cc
index 86bc591..501eee4 100644
--- a/src/trace_processor/raw_table.cc
+++ b/src/trace_processor/raw_table.cc
@@ -141,7 +141,7 @@
     write_arg(SS::kPrevStateFieldNumber - 1, [writer](const Variadic& value) {
       PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
       auto state = static_cast<uint16_t>(value.int_value);
-      writer->AppendString(ftrace_utils::TaskState(state).ToString().data());
+      writer->AppendString(ftrace_utils::TaskState(state).ToString('|').data());
     });
     writer->AppendLiteral(" ==>");
     write_arg(SS::kNextCommFieldNumber - 1, write_value);