| Index: experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc
|
| diff --git a/experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc b/experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc
|
| deleted file mode 100644
|
| index a22d9d0e5e12505d2435d04d2f0173185354fbc8..0000000000000000000000000000000000000000
|
| --- a/experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc
|
| +++ /dev/null
|
| @@ -1,685 +0,0 @@
|
| -// Copyright (c) 2010 Google Inc.
|
| -// All rights reserved.
|
| -//
|
| -// Redistribution and use in source and binary forms, with or without
|
| -// modification, are permitted provided that the following conditions are
|
| -// met:
|
| -//
|
| -// * Redistributions of source code must retain the above copyright
|
| -// notice, this list of conditions and the following disclaimer.
|
| -// * Redistributions in binary form must reproduce the above
|
| -// copyright notice, this list of conditions and the following disclaimer
|
| -// in the documentation and/or other materials provided with the
|
| -// distribution.
|
| -// * Neither the name of Google Inc. nor the names of its
|
| -// contributors may be used to endorse or promote products derived from
|
| -// this software without specific prior written permission.
|
| -//
|
| -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| -
|
| -// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
|
| -
|
| -// stabs_reader_unittest.cc: Unit tests for google_breakpad::StabsReader.
|
| -
|
| -#include <a.out.h>
|
| -#include <cassert>
|
| -#include <cerrno>
|
| -#include <cstdarg>
|
| -#include <cstdlib>
|
| -#include <cstring>
|
| -#include <fstream>
|
| -#include <iomanip>
|
| -#include <iostream>
|
| -#include <map>
|
| -#include <sstream>
|
| -#include <stab.h>
|
| -
|
| -#include "breakpad_googletest_includes.h"
|
| -#include "common/stabs_reader.h"
|
| -
|
| -using std::istream;
|
| -using std::istringstream;
|
| -using std::map;
|
| -using std::ostream;
|
| -using std::ostringstream;
|
| -using std::string;
|
| -
|
| -using ::testing::_;
|
| -using ::testing::Eq;
|
| -using ::testing::InSequence;
|
| -using ::testing::Return;
|
| -using ::testing::Sequence;
|
| -using ::testing::StrEq;
|
| -
|
| -using google_breakpad::StabsHandler;
|
| -using google_breakpad::StabsReader;
|
| -
|
| -namespace {
|
| -
|
| -// Mock stabs file parser
|
| -//
|
| -// In order to test StabsReader, we parse a human-readable input file
|
| -// describing STABS entries into in-memory .stab and .stabstr
|
| -// sections, and then pass those to StabsReader to look at. The
|
| -// human-readable file is called a "mock stabs file".
|
| -//
|
| -// Except for compilation unit boundary lines (described below), each
|
| -// line of a mock stabs file should have the following form:
|
| -//
|
| -// TYPE OTHER DESC VALUE NAME
|
| -//
|
| -// where all data is Latin-1 bytes and fields are separated by single
|
| -// space characters, except for NAME, which may contain spaces and
|
| -// continues to the end of the line. The fields have the following
|
| -// meanings:
|
| -//
|
| -// - TYPE: the name of the stabs symbol type; like SO or FUN. These are
|
| -// the names from /usr/include/bits/stab.def, without the leading N_.
|
| -//
|
| -// - OTHER, DESC, VALUE: numeric values for the n_other, n_desc, and
|
| -// n_value fields of the stab. These can be decimal or hex,
|
| -// using C++ notation (10, 0x10)
|
| -//
|
| -// - NAME: textual data for the entry. STABS packs all kinds of
|
| -// interesting data into entries' NAME fields, so calling it a NAME
|
| -// is misleading, but that's how it is. For SO, this may be a
|
| -// filename; for FUN, this is the function name, plus type data; and
|
| -// so on.
|
| -//
|
| -// A compilation unit boundary line has the form:
|
| -//
|
| -// cu-boundary FILENAME
|
| -
|
| -// I don't know if the whole parser/handler pattern is really worth
|
| -// the bureaucracy in this case. But just writing it out as
|
| -// old-fashioned functions wasn't astonishingly clear either, so it
|
| -// seemed worth a try.
|
| -
|
| -// A handler class for mock stabs data.
|
| -class MockStabsHandler {
|
| - public:
|
| - MockStabsHandler() { }
|
| - virtual ~MockStabsHandler() { }
|
| - // The mock stabs parser calls this member function for each entry
|
| - // it parses, passing it the contents of the entry. If this function
|
| - // returns true, the parser continues; if it returns false, the parser
|
| - // stops, and its Process member function returns false.
|
| - virtual bool Entry(enum __stab_debug_code type, char other, short desc,
|
| - unsigned long value, const string &name) { return true; }
|
| - // Report a compilation unit boundary whose filename is FILENAME. As
|
| - // for the Entry function, this should return true to continue
|
| - // parsing, or false to stop processing.
|
| - virtual bool CUBoundary(const string &filename) { return true; }
|
| -
|
| - // Report an error in parsing the mock stabs data. If this returns true,
|
| - // the parser continues; if it returns false, the parser stops and
|
| - // its Process member function returns false.
|
| - virtual bool Error(const char *format, ...) = 0;
|
| -};
|
| -
|
| -// A class for parsing mock stabs files.
|
| -class MockStabsParser {
|
| - public:
|
| - // Create a parser reading input from STREAM and passing data to HANDLER.
|
| - // Use FILENAME when reporting errors.
|
| - MockStabsParser(const string &filename, istream *stream,
|
| - MockStabsHandler *handler);
|
| - // Parse data from the STREAM, invoking HANDLER->Entry for each
|
| - // entry we get. Return true if we parsed all the data succesfully,
|
| - // or false if we stopped early because Entry returned false, or if
|
| - // there were any errors during parsing.
|
| - bool Process();
|
| - private:
|
| - // A type for maps from stab type names ("SO", "SLINE", etc.) to
|
| - // n_type values.
|
| - typedef map<string, unsigned char> StabTypeNameTable;
|
| -
|
| - // Initialize the table mapping STAB type names to n_type values.
|
| - void InitializeTypeNames();
|
| -
|
| - // Parse LINE, one line of input from a mock stabs file, and pass
|
| - // its contents to handler_->Entry and return the boolean value that
|
| - // returns. If we encounter an error parsing the line, report it
|
| - // using handler->Error.
|
| - bool ParseLine(const string &line);
|
| -
|
| - const string &filename_;
|
| - istream *stream_;
|
| - MockStabsHandler *handler_;
|
| - int line_number_;
|
| - StabTypeNameTable type_names_;
|
| -};
|
| -
|
| -MockStabsParser::MockStabsParser(const string &filename, istream *stream,
|
| - MockStabsHandler *handler):
|
| - filename_(filename), stream_(stream), handler_(handler),
|
| - line_number_(0) {
|
| - InitializeTypeNames();
|
| -}
|
| -
|
| -bool MockStabsParser::Process() {
|
| - // Iterate once per line, including a line at EOF without a
|
| - // terminating newline.
|
| - for(;;) {
|
| - string line;
|
| - getline(*stream_, line, '\n');
|
| - if (line.empty() && stream_->eof())
|
| - break;
|
| - line_number_++;
|
| - if (! ParseLine(line))
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -void MockStabsParser::InitializeTypeNames() {
|
| - // On GLIBC-based systems, <bits/stab.def> is a file containing a
|
| - // call to an unspecified macro __define_stab for each stab type.
|
| - // <stab.h> uses it to define the __stab_debug_code enum type. We
|
| - // use it here to initialize our mapping from type names to enum
|
| - // values.
|
| - //
|
| - // This isn't portable to non-GLIBC systems. Feel free to just
|
| - // hard-code the values if this becomes a problem.
|
| -# define __define_stab(name, code, str) type_names_[string(str)] = code;
|
| -# include <bits/stab.def>
|
| -# undef __define_stab
|
| -}
|
| -
|
| -bool MockStabsParser::ParseLine(const string &line) {
|
| - istringstream linestream(line);
|
| - // Allow "0x" prefix for hex, and so on.
|
| - linestream.unsetf(istringstream::basefield);
|
| - // Parse and validate the stabs type.
|
| - string typeName;
|
| - linestream >> typeName;
|
| - if (typeName == "cu-boundary") {
|
| - if (linestream.peek() == ' ')
|
| - linestream.get();
|
| - string filename;
|
| - getline(linestream, filename, '\n');
|
| - return handler_->CUBoundary(filename);
|
| - } else {
|
| - StabTypeNameTable::const_iterator typeIt = type_names_.find(typeName);
|
| - if (typeIt == type_names_.end())
|
| - return handler_->Error("%s:%d: unrecognized stab type: %s\n",
|
| - filename_.c_str(), line_number_, typeName.c_str());
|
| - // These are int, not char and unsigned char, to ensure they're parsed
|
| - // as decimal numbers, not characters.
|
| - int otherInt, descInt;
|
| - unsigned long value;
|
| - linestream >> otherInt >> descInt >> value;
|
| - if (linestream.fail())
|
| - return handler_->Error("%s:%d: malformed mock stabs input line\n",
|
| - filename_.c_str(), line_number_);
|
| - if (linestream.peek() == ' ')
|
| - linestream.get();
|
| - string name;
|
| - getline(linestream, name, '\n');
|
| - return handler_->Entry(static_cast<__stab_debug_code>(typeIt->second),
|
| - otherInt, descInt, value, name);
|
| - }
|
| -}
|
| -
|
| -// A class for constructing .stab sections.
|
| -//
|
| -// A .stab section is an array of struct nlist entries. These
|
| -// entries' n_un.n_strx fields are indices into an accompanying
|
| -// .stabstr section.
|
| -class StabSection {
|
| - public:
|
| - StabSection(): used_(0), size_(1) {
|
| - entries_ = (struct nlist *) malloc(sizeof(*entries_) * size_);
|
| - }
|
| - ~StabSection() { free(entries_); }
|
| -
|
| - // Append a new 'struct nlist' entry to the end of the section, and
|
| - // return a pointer to it. This pointer is valid until the next
|
| - // call to Append. The caller should initialize the returned entry
|
| - // as needed.
|
| - struct nlist *Append();
|
| - // Set the first entry's n_desc field to COUNT, and set its n_value field
|
| - // to STRING_SIZE.
|
| - void SetHeader(short count, unsigned long string_size);
|
| - // Set SECTION to the contents of a .stab section holding the
|
| - // accumulated list of entries added with Append.
|
| - void GetSection(string *section);
|
| - // Clear the array, and prepare this StabSection to accumulate a fresh
|
| - // set of entries.
|
| - void Clear();
|
| -
|
| - private:
|
| - // The array of stabs entries,
|
| - struct nlist *entries_;
|
| - // The number of elements of entries_ that are used, and the allocated size
|
| - // of the array.
|
| - size_t used_, size_;
|
| -};
|
| -
|
| -struct nlist *StabSection::Append() {
|
| - if (used_ == size_) {
|
| - size_ *= 2;
|
| - entries_ = (struct nlist *) realloc(entries_, sizeof(*entries_) * size_);
|
| - }
|
| - assert(used_ < size_);
|
| - return &entries_[used_++];
|
| -}
|
| -
|
| -void StabSection::SetHeader(short count, unsigned long string_size) {
|
| - assert(used_ >= 1);
|
| - entries_[0].n_desc = count;
|
| - entries_[0].n_value = string_size;
|
| -}
|
| -
|
| -void StabSection::GetSection(string *section) {
|
| - section->assign(reinterpret_cast<char *>(entries_),
|
| - sizeof(*entries_) * used_);
|
| -}
|
| -
|
| -void StabSection::Clear() {
|
| - used_ = 0;
|
| - size_ = 1;
|
| - entries_ = (struct nlist *) realloc(entries_, sizeof(*entries_) * size_);
|
| -}
|
| -
|
| -// A class for building .stabstr sections.
|
| -//
|
| -// A .stabstr section is an array of characters containing a bunch of
|
| -// null-terminated strings. A string is identified by the index of
|
| -// its initial character in the array. The array always starts with a
|
| -// null byte, so that an index of zero refers to the empty string.
|
| -//
|
| -// This implementation also ensures that if two strings are equal, we
|
| -// assign them the same indices; most linkers do this, and some
|
| -// clients may rely upon it. (Note that this is not quite the same as
|
| -// ensuring that a string only appears once in the section; you could
|
| -// share space when one string is a suffix of another, but we don't.)
|
| -class StabstrSection {
|
| - public:
|
| - StabstrSection(): next_byte_(1) { string_indices_[""] = 0; }
|
| - // Ensure STR is present in the string section, and return its index.
|
| - size_t Insert(const string &str);
|
| - // Set SECTION to the contents of a .stabstr section in which the
|
| - // strings passed to Insert appear at the indices we promised.
|
| - void GetSection(string *section);
|
| - // Clear the contents of this StabstrSection, and prepare it to
|
| - // accumulate a new set of strings.
|
| - void Clear();
|
| - private:
|
| - // Maps from strings to .stabstr indices and back.
|
| - typedef map<string, size_t> StringToIndex;
|
| - typedef map<size_t, const string *> IndexToString;
|
| -
|
| - // A map from strings to the indices we've assigned them.
|
| - StringToIndex string_indices_;
|
| -
|
| - // The next unused byte in the section. The next string we add
|
| - // will get this index.
|
| - size_t next_byte_;
|
| -};
|
| -
|
| -size_t StabstrSection::Insert(const string &str) {
|
| - StringToIndex::iterator it = string_indices_.find(str);
|
| - size_t index;
|
| - if (it != string_indices_.end()) {
|
| - index = it->second;
|
| - } else {
|
| - // This is the first time we've seen STR; add it to the table.
|
| - string_indices_[str] = next_byte_;
|
| - index = next_byte_;
|
| - next_byte_ += str.size() + 1;
|
| - }
|
| - return index;
|
| -}
|
| -
|
| -void StabstrSection::GetSection(string *section) {
|
| - // First we have to invert the map.
|
| - IndexToString byIndex;
|
| - for (StringToIndex::const_iterator it = string_indices_.begin();
|
| - it != string_indices_.end(); it++)
|
| - byIndex[it->second] = &it->first;
|
| - // Now we build the .stabstr section.
|
| - section->clear();
|
| - for (IndexToString::const_iterator it = byIndex.begin();
|
| - it != byIndex.end(); it++) {
|
| - // Make sure we're actually assigning it the index we claim to be.
|
| - assert(it->first == section->size());
|
| - *section += *(it->second);
|
| - *section += '\0';
|
| - }
|
| -}
|
| -
|
| -void StabstrSection::Clear() {
|
| - string_indices_.clear();
|
| - string_indices_[""] = 0;
|
| - next_byte_ = 1;
|
| -}
|
| -
|
| -// A mock stabs parser handler class that builds .stab and .stabstr
|
| -// sections.
|
| -class StabsSectionsBuilder: public MockStabsHandler {
|
| - public:
|
| - // Construct a handler that will receive data from a MockStabsParser
|
| - // and construct .stab and .stabstr sections. FILENAME should be
|
| - // the name of the mock stabs input file; we use it in error
|
| - // messages.
|
| - StabsSectionsBuilder(const string &filename)
|
| - : filename_(filename), error_count_(0), has_header_(false),
|
| - entry_count_(0) { }
|
| -
|
| - // Overridden virtual member functions.
|
| - bool Entry(enum __stab_debug_code type, char other, short desc,
|
| - unsigned long value, const string &name);
|
| - bool CUBoundary(const string &filename);
|
| - bool Error(const char *format, ...);
|
| -
|
| - // Set SECTION to the contents of a .stab or .stabstr section
|
| - // reflecting the entries that have been passed to us via Entry.
|
| - void GetStab(string *section);
|
| - void GetStabstr(string *section);
|
| -
|
| - private:
|
| - // Finish a compilation unit. If there are any entries accumulated in
|
| - // stab_ and stabstr_, add them as a new compilation unit to
|
| - // finished_cu_stabs_ and finished_cu_stabstr_, and then clear stab_ and
|
| - // stabstr_.
|
| - void FinishCU();
|
| -
|
| - const string &filename_; // input filename, for error messages
|
| - int error_count_; // number of errors we've seen so far
|
| -
|
| - // The following members accumulate the contents of a single compilation
|
| - // unit, possibly headed by an N_UNDF stab.
|
| - bool has_header_; // true if we have an N_UNDF header
|
| - int entry_count_; // the number of entries we've seen
|
| - StabSection stab_; // 'struct nlist' entries
|
| - StabstrSection stabstr_; // and the strings they love
|
| -
|
| - // Accumulated .stab and .stabstr content for all compilation units.
|
| - string finished_cu_stab_, finished_cu_stabstr_;
|
| -};
|
| -
|
| -bool StabsSectionsBuilder::Entry(enum __stab_debug_code type, char other,
|
| - short desc, unsigned long value,
|
| - const string &name) {
|
| - struct nlist *entry = stab_.Append();
|
| - entry->n_type = type;
|
| - entry->n_other = other;
|
| - entry->n_desc = desc;
|
| - entry->n_value = value;
|
| - entry->n_un.n_strx = stabstr_.Insert(name);
|
| - entry_count_++;
|
| - return true;
|
| -}
|
| -
|
| -bool StabsSectionsBuilder::CUBoundary(const string &filename) {
|
| - FinishCU();
|
| - // Add a header for the compilation unit.
|
| - assert(!has_header_);
|
| - assert(entry_count_ == 0);
|
| - struct nlist *entry = stab_.Append();
|
| - entry->n_type = N_UNDF;
|
| - entry->n_other = 0;
|
| - entry->n_desc = 0; // will be set to number of entries
|
| - entry->n_value = 0; // will be set to size of .stabstr data
|
| - entry->n_un.n_strx = stabstr_.Insert(filename);
|
| - has_header_ = true;
|
| - // The N_UNDF header isn't included in the symbol count, so we
|
| - // shouldn't bump entry_count_ here.
|
| - return true;
|
| -}
|
| -
|
| -void StabsSectionsBuilder::FinishCU() {
|
| - if (entry_count_ > 0) {
|
| - // Get the strings first, so we can record their size in the header.
|
| - string stabstr;
|
| - stabstr_.GetSection(&stabstr);
|
| - finished_cu_stabstr_ += stabstr;
|
| -
|
| - // Initialize our header, if we have one, and extract the .stab data.
|
| - if (has_header_)
|
| - stab_.SetHeader(entry_count_, stabstr.size());
|
| - string stab;
|
| - stab_.GetSection(&stab);
|
| - finished_cu_stab_ += stab;
|
| - }
|
| -
|
| - stab_.Clear();
|
| - stabstr_.Clear();
|
| - has_header_ = false;
|
| - entry_count_ = 0;
|
| -}
|
| -
|
| -bool StabsSectionsBuilder::Error(const char *format, ...) {
|
| - va_list args;
|
| - va_start(args, format);
|
| - vfprintf(stderr, format, args);
|
| - va_end(args);
|
| - error_count_++;
|
| - if (error_count_ >= 20) {
|
| - fprintf(stderr,
|
| - "%s: lots of errors; is this really a mock stabs file?\n",
|
| - filename_.c_str());
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -void StabsSectionsBuilder::GetStab(string *section) {
|
| - FinishCU();
|
| - *section = finished_cu_stab_;
|
| -}
|
| -
|
| -void StabsSectionsBuilder::GetStabstr(string *section) {
|
| - FinishCU();
|
| - *section = finished_cu_stabstr_;
|
| -}
|
| -
|
| -class MockStabsReaderHandler: public StabsHandler {
|
| - public:
|
| - MOCK_METHOD3(StartCompilationUnit,
|
| - bool(const char *, uint64_t, const char *));
|
| - MOCK_METHOD1(EndCompilationUnit, bool(uint64_t));
|
| - MOCK_METHOD2(StartFunction, bool(const std::string &, uint64_t));
|
| - MOCK_METHOD1(EndFunction, bool(uint64_t));
|
| - MOCK_METHOD3(Line, bool(uint64_t, const char *, int));
|
| - void Warning(const char *format, ...) { MockWarning(format); }
|
| - MOCK_METHOD1(MockWarning, void(const char *));
|
| -};
|
| -
|
| -// Create a StabsReader to parse the mock stabs data in INPUT_FILE,
|
| -// passing the parsed information to HANDLER. If all goes well, return
|
| -// the result of calling the reader's Process member function.
|
| -// Otherwise, return false. INPUT_FILE should be relative to the top
|
| -// of the source tree.
|
| -static bool ApplyHandlerToMockStabsData(StabsHandler *handler,
|
| - const string &input_file) {
|
| - string full_input_file
|
| - = string(getenv("srcdir") ? getenv("srcdir") : ".") + "/" + input_file;
|
| -
|
| - // Open the input file.
|
| - std::ifstream stream(full_input_file.c_str());
|
| - if (stream.fail()) {
|
| - fprintf(stderr, "error opening mock stabs input file %s: %s\n",
|
| - full_input_file.c_str(), strerror(errno));
|
| - return false;
|
| - }
|
| -
|
| - // Parse the mock stabs data, and produce stabs sections to use as
|
| - // test input to the reader.
|
| - StabsSectionsBuilder builder(full_input_file);
|
| - MockStabsParser mock_parser(full_input_file, &stream, &builder);
|
| - if (!mock_parser.Process())
|
| - return false;
|
| - string stab, stabstr;
|
| - builder.GetStab(&stab);
|
| - builder.GetStabstr(&stabstr);
|
| -
|
| - // Run the parser on the test input, passing whatever we find to HANDLER.
|
| - StabsReader reader(
|
| - reinterpret_cast<const uint8_t *>(stab.data()), stab.size(),
|
| - reinterpret_cast<const uint8_t *>(stabstr.data()), stabstr.size(),
|
| - handler);
|
| - return reader.Process();
|
| -}
|
| -
|
| -TEST(StabsReader, MockStabsInput) {
|
| - MockStabsReaderHandler mock_handler;
|
| -
|
| - {
|
| - InSequence s;
|
| -
|
| - EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("file1.c"),
|
| - 0x42, StrEq("builddir1/")))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, StartFunction(StrEq("fun1"), 0x62))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, Line(0xe4, StrEq("file1.c"), 91))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, Line(0x164, StrEq("header.h"), 111))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndFunction(0x112))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, StartFunction(StrEq("fun2"), 0x112))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, Line(0x234, StrEq("header.h"), 131))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, Line(0x254, StrEq("file1.c"), 151))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndFunction(0x152))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(0x152))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("file3.c"),
|
| - 0x182, NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(0x192))
|
| - .WillOnce(Return(true));
|
| - }
|
| -
|
| - ASSERT_TRUE(ApplyHandlerToMockStabsData(
|
| - &mock_handler,
|
| - "common/testdata/stabs_reader_unittest.input1"));
|
| -}
|
| -
|
| -TEST(StabsReader, AbruptCU) {
|
| - MockStabsReaderHandler mock_handler;
|
| -
|
| - {
|
| - InSequence s;
|
| -
|
| - EXPECT_CALL(mock_handler,
|
| - StartCompilationUnit(StrEq("file2-1.c"), 0x12, NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(NULL))
|
| - .WillOnce(Return(true));
|
| - }
|
| -
|
| - ASSERT_TRUE(ApplyHandlerToMockStabsData(
|
| - &mock_handler,
|
| - "common/testdata/stabs_reader_unittest.input2"));
|
| -}
|
| -
|
| -TEST(StabsReader, AbruptFunction) {
|
| - MockStabsReaderHandler mock_handler;
|
| -
|
| - {
|
| - InSequence s;
|
| -
|
| - EXPECT_CALL(mock_handler,
|
| - StartCompilationUnit(StrEq("file3-1.c"), 0x12, NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, StartFunction(StrEq("fun3_1"), 0x22))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndFunction(NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(NULL))
|
| - .WillOnce(Return(true));
|
| - }
|
| -
|
| - ASSERT_TRUE(ApplyHandlerToMockStabsData(
|
| - &mock_handler,
|
| - "common/testdata/stabs_reader_unittest.input3"));
|
| -}
|
| -
|
| -TEST(StabsReader, NoCU) {
|
| - MockStabsReaderHandler mock_handler;
|
| -
|
| - EXPECT_CALL(mock_handler, StartCompilationUnit(_, _, _))
|
| - .Times(0);
|
| - EXPECT_CALL(mock_handler, StartFunction(_, _))
|
| - .Times(0);
|
| -
|
| - ASSERT_TRUE(ApplyHandlerToMockStabsData(
|
| - &mock_handler,
|
| - "common/testdata/stabs_reader_unittest.input4"));
|
| -
|
| -}
|
| -
|
| -TEST(StabsReader, NoCUEnd) {
|
| - MockStabsReaderHandler mock_handler;
|
| -
|
| - {
|
| - InSequence s;
|
| -
|
| - EXPECT_CALL(mock_handler,
|
| - StartCompilationUnit(StrEq("file5-1.c"), 0x12, NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler,
|
| - StartCompilationUnit(StrEq("file5-2.c"), 0x22, NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(NULL))
|
| - .WillOnce(Return(true));
|
| - }
|
| -
|
| - ASSERT_TRUE(ApplyHandlerToMockStabsData(
|
| - &mock_handler,
|
| - "common/testdata/stabs_reader_unittest.input5"));
|
| -
|
| -}
|
| -
|
| -TEST(StabsReader, MultipleCUs) {
|
| - MockStabsReaderHandler mock_handler;
|
| -
|
| - {
|
| - InSequence s;
|
| - EXPECT_CALL(mock_handler,
|
| - StartCompilationUnit(StrEq("antimony"), 0x12, NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, StartFunction(Eq("arsenic"), 0x22))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndFunction(0x32))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(0x32))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler,
|
| - StartCompilationUnit(StrEq("aluminum"), 0x42, NULL))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, StartFunction(Eq("selenium"), 0x52))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndFunction(0x62))
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(mock_handler, EndCompilationUnit(0x62))
|
| - .WillOnce(Return(true));
|
| - }
|
| -
|
| - ASSERT_TRUE(ApplyHandlerToMockStabsData(
|
| - &mock_handler,
|
| - "common/testdata/stabs_reader_unittest.input6"));
|
| -}
|
| -
|
| -// name duplication
|
| -
|
| -} // anonymous namespace
|
|
|