1 // Copyright (c) 2018 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SOURCE_COMP_MARKV_LOGGER_H_
16 #define SOURCE_COMP_MARKV_LOGGER_H_
17 
18 #include "source/comp/markv.h"
19 
20 namespace spvtools {
21 namespace comp {
22 
23 class MarkvLogger {
24  public:
MarkvLogger(MarkvLogConsumer log_consumer,MarkvDebugConsumer debug_consumer)25   MarkvLogger(MarkvLogConsumer log_consumer, MarkvDebugConsumer debug_consumer)
26       : log_consumer_(log_consumer), debug_consumer_(debug_consumer) {}
27 
AppendText(const std::string & str)28   void AppendText(const std::string& str) {
29     Append(str);
30     use_delimiter_ = false;
31   }
32 
AppendTextNewLine(const std::string & str)33   void AppendTextNewLine(const std::string& str) {
34     Append(str);
35     Append("\n");
36     use_delimiter_ = false;
37   }
38 
AppendBitSequence(const std::string & str)39   void AppendBitSequence(const std::string& str) {
40     if (debug_consumer_) instruction_bits_ << str;
41     if (use_delimiter_) Append("-");
42     Append(str);
43     use_delimiter_ = true;
44   }
45 
AppendWhitespaces(size_t num)46   void AppendWhitespaces(size_t num) {
47     Append(std::string(num, ' '));
48     use_delimiter_ = false;
49   }
50 
NewLine()51   void NewLine() {
52     Append("\n");
53     use_delimiter_ = false;
54   }
55 
DebugInstruction(const spv_parsed_instruction_t & inst)56   bool DebugInstruction(const spv_parsed_instruction_t& inst) {
57     bool result = true;
58     if (debug_consumer_) {
59       result = debug_consumer_(
60           std::vector<uint32_t>(inst.words, inst.words + inst.num_words),
61           instruction_bits_.str(), instruction_comment_.str());
62       instruction_bits_.str(std::string());
63       instruction_comment_.str(std::string());
64     }
65     return result;
66   }
67 
68  private:
69   MarkvLogger(const MarkvLogger&) = delete;
70   MarkvLogger(MarkvLogger&&) = delete;
71   MarkvLogger& operator=(const MarkvLogger&) = delete;
72   MarkvLogger& operator=(MarkvLogger&&) = delete;
73 
Append(const std::string & str)74   void Append(const std::string& str) {
75     if (log_consumer_) log_consumer_(str);
76     if (debug_consumer_) instruction_comment_ << str;
77   }
78 
79   MarkvLogConsumer log_consumer_;
80   MarkvDebugConsumer debug_consumer_;
81 
82   std::stringstream instruction_bits_;
83   std::stringstream instruction_comment_;
84 
85   // If true a delimiter will be appended before the next bit sequence.
86   // Used to generate outputs like: 1100-0 1110-1-1100-1-1111-0 110-0.
87   bool use_delimiter_ = false;
88 };
89 
90 }  // namespace comp
91 }  // namespace spvtools
92 
93 #endif  // SOURCE_COMP_MARKV_LOGGER_H_
94