| 3722 | /*************** CODE SNIPPET ***************/ |
| 3723 | |
| 3724 | class SourceFile { |
| 3725 | public: |
| 3726 | typedef std::vector<std::pair<unsigned, std::string>> lines_t; |
| 3727 | |
| 3728 | SourceFile() {} |
| 3729 | SourceFile(const std::string& path) |
| 3730 | { |
| 3731 | // 1. If BACKWARD_CXX_SOURCE_PREFIXES is set then assume it contains |
| 3732 | // a colon-separated list of path prefixes. Try prepending each |
| 3733 | // to the given path until a valid file is found. |
| 3734 | const std::vector<std::string>& prefixes = get_paths_from_env_variable(); |
| 3735 | for (size_t i = 0; i < prefixes.size(); ++i) { |
| 3736 | // Double slashes (//) should not be a problem. |
| 3737 | std::string new_path = prefixes[i] + '/' + path; |
| 3738 | _file.reset(new std::ifstream(new_path.c_str())); |
| 3739 | if (is_open()) |
| 3740 | break; |
| 3741 | } |
| 3742 | // 2. If no valid file found then fallback to opening the path as-is. |
| 3743 | if (!_file || !is_open()) { |
| 3744 | _file.reset(new std::ifstream(path.c_str())); |
| 3745 | } |
| 3746 | } |
| 3747 | bool is_open() const { return _file->is_open(); } |
| 3748 | |
| 3749 | lines_t& get_lines(unsigned line_start, unsigned line_count, lines_t& lines) |
| 3750 | { |
| 3751 | using namespace std; |
| 3752 | // This function make uses of the dumbest algo ever: |
| 3753 | // 1) seek(0) |
| 3754 | // 2) read lines one by one and discard until line_start |
| 3755 | // 3) read line one by one until line_start + line_count |
| 3756 | // |
| 3757 | // If you are getting snippets many time from the same file, it is |
| 3758 | // somewhat a waste of CPU, feel free to benchmark and propose a |
| 3759 | // better solution ;) |
| 3760 | |
| 3761 | _file->clear(); |
| 3762 | _file->seekg(0); |
| 3763 | string line; |
| 3764 | unsigned line_idx; |
| 3765 | |
| 3766 | for (line_idx = 1; line_idx < line_start; ++line_idx) { |
| 3767 | std::getline(*_file, line); |
| 3768 | if (!*_file) { |
| 3769 | return lines; |
| 3770 | } |
| 3771 | } |
| 3772 | |
| 3773 | // think of it like a lambda in C++98 ;) |
| 3774 | // but look, I will reuse it two times! |
| 3775 | // What a good boy am I. |
| 3776 | struct isspace { |
| 3777 | bool operator()(char c) { return std::isspace(c); } |
| 3778 | }; |
| 3779 | |
| 3780 | bool started = false; |
| 3781 | for (; line_idx < line_start + line_count; ++line_idx) { |
no test coverage detected