| | |
| | | */ |
| | | size_t strToFloat(const char * str, float * val) { |
| | | char * endptr; |
| | | *val = SCPIDEFINE_strtof(str, &endptr); |
| | | *val = (float)SCPIDEFINE_strtof(str, &endptr); |
| | | return endptr - str; |
| | | } |
| | | |
| | |
| | | if ((pattern_len > 0) && pattern[pattern_len - 1] == '#') { |
| | | size_t new_pattern_len = pattern_len - 1; |
| | | |
| | | pattern_sep_pos_short = patternSeparatorShortPos(pattern, new_pattern_len); |
| | | pattern_sep_pos_short = (int)patternSeparatorShortPos(pattern, new_pattern_len); |
| | | |
| | | return compareStrAndNum(pattern, new_pattern_len, str, str_len, num) || |
| | | compareStrAndNum(pattern, pattern_sep_pos_short, str, str_len, num); |
| | | } else { |
| | | |
| | | pattern_sep_pos_short = patternSeparatorShortPos(pattern, pattern_len); |
| | | pattern_sep_pos_short = (int)patternSeparatorShortPos(pattern, pattern_len); |
| | | |
| | | return compareStr(pattern, pattern_len, str, str_len) || |
| | | compareStr(pattern, pattern_sep_pos_short, str, str_len); |
| | |
| | | int32_t *number_ptr = NULL; |
| | | |
| | | const char * pattern_ptr = pattern; |
| | | int pattern_len = strlen(pattern); |
| | | int pattern_len = (int)strlen(pattern); |
| | | |
| | | const char * cmd_ptr = cmd; |
| | | size_t cmd_len = SCPIDEFINE_strnlen(cmd, len); |
| | |
| | | } |
| | | |
| | | while (1) { |
| | | int pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_len); |
| | | int pattern_sep_pos = (int)patternSeparatorPos(pattern_ptr, pattern_len); |
| | | |
| | | cmd_sep_pos = cmdSeparatorPos(cmd_ptr, cmd_len); |
| | | cmd_sep_pos = (int)cmdSeparatorPos(cmd_ptr, cmd_len); |
| | | |
| | | if ((pattern_sep_pos > 0) && pattern_ptr[pattern_sep_pos - 1] == '#') { |
| | | if (numbers && (numbers_idx < numbers_len)) { |
| | |
| | | if (cmd_len == 0) { |
| | | /* verify all subsequent pattern parts are also optional */ |
| | | while (pattern_len) { |
| | | pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_len); |
| | | pattern_sep_pos = (int)patternSeparatorPos(pattern_ptr, pattern_len); |
| | | switch (pattern_ptr[pattern_sep_pos]) { |
| | | case '[': |
| | | brackets++; |
| | |
| | | |
| | | //组合复合SCPI命令 |
| | | scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) { |
| | | size_t i; |
| | | int i; |
| | | |
| | | /* Invalid input */ |
| | | if (current == NULL || current->ptr == NULL || current->len == 0) |
| | |
| | | unsigned char c1, c2; |
| | | |
| | | for (; n != 0; n--) { |
| | | c1 = tolower((unsigned char) *s1++); |
| | | c2 = tolower((unsigned char) *s2++); |
| | | c1 = (unsigned char)tolower((unsigned char) *s1++); |
| | | c2 = (unsigned char)tolower((unsigned char) *s2++); |
| | | if (c1 != c2) { |
| | | return c1 - c2; |
| | | } |
| | |
| | | |
| | | if (fi != 0) { |
| | | r1 = r1 * 308 / 1024 - ndigits; |
| | | w2 = bufsize; |
| | | w2 = (int)bufsize; |
| | | while (r1 > 0) { |
| | | fj = modf(fi / 10, &fi); |
| | | r2++; |
| | |
| | | } |
| | | while (fi != 0) { |
| | | fj = modf(fi / 10, &fi); |
| | | buf[--w2] = (int) ((fj + .03) * 10) + '0'; |
| | | buf[--w2] = (char) ((fj + .03) * 10) + '0'; |
| | | r2++; |
| | | } |
| | | while (w2 < (int) bufsize) buf[w1++] = buf[w2++]; |
| | |
| | | while (w1 <= w2 && w1 < (int) bufsize) { |
| | | arg *= 10; |
| | | arg = modf(arg, &fj); |
| | | buf[w1++] = (int) fj + '0'; |
| | | buf[w1++] = (char) fj + '0'; |
| | | } |
| | | if (w2 >= (int) bufsize) { |
| | | buf[bufsize - 1] = '\0'; |
| | |
| | | ((val & 0x0000FF0000000000ull) >> 24) | |
| | | ((val & 0x00FF000000000000ull) >> 40) | |
| | | ((val & 0xFF00000000000000ull) >> 56); |
| | | } |
| | | |
| | | |
| | | // 解析模式,将每个部分保存到 segments 中 |
| | | 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) { |
| | | if (*p == '[') { |
| | | // 处理可变段([]) |
| | | segments[seg_count].is_variable = TRUE; |
| | | segments[seg_count].is_required = FALSE; // []是可选的 |
| | | segments[seg_count].is_option = FALSE; |
| | | p++; // 跳过'[' |
| | | |
| | | 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 if (*p == '<') { |
| | | // 处理必选段(<>) |
| | | segments[seg_count].is_variable = TRUE; |
| | | segments[seg_count].is_required = TRUE; // <>是必选的 |
| | | segments[seg_count].is_option = FALSE; |
| | | p++; // 跳过'<' |
| | | |
| | | 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 if (*p == '|') { |
| | | // 处理竖线分隔的多选部分(|) |
| | | segments[seg_count].is_variable = TRUE; |
| | | segments[seg_count].is_required = TRUE; // 选项是必选的 |
| | | segments[seg_count].is_option = TRUE; // 这表示选项组 |
| | | p++; // 跳过'|' |
| | | |
| | | int i = 0; |
| | | while (*p && *p != '|' && *p != '>' && *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; |
| | | segments[seg_count].is_required = TRUE; // 固定段必选 |
| | | segments[seg_count].is_option = FALSE; |
| | | int i = 0; |
| | | while (*p && *p != '[' && *p != '<' && *p != '|' && *p != ':' && i < sizeof(segments[seg_count].text) - 1) { |
| | | segments[seg_count].text[i++] = toupper(*p++); |
| | | } |
| | | segments[seg_count].text[i] = '\0'; // 结束符 |
| | | } |
| | | |
| | | seg_count++; |
| | | } |
| | | |
| | | return seg_count; |
| | | } |
| | | |
| | | // 匹配命令字符串是否符合模式 |
| | | bool match_command(const char* command, Segment segments[], int seg_count) { |
| | | const char* cmd = command; |
| | | int current_seg = 0; |
| | | |
| | | while (*cmd && current_seg < seg_count) { |
| | | // 按冒号分隔命令 |
| | | if (*cmd == ':') { |
| | | cmd++; // 跳过分隔符 |
| | | 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 (segments[current_seg].is_option) { |
| | | // 选项组 - 必须匹配其中一个选项 |
| | | bool matched = FALSE; |
| | | const char* options[] = { segments[current_seg].text, NULL }; |
| | | for (int i = 0; options[i]; i++) { |
| | | if (strncasecmp(cmd, options[i], strlen(options[i])) == 0) { |
| | | matched = TRUE; |
| | | break; |
| | | } |
| | | } |
| | | if (!matched) { |
| | | return FALSE; |
| | | } |
| | | cmd += strlen(options[0]); |
| | | } |
| | | else { |
| | | // 固定段 - 必须精确匹配 |
| | | if (strncasecmp(cmd, segments[current_seg].text, seg_len) != 0) { |
| | | return FALSE; |
| | | } |
| | | cmd += seg_len; // 跳过匹配的部分 |
| | | } |
| | | |
| | | current_seg++; |
| | | } |
| | | |
| | | // 检查是否处理完所有命令和所有段 |
| | | return (*cmd == '\0') && (current_seg == seg_count); |
| | | } |
| | | |
| | | // 测试匹配函数 |
| | | bool test_match(const char* pattern, const char* command) |
| | | { |
| | | |
| | | Segment segments[MAX_SEGMENTS]; |
| | | int seg_count = parse_pattern(pattern, segments, MAX_SEGMENTS); |
| | | return match_command(command, segments, seg_count); |
| | | } |