#include "scpi/externinterface.h" #include #include #include #include // 全局变量定义 CPatternResult* g_pattern_results = nullptr; int g_pattern_count = 0; class Segment { public: bool is_required = false; bool is_variable = false; bool is_nested = false; int variableSize = 0; std::vector options; }; class PatternParser { private: //清除空格 static void trim_whitespace(std::string& str) { auto not_space = [](int ch) { return !std::isspace(ch); }; str.erase(str.begin(), std::find_if(str.begin(), str.end(), not_space)); str.erase(std::find_if(str.rbegin(), str.rend(), not_space).base(), str.end()); } //拆分可选参数 static std::vector split_options(const std::string& input) { std::vector result; size_t start = 0; size_t end = input.find('|'); while (end != std::string::npos) { std::string token = input.substr(start, end - start); trim_whitespace(token); if (!token.empty()) result.push_back(token); start = end + 1; end = input.find('|', start); } std::string last_token = input.substr(start); trim_whitespace(last_token); last_token = remove_colon(last_token); if (!last_token.empty()) result.push_back(last_token); return result; } //删掉可能携带的:分割符 static std::string remove_colon(const std::string& input) { std::string result; for (char ch : input) { if (ch != ':') { result += ch; } } return result; } public: static std::vector parse_input_data(const std::string& input) { std::vector result; size_t start = 0; size_t end = input.find(':'); while (end != std::string::npos) { result.push_back(input.substr(start, end - start)); start = end + 1; end = input.find(':', start); } result.push_back(input.substr(start)); return result; } static bool match_all_segments(const std::vector& stringList, const std::vector& vecSegment) { int currentIndex = 0; for (size_t i = 0; i < vecSegment.size(); i++) { auto currentSegment = vecSegment[i]; if (currentSegment.is_required) { for (const auto& option : currentSegment.options) { //当索引index超过输入参数的词组大小 则表示命令不匹配 if(currentIndex >= stringList.size()) { return false; } if (stringList[currentIndex] != option) { return false; } else { currentIndex += 1; } break; } } else if (currentSegment.is_variable) { if (stringList.size() == vecSegment.size()) { auto vecTempSegments = currentSegment.options; for (const auto& option : vecTempSegments) { if (stringList[currentIndex] != option) { return false; } else { currentIndex += 1; } break; } } } else { currentIndex += 1; } } return true; } static std::vector extract_all_segments(const std::string& pattern) { std::vector segments; size_t pos = 0; const size_t len = pattern.length(); while (pos < len) { while (pos < len && std::isspace(pattern[pos])) ++pos; if (pos >= len) break; if (pattern[pos] == '<') { size_t end_pos = pattern.find('>', pos); if (end_pos == std::string::npos) break; std::string content = pattern.substr(pos + 1, end_pos - pos - 1); trim_whitespace(content); Segment segment; segment.is_variable = false; segment.options = split_options(content); if (content.find(':') != std::string::npos) { segment.is_required = true; } else { segment.is_required = false; } segments.push_back(segment); pos = end_pos + 1; } else if (pattern[pos] == '[') { size_t end_pos = pattern.find(']', pos); if (end_pos == std::string::npos) break; std::string content = pattern.substr(pos + 1, end_pos - pos - 1); trim_whitespace(content); Segment segment; segment.variableSize += 1; segment.is_required = false; segment.is_variable = true; segment.options = split_options(content); segments.push_back(segment); pos = end_pos + 1; } else { size_t next_lt = pattern.find('<', pos); size_t next_lb = pattern.find('[', pos); size_t next_special = std::min(next_lt, next_lb); std::string content; if (next_special != std::string::npos) { content = pattern.substr(pos, next_special - pos); } else { content = pattern.substr(pos); } trim_whitespace(content); if (!content.empty()) { size_t start = 0; size_t end = content.find(':'); while (end != std::string::npos) { std::string token = content.substr(start, end - start); trim_whitespace(token); if (!token.empty()) { Segment segment; segment.is_required = true; segment.is_variable = false; segment.options.push_back(token); segments.push_back(segment); } start = end + 1; end = content.find(':', start); } std::string last_token = content.substr(start); trim_whitespace(last_token); if (!last_token.empty()) { Segment segment; segment.is_required = true; segment.is_variable = false; segment.options.push_back(last_token); segments.push_back(segment); } } pos = (next_special != std::string::npos) ? next_special : len; } } return segments; } }; // 全局管理函数实现 void add_pattern_to_global(const std::vector& segments) { // 重新分配内存 CPatternResult* new_results = new CPatternResult[g_pattern_count + 1]; // 复制旧数据 for (int i = 0; i < g_pattern_count; ++i) { new_results[i] = g_pattern_results[i]; } // 添加新数据 CPatternResult& new_item = new_results[g_pattern_count]; new_item.segments_count = static_cast(segments.size()); new_item.segments = new CSegment[segments.size()]; for (size_t i = 0; i < segments.size(); ++i) { const auto& seg = segments[i]; new_item.segments[i].is_required = seg.is_required; new_item.segments[i].is_variable = seg.is_variable; new_item.segments[i].is_nested = seg.is_nested; new_item.segments[i].variableSize = seg.variableSize; new_item.segments[i].options_count = static_cast(seg.options.size()); new_item.segments[i].options = new char*[seg.options.size()]; for (size_t j = 0; j < seg.options.size(); ++j) { new_item.segments[i].options[j] = strdup(seg.options[j].c_str()); } } // 释放旧内存并更新指针 delete[] g_pattern_results; g_pattern_results = new_results; g_pattern_count++; } void clear_global_patterns() { for (int i = 0; i < g_pattern_count; ++i) { for (int j = 0; j < g_pattern_results[i].segments_count; ++j) { for (int k = 0; k < g_pattern_results[i].segments[j].options_count; ++k) { free(g_pattern_results[i].segments[j].options[k]); } delete[] g_pattern_results[i].segments[j].options; } delete[] g_pattern_results[i].segments; } delete[] g_pattern_results; g_pattern_results = nullptr; g_pattern_count = 0; } int get_pattern_count() { return g_pattern_count; } void parse_pattern_global(const char* pattern) { auto segments = PatternParser::extract_all_segments(pattern); add_pattern_to_global(segments); } int match_segments_global(const char* input, int pattern_index) { if (pattern_index < 0 || pattern_index >= g_pattern_count) { return 0; } std::string inputStr(input); inputStr.erase(std::remove(inputStr.begin(), inputStr.end(), '\n'), inputStr.end()); std::vector inputList; size_t start = 0; size_t end = inputStr.find(':'); while (end != std::string::npos) { inputList.push_back(inputStr.substr(start, end - start)); start = end + 1; end = inputStr.find(':', start); } inputList.push_back(inputStr.substr(start)); std::vector segments; CPatternResult& pattern = g_pattern_results[pattern_index]; for (int i = 0; i < pattern.segments_count; ++i) { Segment seg; seg.is_required = pattern.segments[i].is_required; seg.is_variable = pattern.segments[i].is_variable; seg.is_nested = pattern.segments[i].is_nested; seg.variableSize = pattern.segments[i].variableSize; for (int j = 0; j < pattern.segments[i].options_count; ++j) { seg.options.push_back(pattern.segments[i].options[j]); } segments.push_back(seg); } return PatternParser::match_all_segments(inputList, segments) ? 1 : 0; }