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