blob: 162d9ccade49ef8045962d109c02d219e205446d [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "garnet/bin/zxdb/console/source_util.h"
#include <limits>
#include "garnet/bin/zxdb/common/file_util.h"
#include "lib/fxl/files/file.h"
#include "lib/fxl/logging.h"
namespace zxdb {
Err GetFileContents(const std::string& file_name, const std::string& build_dir,
std::string* contents) {
// Search for the source file. If it's relative, try to find it relative to
// the build dir, and if that doesn't exist, try relative to the current
// directory).
if (IsPathAbsolute(file_name)) {
// Absolute path, expect it to be readable or fail.
if (!files::ReadFileToString(file_name, contents))
return Err("Source file not found: " + file_name);
} else if (!files::ReadFileToString(CatPathComponents(build_dir, file_name),
contents)) {
// Doesn't exist relative to build dir, fall back to trying to read it
// from the current dir.
if (!files::ReadFileToString(file_name, contents))
return Err("Source file not found: " + file_name);
}
return Err();
}
std::vector<std::string> ExtractSourceLines(
const std::string& contents,
int first_line, int last_line) {
FXL_DCHECK(first_line > 0);
std::vector<std::string> result;
constexpr char kCR = 13;
constexpr char kLF = 10;
int cur_line = 1;
size_t line_begin = 0; // Byte offset.
while (line_begin < contents.size() && cur_line <= last_line) {
size_t cur = line_begin;
// Locate extent of current line.
size_t next_line_begin = contents.size();
size_t line_end = contents.size();
while (cur < contents.size()) {
if (contents[cur] == kCR) {
// Either CR or CR+LF
line_end = cur;
if (cur < contents.size() - 1 && contents[cur + 1] == kLF) {
next_line_begin = cur + 2;
} else {
next_line_begin = cur + 1;
}
break;
} else if (contents[cur] == kLF) {
// LF by itself.
line_end = cur;
next_line_begin = cur + 1;
break;
}
cur++;
}
if (cur_line >= first_line && cur_line <= last_line)
result.emplace_back(&contents[line_begin], line_end - line_begin);
// Advance to next line.
line_begin = next_line_begin;
cur_line++;
}
return result;
}
std::vector<std::string> ExtractSourceLines(
const std::string& contents) {
return ExtractSourceLines(contents, 1, std::numeric_limits<int>::max());
}
} // namespace zxdb