#include #include "character.h" #include "locator.h" #include "show.h" #include "file.h" #include "util.h" std::string abbreviate_location( const std::string& location, bool make_map, std::map& relpath) { std::string result = location; fs::path basename = fs::path(location).filename(); if (sks_commands.contains(basename)) { result = basename; } else { if (make_map) { if (relpath.count(location)) { result = relpath[location]; } else { result = fs::relative(location, fs::current_path()); relpath[location] = result; } } } return result; } Locator::Locator(const fs::path& filename, int line, int chr) : m_filename(filename) , m_line(line) , m_chr(chr) { string_map relpath {}; //m_filename = abbreviate_location(m_filename, false, relpath); } std::ostream &nformat(std::ostream &os) { os << std::setfill('0') << std::setw(3); return os; } std::string Locator::str(bool relative) const { // relative_pathname(m_filename, fs::current_path().string()) << ":" std::string filename = m_filename; if (relative) { filename = relative_to_cwd(m_filename); } std::stringstream ss {}; ss << "[" << filename << ":" << nformat << m_line << "." << nformat << m_chr+1 << "]"; return ss.str(); } std::string Locator::desc(bool relative) const { // relative_pathname(m_filename, fs::current_path().string()) << ":" std::string filename = m_filename; if (relative) { filename = relative_to_cwd(m_filename); } std::stringstream ss {}; ss << filename << ", line " << m_line << ", character " << m_chr + 1; return ss.str(); } std::string Locator::abbrev(bool include_chr) const { fs::path fname(m_filename); std::stringstream ss {}; ss << "[" << fname.filename().string() << ":" << nformat << m_line; if (include_chr) { ss << "." << nformat << m_chr+1; } ss << "]"; return ss.str(); } std::string locator_range(const Locator& start_loc, const Locator& end_loc, string_map& relpath) { std::string start_filename = abbreviate_location(start_loc.m_filename, true, relpath); std::string end_filename = abbreviate_location(end_loc.m_filename, true, relpath); std::stringstream ss {}; std::cout << std::setfill('0') << std::setw(3); if (start_filename != end_filename) { ss << start_loc << right_arrow << end_loc; } else { ss << "[" << start_filename << ":"; if (start_loc.m_line == end_loc.m_line) { ss << nformat << start_loc.m_line << "." << nformat << start_loc.m_chr+1 << right_arrow << nformat << end_loc.m_chr+1; } else { ss << nformat << start_loc.m_line << "." << nformat << start_loc.m_chr+1 << right_arrow << nformat << end_loc.m_line << "." << nformat << end_loc.m_chr+1; } ss << "]"; } std::cout << std::setfill(' '); return ss.str(); } Locator current_locator(const std::source_location location) { // file_name() may be null (Homebrew GCC on macOS) -> avoid path(nullptr). return Locator(location.file_name() ? location.file_name() : "", location.line(), location.column()); } std::string locator_summary(std::vector locators) { std::map> file_locs {}; for (auto loc : locators) { if (!file_locs.contains(loc.m_filename)) { file_locs[loc.m_filename] = {}; } file_locs[loc.m_filename].push_back(loc.m_line); } for (auto [filename, lines] : file_locs) { std::cout << " " << filename << ": " << lines << "\n"; } return ""; }