| Index: tools/gn/c_include_iterator.cc
|
| diff --git a/tools/gn/c_include_iterator.cc b/tools/gn/c_include_iterator.cc
|
| index 3690dedd3d2f5ee58de2023c7d7b4f69049363fb..e87e66e2d6faa38fd85f4ba4b767702a2efeabb3 100644
|
| --- a/tools/gn/c_include_iterator.cc
|
| +++ b/tools/gn/c_include_iterator.cc
|
| @@ -5,6 +5,9 @@
|
| #include "tools/gn/c_include_iterator.h"
|
|
|
| #include "base/logging.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "tools/gn/input_file.h"
|
| +#include "tools/gn/location.h"
|
|
|
| namespace {
|
|
|
| @@ -47,24 +50,34 @@ bool ShouldCountTowardNonIncludeLines(const base::StringPiece& line) {
|
| return false; // Don't count comments.
|
| if (StartsWith(line, "#"))
|
| return false; // Don't count preprocessor.
|
| + if (base::ContainsOnlyChars(line, base::kWhitespaceASCII))
|
| + return false; // Don't count whitespace lines.
|
| return true; // Count everything else.
|
| }
|
|
|
| // Given a line, checks to see if it looks like an include or import and
|
| // extract the path. The type of include is returned. Returns INCLUDE_NONE on
|
| // error or if this is not an include line.
|
| +//
|
| +// The 1-based character number on the line that the include was found at
|
| +// will be filled into *begin_char.
|
| IncludeType ExtractInclude(const base::StringPiece& line,
|
| - base::StringPiece* path) {
|
| + base::StringPiece* path,
|
| + int* begin_char) {
|
| static const char kInclude[] = "#include";
|
| static const size_t kIncludeLen = arraysize(kInclude) - 1; // No null.
|
| static const char kImport[] = "#import";
|
| static const size_t kImportLen = arraysize(kImport) - 1; // No null.
|
|
|
| + base::StringPiece trimmed = TrimLeadingWhitespace(line);
|
| + if (trimmed.empty())
|
| + return INCLUDE_NONE;
|
| +
|
| base::StringPiece contents;
|
| - if (StartsWith(line, base::StringPiece(kInclude, kIncludeLen)))
|
| - contents = TrimLeadingWhitespace(line.substr(kIncludeLen));
|
| - else if (StartsWith(line, base::StringPiece(kImport, kImportLen)))
|
| - contents = TrimLeadingWhitespace(line.substr(kImportLen));
|
| + if (StartsWith(trimmed, base::StringPiece(kInclude, kIncludeLen)))
|
| + contents = TrimLeadingWhitespace(trimmed.substr(kIncludeLen));
|
| + else if (StartsWith(trimmed, base::StringPiece(kImport, kImportLen)))
|
| + contents = TrimLeadingWhitespace(trimmed.substr(kImportLen));
|
|
|
| if (contents.empty())
|
| return INCLUDE_NONE;
|
| @@ -87,6 +100,8 @@ IncludeType ExtractInclude(const base::StringPiece& line,
|
| return INCLUDE_NONE;
|
|
|
| *path = contents.substr(1, terminator_index - 1);
|
| + // Note: one based so we do "+ 1".
|
| + *begin_char = static_cast<int>(path->data() - line.data()) + 1;
|
| return type;
|
| }
|
|
|
| @@ -94,47 +109,55 @@ IncludeType ExtractInclude(const base::StringPiece& line,
|
|
|
| const int CIncludeIterator::kMaxNonIncludeLines = 10;
|
|
|
| -CIncludeIterator::CIncludeIterator(const base::StringPiece& file)
|
| - : file_(file),
|
| +CIncludeIterator::CIncludeIterator(const InputFile* input)
|
| + : input_file_(input),
|
| + file_(input->contents()),
|
| offset_(0),
|
| + line_number_(0),
|
| lines_since_last_include_(0) {
|
| }
|
|
|
| CIncludeIterator::~CIncludeIterator() {
|
| }
|
|
|
| -bool CIncludeIterator::GetNextIncludeString(base::StringPiece* out) {
|
| +bool CIncludeIterator::GetNextIncludeString(base::StringPiece* out,
|
| + LocationRange* location) {
|
| base::StringPiece line;
|
| + int cur_line_number = 0;
|
| while (lines_since_last_include_ <= kMaxNonIncludeLines &&
|
| - GetNextLine(&line)) {
|
| - base::StringPiece trimmed = TrimLeadingWhitespace(line);
|
| - if (trimmed.empty())
|
| - continue; // Just ignore all empty lines.
|
| -
|
| + GetNextLine(&line, &cur_line_number)) {
|
| base::StringPiece include_contents;
|
| - IncludeType type = ExtractInclude(trimmed, &include_contents);
|
| + int begin_char;
|
| + IncludeType type = ExtractInclude(line, &include_contents, &begin_char);
|
| if (type == INCLUDE_USER) {
|
| // Only count user includes for now.
|
| *out = include_contents;
|
| + *location = LocationRange(
|
| + Location(input_file_, cur_line_number, begin_char),
|
| + Location(input_file_, cur_line_number,
|
| + begin_char + static_cast<int>(include_contents.size())));
|
| +
|
| lines_since_last_include_ = 0;
|
| return true;
|
| }
|
|
|
| - if (ShouldCountTowardNonIncludeLines(trimmed))
|
| + if (ShouldCountTowardNonIncludeLines(line))
|
| lines_since_last_include_++;
|
| }
|
| return false;
|
| }
|
|
|
| -bool CIncludeIterator::GetNextLine(base::StringPiece* line) {
|
| +bool CIncludeIterator::GetNextLine(base::StringPiece* line, int* line_number) {
|
| if (offset_ == file_.size())
|
| return false;
|
|
|
| size_t begin = offset_;
|
| while (offset_ < file_.size() && file_[offset_] != '\n')
|
| offset_++;
|
| + line_number_++;
|
|
|
| *line = file_.substr(begin, offset_ - begin);
|
| + *line_number = line_number_;
|
|
|
| // If we didn't hit EOF, skip past the newline for the next one.
|
| if (offset_ < file_.size())
|
|
|