diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-30 10:17:07 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-30 10:17:07 +0000 |
commit | 96ea63d0d101ebbdbb08f79a80f3fa38bfb27ced (patch) | |
tree | f33c8f6fa3ae9fbba0178ba0cbf4f291fd3ec11e /tools/gn/err.cc | |
parent | fb68e6c9f20785ccd0024f14b09c200060931953 (diff) | |
download | chromium_src-96ea63d0d101ebbdbb08f79a80f3fa38bfb27ced.zip chromium_src-96ea63d0d101ebbdbb08f79a80f3fa38bfb27ced.tar.gz chromium_src-96ea63d0d101ebbdbb08f79a80f3fa38bfb27ced.tar.bz2 |
Revert 214325 "Revert 214254 "Add initial prototype for the GN m..."
The issue was already fixed :)
> Revert 214254 "Add initial prototype for the GN meta-buildsystem."
>
> It broke the check_licenses step on Android (see http://build.chromium.org/p/chromium.linux/builders/Android%20Builder%20%28dbg%29/builds/39904/steps/check_licenses/logs/stdio):
>
> @@@BUILD_STEP check_licenses@@@
> > /b/build/slave/Android_Builder__dbg_/build/src/android_webview/tools/webview_licenses.py scan
> Got LicenseError "missing README.chromium or licenses.py SPECIAL_CASES entry" while scanning tools/gn/secondary/base/third_party/dynamic_annotations
> Got LicenseError "missing README.chromium or licenses.py SPECIAL_CASES entry" while scanning tools/gn/secondary/third_party/modp_b64
> < /b/build/slave/Android_Builder__dbg_/build/src/android_webview/tools/webview_licenses.py scan
> ERROR: process exited with code 2
> @@@STEP_FAILURE@@@
>
>
> > Add initial prototype for the GN meta-buildsystem.
> >
> > This is currently not hooked into the build. To build, add a reference to the
> > gn.gyp file to build/all.gyp
> >
> > R=darin@chromium.org, scottmg@chromium.org
> >
> > Review URL: https://codereview.chromium.org/21114002
>
> TBR=brettw@chromium.org
>
> Review URL: https://codereview.chromium.org/21084010
TBR=bauerb@chromium.org
Review URL: https://codereview.chromium.org/21204003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@214333 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/gn/err.cc')
-rw-r--r-- | tools/gn/err.cc | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/tools/gn/err.cc b/tools/gn/err.cc new file mode 100644 index 0000000..068ea6d --- /dev/null +++ b/tools/gn/err.cc @@ -0,0 +1,196 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "tools/gn/err.h" + +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "tools/gn/filesystem_utils.h" +#include "tools/gn/input_file.h" +#include "tools/gn/parse_tree.h" +#include "tools/gn/standard_out.h" +#include "tools/gn/tokenizer.h" +#include "tools/gn/value.h" + +namespace { + +std::string GetNthLine(const base::StringPiece& data, int n) { + size_t line_off = Tokenizer::ByteOffsetOfNthLine(data, n); + size_t end = line_off + 1; + while (end < data.size() && !Tokenizer::IsNewline(data, end)) + end++; + return data.substr(line_off, end - line_off).as_string(); +} + +void FillRangeOnLine(const LocationRange& range, int line_number, + std::string* line) { + // Only bother if the range's begin or end overlaps the line. If the entire + // line is highlighted as a result of this range, it's not very helpful. + if (range.begin().line_number() != line_number && + range.end().line_number() != line_number) + return; + + // Watch out, the char offsets in the location are 1-based, so we have to + // subtract 1. + int begin_char; + if (range.begin().line_number() < line_number) + begin_char = 0; + else + begin_char = range.begin().char_offset() - 1; + + int end_char; + if (range.end().line_number() > line_number) + end_char = line->size(); // Ending is non-inclusive. + else + end_char = range.end().char_offset() - 1; + + CHECK(end_char >= begin_char); + CHECK(begin_char >= 0 && begin_char <= static_cast<int>(line->size())); + CHECK(end_char >= 0 && end_char <= static_cast<int>(line->size())); + for (int i = begin_char; i < end_char; i++) + line->at(i) = '-'; +} + +// The line length is used to clip the maximum length of the markers we'll +// make if the error spans more than one line (like unterminated literals). +void OutputHighlighedPosition(const Location& location, + const Err::RangeList& ranges, + size_t line_length) { + // Make a buffer of the line in spaces. + std::string highlight; + highlight.resize(line_length); + for (size_t i = 0; i < line_length; i++) + highlight[i] = ' '; + + // Highlight all the ranges on the line. + for (size_t i = 0; i < ranges.size(); i++) + FillRangeOnLine(ranges[i], location.line_number(), &highlight); + + // Allow the marker to be one past the end of the line for marking the end. + highlight.push_back(' '); + CHECK(location.char_offset() - 1 >= 0 && + location.char_offset() - 1 < static_cast<int>(highlight.size())); + highlight[location.char_offset() - 1] = '^'; + + // Trim unused spaces from end of line. + while (!highlight.empty() && highlight[highlight.size() - 1] == ' ') + highlight.resize(highlight.size() - 1); + + highlight += "\n"; + OutputString(highlight, DECORATION_BLUE); +} + +} // namespace + +Err::Err() : has_error_(false) { +} + +Err::Err(const Location& location, + const std::string& msg, + const std::string& help) + : has_error_(true), + location_(location), + message_(msg), + help_text_(help) { +} + +Err::Err(const LocationRange& range, + const std::string& msg, + const std::string& help) + : has_error_(true), + location_(range.begin()), + message_(msg), + help_text_(help) { + ranges_.push_back(range); +} + +Err::Err(const Token& token, + const std::string& msg, + const std::string& help) + : has_error_(true), + location_(token.location()), + message_(msg), + help_text_(help) { + ranges_.push_back(token.range()); +} + +Err::Err(const ParseNode* node, + const std::string& msg, + const std::string& help_text) + : has_error_(true), + message_(msg), + help_text_(help_text) { + // Node will be null in certain tests. + if (node) { + LocationRange range = node->GetRange(); + location_ = range.begin(); + ranges_.push_back(range); + } +} + +Err::Err(const Value& value, + const std::string msg, + const std::string& help_text) + : has_error_(true), + message_(msg), + help_text_(help_text) { + if (value.origin()) { + LocationRange range = value.origin()->GetRange(); + location_ = range.begin(); + ranges_.push_back(range); + } +} + +Err::~Err() { +} + +void Err::PrintToStdout() const { + InternalPrintToStdout(false); +} + +void Err::AppendSubErr(const Err& err) { + sub_errs_.push_back(err); +} + +void Err::InternalPrintToStdout(bool is_sub_err) const { + DCHECK(has_error_); + + if (!is_sub_err) + OutputString("ERROR ", DECORATION_RED); + + // File name and location. + const InputFile* input_file = location_.file(); + std::string loc_str; + if (input_file) { + std::string path8; + path8.assign(input_file->name().value()); + + if (is_sub_err) + loc_str = "See "; + else + loc_str = "at "; + loc_str += path8 + ": " + + base::IntToString(location_.line_number()) + ":" + + base::IntToString(location_.char_offset()) + ": "; + } + OutputString(loc_str + message_ + "\n"); + + // Quoted line. + if (input_file) { + std::string line = GetNthLine(input_file->contents(), + location_.line_number()); + if (!ContainsOnlyWhitespaceASCII(line)) { + OutputString(line + "\n", DECORATION_BOLD); + OutputHighlighedPosition(location_, ranges_, line.size()); + } + } + + // Optional help text. + if (!help_text_.empty()) + OutputString(help_text_ + "\n"); + + // Sub errors. + for (size_t i = 0; i < sub_errs_.size(); i++) + sub_errs_[i].InternalPrintToStdout(true); +} |