diff --git a/lsp-server/src/main.cpp b/lsp-server/src/main.cpp index 6f78723..76c1110 100644 --- a/lsp-server/src/main.cpp +++ b/lsp-server/src/main.cpp @@ -8,7 +8,7 @@ int main(int argc, char* argv[]) { - lsp::utils::ArgsParser& args_parser = lsp::utils::ArgsParser::GetInstance(); + lsp::utils::ArgsParser& args_parser = lsp::utils::ArgsParser::Instance(); auto& config = args_parser.Parse(argc, argv); if (config.show_help) diff --git a/lsp-server/src/service/base/bootstrap.cpp b/lsp-server/src/service/base/bootstrap.cpp index a1694b9..cfd3911 100644 --- a/lsp-server/src/service/base/bootstrap.cpp +++ b/lsp-server/src/service/base/bootstrap.cpp @@ -15,7 +15,7 @@ namespace lsp::service { spdlog::info("Registering LSP services..."); - auto& config = utils::ArgsParser::GetInstance().GetConfig(); + auto& config = utils::ArgsParser::Instance().GetConfig(); std::shared_ptr event_bus = std::make_shared(); std::shared_ptr document = std::make_shared(event_bus); std::shared_ptr parser = std::make_shared(event_bus); diff --git a/lsp-server/src/utils/args_parser.cpp b/lsp-server/src/utils/args_parser.cpp index 00eb57d..61997e8 100644 --- a/lsp-server/src/utils/args_parser.cpp +++ b/lsp-server/src/utils/args_parser.cpp @@ -5,7 +5,7 @@ namespace lsp::utils { - ArgsParser& ArgsParser::GetInstance() + ArgsParser& ArgsParser::Instance() { static ArgsParser instance; return instance; diff --git a/lsp-server/src/utils/args_parser.hpp b/lsp-server/src/utils/args_parser.hpp index 06c5504..581ad00 100644 --- a/lsp-server/src/utils/args_parser.hpp +++ b/lsp-server/src/utils/args_parser.hpp @@ -19,7 +19,7 @@ namespace lsp::utils public: ArgsParser(const ArgsParser&) = delete; ArgsParser& operator=(const ArgsParser&) = delete; - static ArgsParser& GetInstance(); + static ArgsParser& Instance(); const ServerConfig& Parse(int argc, char* argv[]); const ServerConfig& GetConfig() const; diff --git a/lsp-server/src/utils/string.cpp b/lsp-server/src/utils/string.cpp index 57b4316..81415be 100644 --- a/lsp-server/src/utils/string.cpp +++ b/lsp-server/src/utils/string.cpp @@ -9,34 +9,104 @@ namespace lsp::utils if (first == std::string::npos) return ""; size_t last = str.find_last_not_of(" \t\n\r"); - return str.substr(first, (last - first + 1)); + return str.substr(first, last - first + 1); } std::string ToLower(const std::string& str) { std::string result = str; - std::transform(result.begin(), result.end(), result.begin(), ::tolower); + std::transform(result.begin(), result.end(), result.begin(), [](unsigned char c) { return std::tolower(c); }); return result; } - bool StartsWithIgnoreCase(const std::string& str, const std::string& prefix) + std::string ToUpper(const std::string& str) + { + std::string result = str; + std::transform(result.begin(), result.end(), result.begin(), [](unsigned char c) { return std::toupper(c); }); + return result; + } + + bool StartsWith(const std::string& str, const std::string& prefix) + { + if (prefix.size() > str.size()) + return false; + return str.compare(0, prefix.size(), prefix) == 0; + } + + bool EndsWith(const std::string& str, const std::string& suffix) + { + if (suffix.size() > str.size()) + return false; + return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; + } + + // ==================== 大小写不敏感比较 ==================== + bool IEquals(const std::string& a, const std::string& b) + { + if (a.size() != b.size()) + return false; + + return std::equal(a.begin(), a.end(), b.begin(), [](unsigned char ca, unsigned char cb) { + return std::tolower(ca) == std::tolower(cb); + }); + } + + bool IStartsWith(const std::string& str, const std::string& prefix) { if (prefix.size() > str.size()) return false; for (size_t i = 0; i < prefix.size(); ++i) - if (std::tolower(str[i]) != std::tolower(prefix[i])) + { + if (std::tolower(static_cast(str[i])) != + std::tolower(static_cast(prefix[i]))) return false; + } return true; } - bool StartsWith(const std::string& str, const std::string& prefix, bool ignoreCase) + bool IEndsWith(const std::string& str, const std::string& suffix) { - if (ignoreCase) - return StartsWithIgnoreCase(str, prefix); - - if (prefix.size() > str.size()) + if (suffix.size() > str.size()) return false; - return str.compare(0, prefix.size(), prefix) == 0; + + size_t offset = str.size() - suffix.size(); + for (size_t i = 0; i < suffix.size(); ++i) + { + if (std::tolower(static_cast(str[offset + i])) != + std::tolower(static_cast(suffix[i]))) + return false; + } + return true; + } + + int ICompare(const std::string& a, const std::string& b) + { + size_t min_len = std::min(a.size(), b.size()); + + for (size_t i = 0; i < min_len; ++i) + { + int ca = std::tolower(static_cast(a[i])); + int cb = std::tolower(static_cast(b[i])); + + if (ca != cb) + return ca - cb; + } + + // 长度不同 + if (a.size() < b.size()) + return -1; + if (a.size() > b.size()) + return 1; + + return 0; + } + + size_t IHash(const std::string& str) + { + size_t hash = 0; + for (unsigned char c : str) + hash = hash * 31 + std::tolower(c); + return hash; } } diff --git a/lsp-server/src/utils/string.hpp b/lsp-server/src/utils/string.hpp index bed1bd1..108ecc1 100644 --- a/lsp-server/src/utils/string.hpp +++ b/lsp-server/src/utils/string.hpp @@ -4,8 +4,44 @@ namespace lsp::utils { + // ==================== 字符串工具 ==================== std::string Trim(const std::string& str); std::string ToLower(const std::string& str); - bool StartsWith(const std::string& str, const std::string& prefix, bool ignoreCase = true); - bool StartsWithIgnoreCase(const std::string& str, const std::string& prefix); + std::string ToUpper(const std::string& str); + + // ==================== 大小写敏感比较 ==================== + bool StartsWith(const std::string& str, const std::string& prefix); + bool EndsWith(const std::string& str, const std::string& suffix); + + // ==================== 大小写不敏感比较 ==================== + bool IEquals(const std::string& a, const std::string& b); + bool IStartsWith(const std::string& str, const std::string& prefix); + bool IEndsWith(const std::string& str, const std::string& suffix); + int ICompare(const std::string& a, const std::string& b); + size_t IHash(const std::string& str); + + // ==================== STL 容器比较器 ==================== + struct IHasher + { + size_t operator()(const std::string& key) const + { + return IHash(key); + } + }; + + struct IEqualTo + { + bool operator()(const std::string& a, const std::string& b) const + { + return IEquals(a, b); + } + }; + + struct ILess + { + bool operator()(const std::string& a, const std::string& b) const + { + return ICompare(a, b) < 0; + } + }; }