| 3685 | /*************** CODE SNIPPET ***************/ |
| 3686 | |
| 3687 | class SourceFile { |
| 3688 | public: |
| 3689 | typedef std::vector<std::pair<unsigned, std::string>> lines_t; |
| 3690 | |
| 3691 | SourceFile() {} |
| 3692 | SourceFile(const std::string &path) { |
| 3693 | // 1. If BACKWARD_CXX_SOURCE_PREFIXES is set then assume it contains |
| 3694 | // a colon-separated list of path prefixes. Try prepending each |
| 3695 | // to the given path until a valid file is found. |
| 3696 | const std::vector<std::string> &prefixes = get_paths_from_env_variable(); |
| 3697 | for (size_t i = 0; i < prefixes.size(); ++i) { |
| 3698 | // Double slashes (//) should not be a problem. |
| 3699 | std::string new_path = prefixes[i] + '/' + path; |
| 3700 | _file.reset(new std::ifstream(new_path.c_str())); |
| 3701 | if (is_open()) |
| 3702 | break; |
| 3703 | } |
| 3704 | // 2. If no valid file found then fallback to opening the path as-is. |
| 3705 | if (!_file || !is_open()) { |
| 3706 | _file.reset(new std::ifstream(path.c_str())); |
| 3707 | } |
| 3708 | } |
| 3709 | bool is_open() const { return _file->is_open(); } |
| 3710 | |
| 3711 | lines_t &get_lines(unsigned line_start, unsigned line_count, lines_t &lines) { |
| 3712 | using namespace std; |
| 3713 | // This function make uses of the dumbest algo ever: |
| 3714 | // 1) seek(0) |
| 3715 | // 2) read lines one by one and discard until line_start |
| 3716 | // 3) read line one by one until line_start + line_count |
| 3717 | // |
| 3718 | // If you are getting snippets many time from the same file, it is |
| 3719 | // somewhat a waste of CPU, feel free to benchmark and propose a |
| 3720 | // better solution ;) |
| 3721 | |
| 3722 | _file->clear(); |
| 3723 | _file->seekg(0); |
| 3724 | string line; |
| 3725 | unsigned line_idx; |
| 3726 | |
| 3727 | for (line_idx = 1; line_idx < line_start; ++line_idx) { |
| 3728 | std::getline(*_file, line); |
| 3729 | if (!*_file) { |
| 3730 | return lines; |
| 3731 | } |
| 3732 | } |
| 3733 | |
| 3734 | // think of it like a lambda in C++98 ;) |
| 3735 | // but look, I will reuse it two times! |
| 3736 | // What a good boy am I. |
| 3737 | struct isspace { |
| 3738 | bool operator()(char c) { return std::isspace(c); } |
| 3739 | }; |
| 3740 | |
| 3741 | bool started = false; |
| 3742 | for (; line_idx < line_start + line_count; ++line_idx) { |
| 3743 | getline(*_file, line); |
| 3744 | if (!*_file) { |
no test coverage detected