| | |
| | | ((val & 0xFF00000000000000ull) >> 56); |
| | | } |
| | | |
| | | int parse_pattern(const char* pattern, Segment segments[], int max_segments) { |
| | | int seg_count = 0; |
| | | const char* p = pattern; |
| | | |
| | | while (*p && seg_count < max_segments) |
| | | // 用于提取并处理选项的函数 |
| | | int extract_required_options(const char* pattern, char options[MAX_TAGS][MAX_OPTION_LEN][MAX_OPTION_LEN], int max_tags) { |
| | | const char* start = strchr(pattern, '<'); // 查找第一个 '<' |
| | | const char* end = NULL; |
| | | int tag_count = 0; |
| | | |
| | | // 处理 <...> 内的选项 |
| | | while (start != NULL && tag_count < max_tags) |
| | | { |
| | | if (*p == '[') |
| | | { |
| | | // 处理可变段 |
| | | segments[seg_count].is_variable = TRUE; |
| | | // 跳过'[' |
| | | p++; |
| | | end = strchr(start, '>'); // 查找对应的 '>' |
| | | |
| | | int i = 0; |
| | | while (*p && *p != ']' && i < sizeof(segments[seg_count].text)-1) |
| | | { |
| | | segments[seg_count].text[i++] = toupper(*p++); |
| | | } |
| | | segments[seg_count].text[i] = '\0'; |
| | | |
| | | if (*p == ']') |
| | | { |
| | | // 跳过']' |
| | | p++; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // 处理固定段 |
| | | segments[seg_count].is_variable = FALSE; |
| | | |
| | | int i = 0; |
| | | while (*p && *p != '[' && i < sizeof(segments[seg_count].text)-1) |
| | | { |
| | | segments[seg_count].text[i++] = toupper(*p++); |
| | | } |
| | | segments[seg_count].text[i] = '\0'; |
| | | if (end == NULL) { |
| | | break; // 如果没有找到 '>',则退出 |
| | | } |
| | | |
| | | seg_count++; |
| | | // 提取 <...> 中的内容 |
| | | int len = end - start - 1; |
| | | if (len > 0 && len < MAX_OPTION_LEN) { |
| | | char buffer[MAX_OPTION_LEN]; |
| | | strncpy(buffer, start + 1, len); // 复制 '<' 和 '>' 之间的内容 |
| | | buffer[len] = '\0'; // 结束符 |
| | | |
| | | // 处理 | 分隔符,提取多个选项 |
| | | char* token = strtok(buffer, "|"); |
| | | int option_count = 0; |
| | | while (token && option_count < MAX_OPTION_LEN) { |
| | | // 去除 token 中的 "[:", "]" 和空格 |
| | | char* p = token; |
| | | while (*p == ' ' || *p == '[' || *p == ':') p++; // 去除前导空格和 [: |
| | | char* q = p + strlen(p) - 1; |
| | | while (q > p && (*q == ' ' || *q == ']')) q--; // 去除尾随空格和 ] |
| | | *(q + 1) = '\0'; // 确保结尾是'\0' |
| | | |
| | | // 拷贝选项到 options 数组 |
| | | if (option_count < MAX_OPTION_LEN) { // 确保不会越界 |
| | | strncpy(options[tag_count][option_count], p, MAX_OPTION_LEN - 1); |
| | | options[tag_count][option_count][MAX_OPTION_LEN - 1] = '\0'; // 确保结束符 |
| | | option_count++; |
| | | } |
| | | token = strtok(NULL, "|"); |
| | | } |
| | | } |
| | | |
| | | // 移动到下一个 '<' 位置,继续查找 |
| | | start = strchr(end + 1, '<'); |
| | | tag_count++; |
| | | } |
| | | |
| | | return seg_count; |
| | | return tag_count; |
| | | } |
| | | |
| | | // 匹配命令与模式 |
| | | bool match_command(const char* command, Segment segments[], int seg_count) |
| | | { |
| | | const char* cmd = command; |
| | | int current_seg = 0; |
| | | // 用于检查输入是否能匹配每一组选项 |
| | | int match_input_to_options(const char* input, char options[MAX_TAGS][MAX_OPTION_LEN][MAX_OPTION_LEN], int num_tags) { |
| | | char input_copy[MAX_INPUT_LEN]; |
| | | strncpy(input_copy, input, MAX_INPUT_LEN - 1); |
| | | input_copy[MAX_INPUT_LEN - 1] = '\0'; // 确保结尾是'\0' |
| | | |
| | | while (*cmd && current_seg < seg_count) |
| | | { |
| | | // 跳过命令中的分隔符(冒号) |
| | | if (*cmd == ':') |
| | | { |
| | | cmd++; |
| | | // 模式中也应该有对应的分隔符 |
| | | if (segments[current_seg].text[0] != ':') |
| | | { |
| | | return FALSE; |
| | | // 拆分输入字符串,按 ":" 分割 |
| | | char* token = strtok(input_copy, ":"); |
| | | int group_idx = 0; |
| | | |
| | | // 对每一组进行匹配 |
| | | while (token != NULL && group_idx < num_tags) { |
| | | int match_found = 0; |
| | | // 检查当前组的每个选项是否与输入的 token 匹配 |
| | | printf("Checking input token: '%s' against group %d options\n", token, group_idx + 1); // Debug info |
| | | for (int i = 0; i < MAX_OPTION_LEN && options[group_idx][i][0] != '\0'; i++) { |
| | | printf(" Comparing with option: '%s'\n", options[group_idx][i]); // Debug info |
| | | if (strcmp(options[group_idx][i], token) == 0) { |
| | | match_found = 1; |
| | | break; |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | // 获取当前段长度 |
| | | size_t seg_len = strlen(segments[current_seg].text); |
| | | |
| | | if (segments[current_seg].is_variable) |
| | | { |
| | | // 可变段 - 跳过对应长度的字符 |
| | | int i = 0; |
| | | while (*cmd && *cmd != ':' && i < seg_len) |
| | | { |
| | | cmd++; |
| | | i++; |
| | | } |
| | | } else |
| | | { |
| | | // 固定段 - 必须精确匹配 |
| | | if (strncasecmp(cmd, segments[current_seg].text, seg_len) != 0) |
| | | { |
| | | return FALSE; |
| | | } |
| | | cmd += seg_len; |
| | | // 如果当前组的某个选项没有匹配上,返回 false |
| | | if (!match_found) { |
| | | return 0; // 不匹配 |
| | | } |
| | | |
| | | current_seg++; |
| | | // 处理下一个输入部分 |
| | | token = strtok(NULL, ":"); |
| | | group_idx++; |
| | | } |
| | | |
| | | // 检查是否处理完所有命令和所有段 |
| | | return (*cmd == '\0') && (current_seg == seg_count); |
| | | return (group_idx == num_tags); |
| | | } |
| | | |
| | | // 测试函数 |
| | | |
| | | // 测试匹配函数 |
| | | bool test_match(const char* pattern, const char* command) |
| | | { |
| | | Segment segments[16]; |
| | | int seg_count = parse_pattern(pattern, segments, 16); |
| | | return (match_command(command, segments, seg_count)); |
| | | |
| | | char options[MAX_TAGS][MAX_OPTION_LEN][MAX_OPTION_LEN] = { {{0}} }; |
| | | int num_tags = extract_required_options(pattern, options, MAX_TAGS); |
| | | return match_input_to_options(command, options, num_tags); |
| | | } |
| | | |
| | | |