From 8a0ad09e70d555974cd319e6157b09f857960867 Mon Sep 17 00:00:00 2001 From: nancy.liao <huihui.liao@greentest.com.cn> Date: 周三, 23 4月 2025 11:31:35 +0800 Subject: [PATCH] 通用的命令解析完成 如<[:MEASure]|[SOURCE]><[:ARM]|[TRigger]>[:DC] 以及[:MEASure][:DC],当前还没有区分必填项和可选性,输入参数将严格按照:的参数个数进行解析 --- libscpi/src/parser.c | 5 + libscpi/src/utils_private.h | 77 ++++++++++--------- libscpi/inc/scpi/parser.h | 2 libscpi/src/utils.c | 137 +++++++++++++++++++++------------- 4 files changed, 131 insertions(+), 90 deletions(-) diff --git a/libscpi/inc/scpi/parser.h b/libscpi/inc/scpi/parser.h index ab65275..d0ddfb1 100644 --- a/libscpi/inc/scpi/parser.h +++ b/libscpi/inc/scpi/parser.h @@ -64,7 +64,7 @@ #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE void SCPI_InitHeap(scpi_t * context, char * error_info_heap, size_t error_info_heap_length); #endif - + scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len); scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len); scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len); diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index 2240d5c..ad19ccf 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -180,11 +180,14 @@ * @param context * @result TRUE if context->paramlist is filled with correct values */ -static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len) { +static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len) +{ + int32_t i; const scpi_command_t * cmd = NULL; for (i = 0; i<context->cmdlistSize; i++) { cmd = &context->cmdlist[i]; + bool result =test_match(cmd->pattern, header); if(result) { diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index bdde1ea..afb6664 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1145,43 +1145,75 @@ ((val & 0xFF00000000000000ull) >> 56); } + +// 瑙f瀽妯″紡锛屽皢姣忎釜閮ㄥ垎淇濆瓨鍒� 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 == '[') - { - // 澶勭悊鍙彉娈� + while (*p && seg_count < max_segments) { + if (*p == '[') { + // 澶勭悊鍙彉娈碉紙[]锛� segments[seg_count].is_variable = TRUE; - // 璺宠繃'[' - p++; + 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) - { + while (*p && *p != ']' && i < sizeof(segments[seg_count].text) - 1) { segments[seg_count].text[i++] = toupper(*p++); } - segments[seg_count].text[i] = '\0'; + segments[seg_count].text[i] = '\0'; // 缁撴潫绗� - if (*p == ']') - { - // 璺宠繃']' - p++; + if (*p == ']') { + p++; // 璺宠繃']' } } - else - { - // 澶勭悊鍥哄畾娈� - segments[seg_count].is_variable = FALSE; + 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) - { + while (*p && *p != '>' && i < sizeof(segments[seg_count].text) - 1) { segments[seg_count].text[i++] = toupper(*p++); } - segments[seg_count].text[i] = '\0'; + 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++; @@ -1190,46 +1222,49 @@ return seg_count; } -// 鍖归厤鍛戒护涓庢ā寮� -bool match_command(const char* command, Segment segments[], int 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++; - // 妯″紡涓篃搴旇鏈夊搴旂殑鍒嗛殧绗� - if (segments[current_seg].text[0] != ':') - { - return FALSE; - } + 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) - { + if (segments[current_seg].is_variable) { // 鍙彉娈� - 璺宠繃瀵瑰簲闀垮害鐨勫瓧绗� int i = 0; - while (*cmd && *cmd != ':' && i < seg_len) - { + while (*cmd && *cmd != ':' && i < seg_len) { cmd++; i++; } - } else - { - // 鍥哄畾娈� - 蹇呴』绮剧‘鍖归厤 - if (strncasecmp(cmd, segments[current_seg].text, seg_len) != 0) - { + } + 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 += seg_len; + cmd += strlen(options[0]); + } + else { + // 鍥哄畾娈� - 蹇呴』绮剧‘鍖归厤 + if (strncasecmp(cmd, segments[current_seg].text, seg_len) != 0) { + return FALSE; + } + cmd += seg_len; // 璺宠繃鍖归厤鐨勯儴鍒� } current_seg++; @@ -1239,13 +1274,11 @@ return (*cmd == '\0') && (current_seg == seg_count); } -// 娴嬭瘯鍑芥暟 +// 娴嬭瘯鍖归厤鍑芥暟 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)); + Segment segments[MAX_SEGMENTS]; + int seg_count = parse_pattern(pattern, segments, MAX_SEGMENTS); + return match_command(command, segments, seg_count); } - - diff --git a/libscpi/src/utils_private.h b/libscpi/src/utils_private.h index 485ba16..fbc81e0 100644 --- a/libscpi/src/utils_private.h +++ b/libscpi/src/utils_private.h @@ -60,62 +60,67 @@ #define LOCAL #endif - char * strnpbrk(const char *str, size_t size, const char *set) LOCAL; - scpi_bool_t compareStr(const char * str1, size_t len1, const char * str2, size_t len2) LOCAL; - scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) LOCAL; - size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; - size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; - size_t strBaseToInt32(const char * str, int32_t * val, int8_t base) LOCAL; - size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) LOCAL; - size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) LOCAL; - size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) LOCAL; - size_t strToFloat(const char * str, float * val) LOCAL; - size_t strToDouble(const char * str, double * val) LOCAL; - scpi_bool_t locateText(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; - scpi_bool_t locateStr(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; - size_t skipWhitespace(const char * cmd, size_t len) LOCAL; - scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len, int32_t * num) LOCAL; - scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value) LOCAL; - scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) LOCAL; +char * strnpbrk(const char *str, size_t size, const char *set) LOCAL; +scpi_bool_t compareStr(const char * str1, size_t len1, const char * str2, size_t len2) LOCAL; +scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) LOCAL; +size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; +size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; +size_t strBaseToInt32(const char * str, int32_t * val, int8_t base) LOCAL; +size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) LOCAL; +size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) LOCAL; +size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) LOCAL; +size_t strToFloat(const char * str, float * val) LOCAL; +size_t strToDouble(const char * str, double * val) LOCAL; +scpi_bool_t locateText(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; +scpi_bool_t locateStr(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; +size_t skipWhitespace(const char * cmd, size_t len) LOCAL; +scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len, int32_t * num) LOCAL; +scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value) LOCAL; +scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) LOCAL; +#define MAX_SEGMENTS 16 - typedef struct { - bool is_variable; // 鏄惁涓哄彲鍙橀儴鍒嗭紙鐢╗]鎷捣鏉ョ殑锛� - char text[32]; // 娈靛唴瀹癸紙涓嶅寘鍚玔]锛� - } Segment; +typedef struct { + bool is_variable; // 鏄惁涓哄彲鍙橀儴鍒嗭紙鐢╗]鎷捣鏉ョ殑锛� + bool is_required; // 鏄惁涓哄繀閫夐儴鍒嗭紙鐢�<>鎷捣鏉ョ殑锛� + bool is_option; // 鏄惁涓洪�夐」缁勯儴鍒嗭紙鐢▅鍒嗛殧锛� + char text[32]; // 娈靛唴瀹癸紙涓嶅寘鍚玔]鎴�<>锛� +} Segment; - int parse_pattern(const char* pattern, Segment segments[], int max_segments); - bool match_command(const char* command, Segment segments[], int seg_count); - bool test_match(const char* pattern, const char* command); +//鍖归厤[:MEASure][:VOLTage] +int parse_pattern(const char* pattern, Segment segments[], int max_segments); +bool match_command(const char* command, Segment segments[], int seg_count); +bool test_match(const char* pattern, const char* command); + #define SCPI_DTOSTRE_UPPERCASE 1 #define SCPI_DTOSTRE_ALWAYS_SIGN 2 #define SCPI_DTOSTRE_PLUS_SIGN 4 - char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags); +char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags); - scpi_array_format_t SCPI_GetNativeFormat(void); - uint16_t SCPI_Swap16(uint16_t val); - uint32_t SCPI_Swap32(uint32_t val); - uint64_t SCPI_Swap64(uint64_t val); +scpi_array_format_t SCPI_GetNativeFormat(void); +uint16_t SCPI_Swap16(uint16_t val); +uint32_t SCPI_Swap32(uint32_t val); +uint64_t SCPI_Swap64(uint64_t val); #if !HAVE_STRNLEN - size_t BSD_strnlen(const char *s, size_t maxlen) LOCAL; +size_t BSD_strnlen(const char *s, size_t maxlen) LOCAL; #endif #if !HAVE_STRNCASECMP && !HAVE_STRNICMP - int OUR_strncasecmp(const char *s1, const char *s2, size_t n) LOCAL; +int OUR_strncasecmp(const char *s1, const char *s2, size_t n) LOCAL; #endif #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE - void scpiheap_init(scpi_error_info_heap_t * heap, char * error_info_heap, size_t error_info_heap_length); - char * scpiheap_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) LOCAL; - void scpiheap_free(scpi_error_info_heap_t * heap, char *s, scpi_bool_t rollback) LOCAL; - scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap, const char *s1, size_t * len1, const char ** s2, size_t * len2) LOCAL; +void scpiheap_init(scpi_error_info_heap_t * heap, char * error_info_heap, size_t error_info_heap_length); +char * scpiheap_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) LOCAL; +void scpiheap_free(scpi_error_info_heap_t * heap, char *s, scpi_bool_t rollback) LOCAL; +scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap, const char *s1, size_t * len1, const char ** s2, size_t * len2) LOCAL; #endif #if !HAVE_STRNDUP - char *OUR_strndup(const char *s, size_t n); +char *OUR_strndup(const char *s, size_t n); #endif #ifndef min -- Gitblit v1.9.1