1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "extensions/common/stack_frame.h"
6
7#include <string>
8
9#include "base/strings/utf_string_conversions.h"
10#include "third_party/re2/re2/re2.h"
11
12namespace extensions {
13
14namespace {
15const char kAnonymousFunction[] = "(anonymous function)";
16}
17
18StackFrame::StackFrame() : line_number(1), column_number(1) {
19}
20
21StackFrame::StackFrame(const StackFrame& frame)
22    : line_number(frame.line_number),
23      column_number(frame.column_number),
24      source(frame.source),
25      function(frame.function) {
26}
27
28StackFrame::StackFrame(size_t line_number,
29                       size_t column_number,
30                       const base::string16& source,
31                       const base::string16& function)
32    : line_number(line_number),
33      column_number(column_number),
34      source(source),
35      function(function.empty() ? base::UTF8ToUTF16(kAnonymousFunction)
36                   : function) {
37}
38
39StackFrame::~StackFrame() {
40}
41
42// Create a stack frame from the passed text. The text must follow one of two
43// formats:
44//   - "function_name (source:line_number:column_number)"
45//   - "source:line_number:column_number"
46// (We have to recognize two formats because V8 will report stack traces in
47// both ways. If we reconcile this, we can clean this up.)
48// static
49scoped_ptr<StackFrame> StackFrame::CreateFromText(
50    const base::string16& frame_text) {
51  // We need to use utf8 for re2 matching.
52  std::string text = base::UTF16ToUTF8(frame_text);
53
54  size_t line = 1;
55  size_t column = 1;
56  std::string source;
57  std::string function;
58  if (!re2::RE2::FullMatch(text,
59                           "(.+) \\(([^\\(\\)]+):(\\d+):(\\d+)\\)",
60                           &function, &source, &line, &column) &&
61      !re2::RE2::FullMatch(text,
62                           "([^\\(\\)]+):(\\d+):(\\d+)",
63                           &source, &line, &column)) {
64    return scoped_ptr<StackFrame>();
65  }
66
67  return scoped_ptr<StackFrame>(new StackFrame(line,
68                                               column,
69                                               base::UTF8ToUTF16(source),
70                                               base::UTF8ToUTF16(function)));
71}
72
73bool StackFrame::operator==(const StackFrame& rhs) const {
74  return line_number == rhs.line_number &&
75         column_number == rhs.column_number &&
76         source == rhs.source &&
77         function == rhs.function;
78}
79
80}  // namespace extensions
81