nancy.liao
2025-05-08 bf8143c649292042de87c0cef63e6cb3c523388f
libscpi/src/utils.c
@@ -319,7 +319,7 @@
 */
size_t strToFloat(const char * str, float * val) {
    char * endptr;
    *val = SCPIDEFINE_strtof(str, &endptr);
    *val = (float)SCPIDEFINE_strtof(str, &endptr);
    return endptr - str;
}
@@ -480,13 +480,13 @@
    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);
@@ -512,7 +512,7 @@
    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);
@@ -548,9 +548,9 @@
    }
    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)) {
@@ -584,7 +584,7 @@
            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++;
@@ -677,7 +677,7 @@
//组合复合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)
@@ -741,8 +741,8 @@
    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;
        }
@@ -958,7 +958,7 @@
    if (fi != 0) {
        r1 = r1 * 308 / 1024 - ndigits;
        w2 = bufsize;
        w2 = (int)bufsize;
        while (r1 > 0) {
            fj = modf(fi / 10, &fi);
            r2++;
@@ -966,7 +966,7 @@
        }
        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++];
@@ -985,7 +985,7 @@
    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';
@@ -1143,142 +1143,4 @@
           ((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);
}