158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "extensions/common/stack_frame.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <string>
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "third_party/re2/re2/re2.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace extensions {
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kAnonymousFunction[] = "(anonymous function)";
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)StackFrame::StackFrame() : line_number(1), column_number(1) {
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)StackFrame::StackFrame(const StackFrame& frame)
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : line_number(frame.line_number),
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      column_number(frame.column_number),
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      source(frame.source),
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      function(frame.function) {
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)StackFrame::StackFrame(size_t line_number,
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       size_t column_number,
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       const base::string16& source,
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       const base::string16& function)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : line_number(line_number),
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      column_number(column_number),
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      source(source),
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      function(function.empty() ? base::UTF8ToUTF16(kAnonymousFunction)
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   : function) {
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)StackFrame::~StackFrame() {
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Create a stack frame from the passed text. The text must follow one of two
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// formats:
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)//   - "function_name (source:line_number:column_number)"
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)//   - "source:line_number:column_number"
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// (We have to recognize two formats because V8 will report stack traces in
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// both ways. If we reconcile this, we can clean this up.)
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<StackFrame> StackFrame::CreateFromText(
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::string16& frame_text) {
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // We need to use utf8 for re2 matching.
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string text = base::UTF16ToUTF8(frame_text);
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  size_t line = 1;
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  size_t column = 1;
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string source;
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string function;
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!re2::RE2::FullMatch(text,
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           "(.+) \\(([^\\(\\)]+):(\\d+):(\\d+)\\)",
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           &function, &source, &line, &column) &&
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !re2::RE2::FullMatch(text,
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           "([^\\(\\)]+):(\\d+):(\\d+)",
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           &source, &line, &column)) {
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return scoped_ptr<StackFrame>();
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return scoped_ptr<StackFrame>(new StackFrame(line,
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                               column,
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                               base::UTF8ToUTF16(source),
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                               base::UTF8ToUTF16(function)));
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool StackFrame::operator==(const StackFrame& rhs) const {
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return line_number == rhs.line_number &&
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         column_number == rhs.column_number &&
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         source == rhs.source &&
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         function == rhs.function;
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace extensions
81