From f2dbd1cc2948f4a52e952f2b10c5ac8bca10dba6 Mon Sep 17 00:00:00 2001
From: Jan Breuer <jan.breuer@jaybee.cz>
Date: 周二, 19 8月 2014 21:19:22 +0800
Subject: [PATCH] Add support for matching number suffix

---
 libscpi/inc/scpi/types.h         |   15 ++++---
 libscpi/inc/scpi/utils_private.h |    1 
 libscpi/src/parser.c             |    3 +
 libscpi/test/test_scpi_utils.c   |   35 +++++++++++++++++
 libscpi/src/utils.c              |   49 +++++++++++++++++++++++-
 examples/common/scpi-def.c       |    8 ++++
 6 files changed, 101 insertions(+), 10 deletions(-)

diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c
index 3a863c9..9e3cc5d 100644
--- a/examples/common/scpi-def.c
+++ b/examples/common/scpi-def.c
@@ -154,6 +154,13 @@
     return SCPI_RES_OK;
 }
 
+scpi_result_t TEST_Numbers(scpi_t * context) {
+
+    fprintf(stderr, "RAW CMD %.*s\r\n", (int)context->paramlist.cmd_raw.length, context->paramlist.cmd_raw.data);
+
+    return SCPI_RES_OK;
+}
+
 static const scpi_command_t scpi_commands[] = {
     /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */
     { .pattern = "*CLS", .callback = SCPI_CoreCls,},
@@ -204,6 +211,7 @@
 
     {.pattern = "TEST:BOOL", .callback = TEST_Bool,},
     {.pattern = "TEST:CHOice?", .callback = TEST_ChoiceQ,},
+    {.pattern = "TEST#:NUMbers#", .callback = TEST_Numbers,},
 
     SCPI_CMD_LIST_END
 };
diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h
index 3597275..78a5cd6 100644
--- a/libscpi/inc/scpi/types.h
+++ b/libscpi/inc/scpi/types.h
@@ -105,10 +105,18 @@
 
     typedef struct _scpi_command_t scpi_command_t;
 
+    struct _scpi_buffer_t {
+        size_t length;
+        size_t position;
+        char * data;
+    };
+    typedef struct _scpi_buffer_t scpi_buffer_t;
+
     struct _scpi_param_list_t {
         const scpi_command_t * cmd;
         const char * parameters;
         size_t length;
+        scpi_buffer_t cmd_raw;
     };
     #define SCPI_CMD_LIST_END       {NULL, NULL, }
     typedef struct _scpi_param_list_t scpi_param_list_t;
@@ -116,13 +124,6 @@
     /* scpi interface */
     typedef struct _scpi_t scpi_t;
     typedef struct _scpi_interface_t scpi_interface_t;
-
-    struct _scpi_buffer_t {
-        size_t length;
-        size_t position;
-        char * data;
-    };
-    typedef struct _scpi_buffer_t scpi_buffer_t;
 
     typedef size_t(*scpi_write_t)(scpi_t * context, const char * data, size_t len);
     typedef scpi_result_t(*scpi_write_control_t)(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val);
diff --git a/libscpi/inc/scpi/utils_private.h b/libscpi/inc/scpi/utils_private.h
index f3b6859..230ce98 100644
--- a/libscpi/inc/scpi/utils_private.h
+++ b/libscpi/inc/scpi/utils_private.h
@@ -53,6 +53,7 @@
 
     const 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) LOCAL;
     size_t longToStr(int32_t val, char * str, size_t len) LOCAL;
     size_t doubleToStr(double val, char * str, size_t len) LOCAL;
     size_t strToLong(const char * str, int32_t * val) LOCAL;
diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c
index 61d6588..b4f79ac 100644
--- a/libscpi/src/parser.c
+++ b/libscpi/src/parser.c
@@ -236,6 +236,9 @@
             context->paramlist.cmd = cmd;
             context->paramlist.parameters = cmdline_ptr + cmd_len;
             context->paramlist.length = cmdline_len - cmd_len;
+            context->paramlist.cmd_raw.data = cmdline_ptr;
+            context->paramlist.cmd_raw.length = cmd_len;
+            context->paramlist.cmd_raw.position = 0;
             return TRUE;
         }
     }
diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c
index 7633abf..8c3cbd6 100644
--- a/libscpi/src/utils.c
+++ b/libscpi/src/utils.c
@@ -158,6 +158,36 @@
     return FALSE;
 }
 
