aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/vcpkg_Files.cpp
blob: 57d4c665cf177c4e3765b375174a1d0c7eeef5c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "pch.h"
#include "vcpkg_Files.h"
#include "vcpkg_System.h"

namespace vcpkg::Files
{
    static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])");

    void check_is_directory(const fs::path& dirpath)
    {
        Checks::check_exit(fs::is_directory(dirpath), "The path %s is not a directory", dirpath.string());
    }

    bool has_invalid_chars_for_filesystem(const std::string& s)
    {
        return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX);
    }

    expected<std::string> read_contents(const fs::path& file_path) noexcept
    {
        std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
        if (file_stream.fail())
        {
            return std::errc::no_such_file_or_directory;
        }

        file_stream.seekg(0, file_stream.end);
        auto length = file_stream.tellg();
        file_stream.seekg(0, file_stream.beg);

        if (length > SIZE_MAX)
        {
            return std::errc::file_too_large;
        }

        std::string output;
        output.resize(static_cast<size_t>(length));
        file_stream.read(&output[0], length);
        file_stream.close();

        return std::move(output);
    }

    expected<std::vector<std::string>> read_all_lines(const fs::path& file_path)
    {
        std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
        if (file_stream.fail())
        {
            return std::errc::no_such_file_or_directory;
        }

        std::vector<std::string> output;
        std::string line;
        while (std::getline(file_stream, line))
        {
            output.push_back(line);
        }
        file_stream.close();

        return std::move(output);
    }

    void write_all_lines(const fs::path& file_path, const std::vector<std::string>& lines)
    {
        std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
        for (const std::string& line : lines)
        {
            output << line << "\n";
        }
        output.close();
    }

    fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename)
    {
        fs::path current_dir = starting_dir;
        for (; !current_dir.empty(); current_dir = current_dir.parent_path())
        {
            const fs::path candidate = current_dir / filename;
            if (fs::exists(candidate))
            {
                break;
            }
        }

        return current_dir;
    }

    void recursive_find_files_with_extension_in_dir(const fs::path& dir, const std::string& extension, std::vector<fs::path>* output)
    {
        recursive_find_matching_paths_in_dir(dir, [&extension](const fs::path& current)
                                             {
                                                 return !fs::is_directory(current) && current.extension() == extension;
                                             }, output);
    }

    std::vector<fs::path> recursive_find_files_with_extension_in_dir(const fs::path& dir, const std::string& extension)
    {
        std::vector<fs::path> v;
        recursive_find_files_with_extension_in_dir(dir, extension, &v);
        return v;
    }

    void recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output)
    {
        recursive_find_matching_paths_in_dir(dir, [](const fs::path& current)
                                             {
                                                 return !fs::is_directory(current);
                                             }, output);
    }

    std::vector<fs::path> recursive_find_all_files_in_dir(const fs::path& dir)
    {
        std::vector<fs::path> v;
        recursive_find_all_files_in_dir(dir, &v);
        return v;
    }

    void non_recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output)
    {
        non_recursive_find_matching_paths_in_dir(dir, [](const fs::path& current)
                                                 {
                                                     return !fs::is_directory(current);
                                                 }, output);
    }

    std::vector<fs::path> non_recursive_find_all_files_in_dir(const fs::path& dir)
    {
        std::vector<fs::path> v;
        non_recursive_find_all_files_in_dir(dir, &v);
        return v;
    }

    void print_paths(const std::vector<fs::path>& paths)
    {
        System::println("");
        for (const fs::path& p : paths)
        {
            System::println("    %s", p.generic_string());
        }
        System::println("");
    }
}