diff options
Diffstat (limited to 'src/util.cc')
-rw-r--r-- | src/util.cc | 202 |
1 files changed, 134 insertions, 68 deletions
diff --git a/src/util.cc b/src/util.cc index 73b158d..20dea71 100644 --- a/src/util.cc +++ b/src/util.cc @@ -6,11 +6,19 @@ #include <iostream> #include <fstream> #include <algorithm> +#include <sstream> + +namespace { +char to_lower_c(char ch) +{ + return static_cast<char>(::tolower(ch)); +} +} std::string to_lower(const std::string& str) { std::string out{str}; - std::transform(out.begin(), out.end(), out.begin(), ::tolower); + std::transform(out.begin(), out.end(), out.begin(), to_lower_c); return out; } @@ -19,73 +27,18 @@ std::string readFile(const std::string& fileName) std::ifstream ifs(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - std::ifstream::pos_type fileSize = ifs.tellg(); - ifs.seekg(0, std::ios::beg); - - std::vector<char> bytes(static_cast<std::size_t>(fileSize)); - ifs.read(bytes.data(), fileSize); - - return {bytes.data(), static_cast<std::size_t>(fileSize)}; -} - -std::vector<std::string> readDeps(const std::string& depFile) -{ - if(!std::filesystem::exists(depFile)) + auto tell = ifs.tellg(); + if(tell < 0) { return {}; } + auto fileSize = static_cast<std::size_t>(tell); + ifs.seekg(0, std::ios::beg); - auto str = readFile(depFile); - - std::vector<std::string> output; - std::string tmp; - bool start{false}; - bool in_whitespace{false}; - for(const auto& c : str) - { - if(c == '\\' || c == '\n') - { - continue; - } - - if(c == ':') - { - start = true; - continue; - } - - if(!start) - { - continue; - } - - if(c == ' ' || c == '\t') - { - if(in_whitespace) - { - continue; - } - - if(!tmp.empty()) - { - output.push_back(tmp); - } - tmp.clear(); - in_whitespace = true; - } - else - { - in_whitespace = false; - tmp += c; - } - } - - if(!tmp.empty()) - { - output.push_back(tmp); - } + std::vector<char> bytes(fileSize); + ifs.read(bytes.data(), static_cast<long>(bytes.size())); - return output; + return { bytes.data(), bytes.size() }; } ctor::language languageFromExtension(const std::filesystem::path& file) @@ -130,7 +83,7 @@ namespace { bool isClean(char c) { - return c != '.' && c != '/'; + return c != '.' && c != '/' && c != '\\'; } } @@ -229,18 +182,131 @@ std::string locate(const std::string& prog, } } + if(std::filesystem::exists(program + ".exe")) + { + if(check_executable(program + ".exe")) + { + return program + ".exe"; + } + } + for(const auto& path_str : paths) { std::filesystem::path path(path_str); - auto prog_path = path / program; - if(std::filesystem::exists(prog_path)) { - if(check_executable(prog_path)) + auto prog_path = path / program; + if(std::filesystem::exists(prog_path)) + { + if(check_executable(prog_path)) + { + return prog_path.string(); + } + } + } + + { + auto prog_path = path / (program + ".exe"); + if(std::filesystem::exists(prog_path)) { - return prog_path.string(); + if(check_executable(prog_path)) + { + return prog_path.string(); + } } } } return {}; } + +std::vector<std::string> argsplit(const std::string& str) +{ + enum class state + { + normal, + in_quot, + in_apotrophe, + } state{state::normal}; + bool esc{false}; + + std::string token; + std::vector<std::string> tokens; + for(auto c : str) + { + switch(state) + { + case state::normal: + if(esc) + { + esc = false; + } + else + { + if(c == ' ') + { + tokens.push_back(token); + token.clear(); + continue; + } + if(c == '\\') + { + esc = true; + } + if(c == '"') + { + state = state::in_quot; + } + if(c == '\'') + { + state = state::in_apotrophe; + } + } + + token += c; + break; + case state::in_quot: + if(esc) + { + esc = false; + } + else + { + if(c == '\\') + { + esc = true; + } + if(c == '"') + { + state = state::normal; + } + } + + token += c; + break; + case state::in_apotrophe: + if(esc) + { + esc = false; + } + else + { + if(c == '\\') + { + esc = true; + } + if(c == '\'') + { + state = state::normal; + } + } + + token += c; + break; + } + } + if(!token.empty()) + { + tokens.push_back(token); + } + return tokens; +} |