+/**
+ * Compare two strings, one be longer but may contains only numbers in that section
+ * @param str1
+ * @param len1
+ * @param str2
+ * @param len2
+ * @return TRUE if strings match
+ */
+scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2) {
+    scpi_bool_t result = FALSE;
+    size_t i;
+
+    if (len2 < len1) {
+        return FALSE;
+    }
+
+    if (SCPI_strncasecmp(str1, str2, len1) == 0) {
+        result = TRUE;
+    }
+
+    for (i = len1; i<len2; i++) {
+        if (!isdigit(str2[i])) {
+            result = FALSE;
+            break;
+        }
+    }
+
+    return result;
+}
+
 enum _locate_text_states {
     STATE_FIRST_WHITESPACE,
     STATE_TEXT_QUOTED,
@@ -436,9 +466,22 @@
  * @return 
  */
 scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len) {
-    int pattern_sep_pos_short = patternSeparatorShortPos(pattern, pattern_len);
-    return compareStr(pattern, pattern_len, str, str_len) ||
-            compareStr(pattern, pattern_sep_pos_short, str, str_len);
+    int pattern_sep_pos_short;
+
+    if (pattern[pattern_len - 1] == '#') {
+        size_t new_pattern_len = pattern_len - 1;
+
+        pattern_sep_pos_short = patternSeparatorShortPos(pattern, new_pattern_len);
+
+        return compareStrAndNum(pattern, new_pattern_len, str, str_len) ||
+                compareStrAndNum(pattern, pattern_sep_pos_short, str, str_len);
+    } else {
+
+        pattern_sep_pos_short = patternSeparatorShortPos(pattern, pattern_len);
+
+        return compareStr(pattern, pattern_len, str, str_len) ||
+                compareStr(pattern, pattern_sep_pos_short, str, str_len);
+    }
 }
 
 /**
diff --git a/libscpi/test/test_scpi_utils.c b/libscpi/test/test_scpi_utils.c
index c772b5f..5817f61 100644
--- a/libscpi/test/test_scpi_utils.c
+++ b/libscpi/test/test_scpi_utils.c
@@ -165,6 +165,24 @@
     CU_ASSERT_FALSE(compareStr("ABCD", 4, "abcd", 3));
 }
 
+void test_compareStrAndNum() {
+
+    CU_ASSERT_TRUE(compareStrAndNum("abcd", 1, "afgh", 1));
+    CU_ASSERT_TRUE(compareStrAndNum("ABCD", 4, "abcd", 4));
+    CU_ASSERT_TRUE(compareStrAndNum("AbCd", 3, "AbCE", 3));
+    CU_ASSERT_TRUE(compareStrAndNum("ABCD", 1, "a", 1));
+
+    CU_ASSERT_FALSE(compareStrAndNum("abcd", 1, "efgh", 1));
+    CU_ASSERT_FALSE(compareStrAndNum("ABCD", 4, "abcd", 3));
+
+    CU_ASSERT_TRUE(compareStrAndNum("abcd", 4, "abcd1", 5));
+    CU_ASSERT_TRUE(compareStrAndNum("abcd", 4, "abcd123", 7));
+    CU_ASSERT_FALSE(compareStrAndNum("abcd", 4, "abcd12A", 7));
+    CU_ASSERT_FALSE(compareStrAndNum("abcd", 4, "abcdB12", 7));
+    CU_ASSERT_FALSE(compareStrAndNum("abdd", 4, "abcd132", 7));
+
+}
+
 void test_locateText() {
 
     const char * v;
@@ -387,6 +405,22 @@
     TEST_MATCH_COMMAND("*IDN?", ":idn?", FALSE); // common command
     TEST_MATCH_COMMAND("*IDN?", ":*idn", FALSE); // common command
     TEST_MATCH_COMMAND("*IDN?", ":*idn?", FALSE); // common command
+
+    TEST_MATCH_COMMAND("ABCdef#", "abc", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("ABCdef#", "abc1324", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("ABCdef#", "abcDef1324", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("ABCdef#", "abcDef124b", FALSE); // test numeric parameter
+
+    TEST_MATCH_COMMAND("OUTPut#:MODulation#:FM#", "abc", FALSE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#:MODulation#:FM#", "outp1:mod10:fm", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#:MODulation#:FM#", "output1:mod10:fm", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#:MODulation#:FM#", "outp1:modulation:fm5", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#:MODulation#:FM#", "output:mod:fm", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#:MODulation#:FM#", "outp1:mod10a:fm", FALSE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#[:MODulation#]:FM#", "outp1:fm", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#[:MODulation#]:FM#", "outp1:mod10:fm", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#[:MODulation#]:FM#", "outp1:fm2", TRUE); // test numeric parameter
+    TEST_MATCH_COMMAND("OUTPut#[:MODulation#]:FM#", "output:fm", TRUE); // test numeric parameter
 }
 
 void test_composeCompoundCommand(void) {
@@ -445,6 +479,7 @@
             || (NULL == CU_add_test(pSuite, "strToLong", test_strToLong))
             || (NULL == CU_add_test(pSuite, "strToDouble", test_strToDouble))
             || (NULL == CU_add_test(pSuite, "compareStr", test_compareStr))
+            || (NULL == CU_add_test(pSuite, "compareStrAndNum", test_compareStrAndNum))
             || (NULL == CU_add_test(pSuite, "locateText", test_locateText))
             || (NULL == CU_add_test(pSuite, "locateStr", test_locateStr))
             || (NULL == CU_add_test(pSuite, "matchPattern", test_matchPattern))

--
Gitblit v1.9.1