Example #1
0
/**
 * Compare pattern and command
 * @param pattern
 * @param cmd - command
 * @param len - max search length
 * @return TRUE if pattern matches, FALSE otherwise
 */
bool_t matchCommand(const char * pattern, const char * cmd, size_t len) {
    int result = FALSE;
    
    const char * pattern_ptr = pattern;
    int pattern_len = strlen(pattern);
    const char * pattern_end = pattern + pattern_len;
    
    const char * cmd_ptr = cmd;
    size_t cmd_len = SCPI_strnlen(cmd, len);
    const char * cmd_end = cmd + cmd_len;
    
    /* TODO: now it is possible to send command ":*IDN?" which is incorrect */
    if (iscolon(cmd_ptr[0])) {
        cmd_len --;
        cmd_ptr ++;
    }
    
    while (1) {
        int pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_end - pattern_ptr);
        int cmd_sep_pos = cmdSeparatorPos(cmd_ptr, cmd_end - cmd_ptr);
        
        if (matchPattern(pattern_ptr, pattern_sep_pos, cmd_ptr, cmd_sep_pos)) {
            pattern_ptr = pattern_ptr + pattern_sep_pos;
            cmd_ptr = cmd_ptr + cmd_sep_pos;
            result = TRUE;
            
            /* command is complete */
            if ((pattern_ptr == pattern_end) && (cmd_ptr >= cmd_end)) {
                break;
            }
            
            /* pattern complete, but command not */
            if ((pattern_ptr == pattern_end) && (cmd_ptr < cmd_end)) {
                result = FALSE;
                break;
            }
            
            /* command complete, but pattern not */
            if (cmd_ptr >= cmd_end) {
                result = FALSE;
                break;
            }
            
            /* both command and patter contains command separator at this position */
            if ((pattern_ptr[0] == cmd_ptr[0]) && ((pattern_ptr[0] == ':') || (pattern_ptr[0] == '?'))) {
                pattern_ptr = pattern_ptr + 1;
                cmd_ptr = cmd_ptr + 1;
            } else {
                result = FALSE;
                break;
            }
        } else {
            result = FALSE;
            break;
        }
    }
    
    return result;
}
Example #2
0
/**
 * Compare pattern and command
 * @param pattern eg. [:MEASure]:VOLTage:DC?
 * @param cmd - command
 * @param len - max search length
 * @return TRUE if pattern matches, FALSE otherwise
 */
scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len) {
    scpi_bool_t result = FALSE;
    int leftFlag = 0; // flag for '[' on left
    int rightFlag = 0; // flag for ']' on right
    int cmd_sep_pos = 0;

    const char * pattern_ptr = pattern;
    int pattern_len = strlen(pattern);
    const char * pattern_end = pattern + pattern_len;

    const char * cmd_ptr = cmd;
    size_t cmd_len = SCPI_strnlen(cmd, len);
    const char * cmd_end = cmd + cmd_len;

    /* now support optional keywords in pattern style, e.g. [:MEASure]:VOLTage:DC? */
    if (pattern_ptr[0] == '[') { // skip first '['
        pattern_len--;
        pattern_ptr++;
        leftFlag++;
    }
    if (pattern_ptr[0] == ':') { // skip first ':'
        pattern_len--;
        pattern_ptr++;
    }

    if (cmd_ptr[0] == ':') {
        /* handle errornouse ":*IDN?" */
        if((cmd_len >= 2) && (cmd_ptr[1] != '*')) {
            cmd_len--;
            cmd_ptr++;
        }
    }

    while (1) {
        int pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_end - pattern_ptr);

        if ((leftFlag > 0) && (rightFlag > 0)) {
            leftFlag--;
            rightFlag--;
        } else {
            cmd_sep_pos = cmdSeparatorPos(cmd_ptr, cmd_end - cmd_ptr);
        }

        if (matchPattern(pattern_ptr, pattern_sep_pos, cmd_ptr, cmd_sep_pos)) {
            pattern_ptr = pattern_ptr + pattern_sep_pos;
            cmd_ptr = cmd_ptr + cmd_sep_pos;
            result = TRUE;

            /* command is complete */
            if ((pattern_ptr == pattern_end) && (cmd_ptr >= cmd_end)) {
                break;
            }

            /* pattern complete, but command not */
            if ((pattern_ptr == pattern_end) && (cmd_ptr < cmd_end)) {
                result = FALSE;
                break;
            }

            /* command complete, but pattern not */
            if (cmd_ptr >= cmd_end) {
                if (cmd_end == cmd_ptr) {
                    if (cmd_ptr[0] == pattern_ptr[pattern_end - pattern_ptr - 1]) {
                        break; /* exist optional keyword, command is complete */
                    }
                    if (']' == pattern_ptr[pattern_end - pattern_ptr - 1]) {
                        break; /* exist optional keyword, command is complete */
                    }
                }
                result = FALSE;
                break;
            }

            /* both command and patter contains command separator at this position */
            if ((pattern_ptr[0] == cmd_ptr[0]) && ((pattern_ptr[0] == ':') || (pattern_ptr[0] == '?'))) {
                pattern_ptr = pattern_ptr + 1;
                cmd_ptr = cmd_ptr + 1;
            } else if ((pattern_ptr[1] == cmd_ptr[0])
                    && (pattern_ptr[0] == '[')
                    && (pattern_ptr[1] == ':')) {
                pattern_ptr = pattern_ptr + 2; // for skip '[' in "[:"
                cmd_ptr = cmd_ptr + 1;
                leftFlag++;
            } else if ((pattern_ptr[1] == cmd_ptr[0])
                    && (pattern_ptr[0] == ']')
                    && (pattern_ptr[1] == ':')) {
                pattern_ptr = pattern_ptr + 2; // for skip ']' in "]:"
                cmd_ptr = cmd_ptr + 1;
            } else if ((pattern_ptr[2] == cmd_ptr[0])
                    && (pattern_ptr[0] == ']')
                    && (pattern_ptr[1] == '[')
                    && (pattern_ptr[2] == ':')) {
                pattern_ptr = pattern_ptr + 3; // for skip '][' in "][:"
                cmd_ptr = cmd_ptr + 1;
                leftFlag++;
            } else if (((pattern_ptr[0] == ']')
                    || (pattern_ptr[0] == '['))
                    && (*(pattern_end - 1) == '?') // last is '?'
                    && (cmd_ptr[0] == '?')) {
                result = TRUE; // exist optional keyword, and they are end with '?'
                break; // command is complete  OK
            } else {
                result = FALSE;
                break;
            }
        } else {
            pattern_ptr = pattern_ptr + pattern_sep_pos;
            if ((pattern_ptr[0] == ']') && (pattern_ptr[1] == ':')) {
                pattern_ptr = pattern_ptr + 2; // for skip ']' in "]:" , pattern_ptr continue, while cmd_ptr remain unchanged
                rightFlag++;
            } else if ((pattern_ptr[0] == ']')
                    && (pattern_ptr[1] == '[')
                    && (pattern_ptr[2] == ':')) {
                pattern_ptr = pattern_ptr + 3; // for skip ']' in "][:" , pattern_ptr continue, while cmd_ptr remain unchanged
                rightFlag++;
            } else {
                result = FALSE;
                break;
            }
        }
    }

    return result;
}