Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: tools/gn/c_include_iterator.cc

Issue 231813002: Improve GN public header file checking (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/c_include_iterator.h ('k') | tools/gn/c_include_iterator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/c_include_iterator.h" 5 #include "tools/gn/c_include_iterator.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "tools/gn/input_file.h"
10 #include "tools/gn/location.h"
8 11
9 namespace { 12 namespace {
10 13
11 enum IncludeType { 14 enum IncludeType {
12 INCLUDE_NONE, 15 INCLUDE_NONE,
13 INCLUDE_SYSTEM, // #include <...> 16 INCLUDE_SYSTEM, // #include <...>
14 INCLUDE_USER // #include "..." 17 INCLUDE_USER // #include "..."
15 }; 18 };
16 19
17 // Returns true if str starts with the prefix. 20 // Returns true if str starts with the prefix.
(...skipping 22 matching lines...) Expand all
40 // full C++ parser here, we're just trying to get a good heuristic for checking 43 // full C++ parser here, we're just trying to get a good heuristic for checking
41 // the file. 44 // the file.
42 // 45 //
43 // We assume the line has leading whitespace trimmed. We also assume that empty 46 // We assume the line has leading whitespace trimmed. We also assume that empty
44 // lines have already been filtered out. 47 // lines have already been filtered out.
45 bool ShouldCountTowardNonIncludeLines(const base::StringPiece& line) { 48 bool ShouldCountTowardNonIncludeLines(const base::StringPiece& line) {
46 if (StartsWith(line, "//")) 49 if (StartsWith(line, "//"))
47 return false; // Don't count comments. 50 return false; // Don't count comments.
48 if (StartsWith(line, "#")) 51 if (StartsWith(line, "#"))
49 return false; // Don't count preprocessor. 52 return false; // Don't count preprocessor.
53 if (base::ContainsOnlyChars(line, base::kWhitespaceASCII))
54 return false; // Don't count whitespace lines.
50 return true; // Count everything else. 55 return true; // Count everything else.
51 } 56 }
52 57
53 // Given a line, checks to see if it looks like an include or import and 58 // Given a line, checks to see if it looks like an include or import and
54 // extract the path. The type of include is returned. Returns INCLUDE_NONE on 59 // extract the path. The type of include is returned. Returns INCLUDE_NONE on
55 // error or if this is not an include line. 60 // error or if this is not an include line.
61 //
62 // The 1-based character number on the line that the include was found at
63 // will be filled into *begin_char.
56 IncludeType ExtractInclude(const base::StringPiece& line, 64 IncludeType ExtractInclude(const base::StringPiece& line,
57 base::StringPiece* path) { 65 base::StringPiece* path,
66 int* begin_char) {
58 static const char kInclude[] = "#include"; 67 static const char kInclude[] = "#include";
59 static const size_t kIncludeLen = arraysize(kInclude) - 1; // No null. 68 static const size_t kIncludeLen = arraysize(kInclude) - 1; // No null.
60 static const char kImport[] = "#import"; 69 static const char kImport[] = "#import";
61 static const size_t kImportLen = arraysize(kImport) - 1; // No null. 70 static const size_t kImportLen = arraysize(kImport) - 1; // No null.
62 71
72 base::StringPiece trimmed = TrimLeadingWhitespace(line);
73 if (trimmed.empty())
74 return INCLUDE_NONE;
75
63 base::StringPiece contents; 76 base::StringPiece contents;
64 if (StartsWith(line, base::StringPiece(kInclude, kIncludeLen))) 77 if (StartsWith(trimmed, base::StringPiece(kInclude, kIncludeLen)))
65 contents = TrimLeadingWhitespace(line.substr(kIncludeLen)); 78 contents = TrimLeadingWhitespace(trimmed.substr(kIncludeLen));
66 else if (StartsWith(line, base::StringPiece(kImport, kImportLen))) 79 else if (StartsWith(trimmed, base::StringPiece(kImport, kImportLen)))
67 contents = TrimLeadingWhitespace(line.substr(kImportLen)); 80 contents = TrimLeadingWhitespace(trimmed.substr(kImportLen));
68 81
69 if (contents.empty()) 82 if (contents.empty())
70 return INCLUDE_NONE; 83 return INCLUDE_NONE;
71 84
72 IncludeType type = INCLUDE_NONE; 85 IncludeType type = INCLUDE_NONE;
73 char terminating_char = 0; 86 char terminating_char = 0;
74 if (contents[0] == '"') { 87 if (contents[0] == '"') {
75 type = INCLUDE_USER; 88 type = INCLUDE_USER;
76 terminating_char = '"'; 89 terminating_char = '"';
77 } else if (contents[0] == '<') { 90 } else if (contents[0] == '<') {
78 type = INCLUDE_SYSTEM; 91 type = INCLUDE_SYSTEM;
79 terminating_char = '>'; 92 terminating_char = '>';
80 } else { 93 } else {
81 return INCLUDE_NONE; 94 return INCLUDE_NONE;
82 } 95 }
83 96
84 // Count everything to next "/> as the contents. 97 // Count everything to next "/> as the contents.
85 size_t terminator_index = contents.find(terminating_char, 1); 98 size_t terminator_index = contents.find(terminating_char, 1);
86 if (terminator_index == base::StringPiece::npos) 99 if (terminator_index == base::StringPiece::npos)
87 return INCLUDE_NONE; 100 return INCLUDE_NONE;
88 101
89 *path = contents.substr(1, terminator_index - 1); 102 *path = contents.substr(1, terminator_index - 1);
103 // Note: one based so we do "+ 1".
104 *begin_char = static_cast<int>(path->data() - line.data()) + 1;
90 return type; 105 return type;
91 } 106 }
92 107
93 } // namespace 108 } // namespace
94 109
95 const int CIncludeIterator::kMaxNonIncludeLines = 10; 110 const int CIncludeIterator::kMaxNonIncludeLines = 10;
96 111
97 CIncludeIterator::CIncludeIterator(const base::StringPiece& file) 112 CIncludeIterator::CIncludeIterator(const InputFile* input)
98 : file_(file), 113 : input_file_(input),
114 file_(input->contents()),
99 offset_(0), 115 offset_(0),
116 line_number_(0),
100 lines_since_last_include_(0) { 117 lines_since_last_include_(0) {
101 } 118 }
102 119
103 CIncludeIterator::~CIncludeIterator() { 120 CIncludeIterator::~CIncludeIterator() {
104 } 121 }
105 122
106 bool CIncludeIterator::GetNextIncludeString(base::StringPiece* out) { 123 bool CIncludeIterator::GetNextIncludeString(base::StringPiece* out,
124 LocationRange* location) {
107 base::StringPiece line; 125 base::StringPiece line;
126 int cur_line_number = 0;
108 while (lines_since_last_include_ <= kMaxNonIncludeLines && 127 while (lines_since_last_include_ <= kMaxNonIncludeLines &&
109 GetNextLine(&line)) { 128 GetNextLine(&line, &cur_line_number)) {
110 base::StringPiece trimmed = TrimLeadingWhitespace(line);
111 if (trimmed.empty())
112 continue; // Just ignore all empty lines.
113
114 base::StringPiece include_contents; 129 base::StringPiece include_contents;
115 IncludeType type = ExtractInclude(trimmed, &include_contents); 130 int begin_char;
131 IncludeType type = ExtractInclude(line, &include_contents, &begin_char);
116 if (type == INCLUDE_USER) { 132 if (type == INCLUDE_USER) {
117 // Only count user includes for now. 133 // Only count user includes for now.
118 *out = include_contents; 134 *out = include_contents;
135 *location = LocationRange(
136 Location(input_file_, cur_line_number, begin_char),
137 Location(input_file_, cur_line_number,
138 begin_char + static_cast<int>(include_contents.size())));
139
119 lines_since_last_include_ = 0; 140 lines_since_last_include_ = 0;
120 return true; 141 return true;
121 } 142 }
122 143
123 if (ShouldCountTowardNonIncludeLines(trimmed)) 144 if (ShouldCountTowardNonIncludeLines(line))
124 lines_since_last_include_++; 145 lines_since_last_include_++;
125 } 146 }
126 return false; 147 return false;
127 } 148 }
128 149
129 bool CIncludeIterator::GetNextLine(base::StringPiece* line) { 150 bool CIncludeIterator::GetNextLine(base::StringPiece* line, int* line_number) {
130 if (offset_ == file_.size()) 151 if (offset_ == file_.size())
131 return false; 152 return false;
132 153
133 size_t begin = offset_; 154 size_t begin = offset_;
134 while (offset_ < file_.size() && file_[offset_] != '\n') 155 while (offset_ < file_.size() && file_[offset_] != '\n')
135 offset_++; 156 offset_++;
157 line_number_++;
136 158
137 *line = file_.substr(begin, offset_ - begin); 159 *line = file_.substr(begin, offset_ - begin);
160 *line_number = line_number_;
138 161
139 // If we didn't hit EOF, skip past the newline for the next one. 162 // If we didn't hit EOF, skip past the newline for the next one.
140 if (offset_ < file_.size()) 163 if (offset_ < file_.size())
141 offset_++; 164 offset_++;
142 return true; 165 return true;
143 } 166 }
OLDNEW
« no previous file with comments | « tools/gn/c_include_iterator.h ('k') | tools/gn/c_include_iterator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698