From 94ccbeebf69d856effb7ba0dc2dd7e4b13ba3a06 Mon Sep 17 00:00:00 2001
From: Jan Breuer <jan.breuer@jaybee.cz>
Date: 摹曛, 03 10月 2013 21:51:46 +0800
Subject: [PATCH] Add support for Boolean program data

---
 examples/Makefile                |   15 +++++++
 libscpi/src/parser.c             |   31 +++++++++++++++
 Makefile                         |    7 +++
 libscpi/test/test_lexer_parser.c |   12 ++++++
 libscpi/inc/scpi/parser.h        |    2 +
 examples/common/scpi-def.c       |   17 ++++++++
 6 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..14ff52a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+all:
+	$(MAKE) -C libscpi
+	$(MAKE) -C examples
+
+clean:
+	$(MAKE) clean -C libscpi
+	$(MAKE) clean -C examples
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 0000000..7ba0bdb
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,15 @@
+
+all:
+	$(MAKE) -C test-interactive
+	$(MAKE) -C test-parser
+	$(MAKE) -C test-tcp
+	$(MAKE) -C test-tcp-srq
+
+
+clean:
+	$(MAKE) clean -C test-interactive
+	$(MAKE) clean -C test-parser
+	$(MAKE) clean -C test-tcp
+	$(MAKE) clean -C test-tcp-srq
+
+
diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c
index 9f1926a..782445a 100644
--- a/examples/common/scpi-def.c
+++ b/examples/common/scpi-def.c
@@ -89,6 +89,21 @@
     return SCPI_RES_OK;
 }
 
+scpi_result_t SCPI_TestBool(scpi_t * context) {
+    scpi_parameter_t param1;
+    fprintf(stderr, "TEST:BOOL\r\n"); // debug command name   
+
+    // read first parameter if present
+    if (!SCPI_Parameter(context, &param1, true)) {
+        return SCPI_RES_ERR;
+    }
+
+    fprintf(stderr, "\tP1=%d\r\n", SCPI_ParamGetBoolVal(context, &param1));
+
+    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,},
@@ -136,6 +151,8 @@
     {.pattern = "MEASure:PERiod?", .callback = SCPI_StubQ,},
     
     {.pattern = "SYSTem:COMMunication:TCPIP:CONTROL?", .callback = SCPI_SystemCommTcpipControlQ,},
+    
+    {.pattern = "TEST:BOOL", .callback = SCPI_TestBool,},
 
     SCPI_CMD_LIST_END
 };
diff --git a/libscpi/inc/scpi/parser.h b/libscpi/inc/scpi/parser.h
index 6a9ebda..d42f9bd 100644
--- a/libscpi/inc/scpi/parser.h
+++ b/libscpi/inc/scpi/parser.h
@@ -56,12 +56,14 @@
     size_t SCPI_ResultDouble(scpi_t * context, double val);
     size_t SCPI_ResultText(scpi_t * context, const char * data);
     size_t SCPI_ResultArbitraryBlock(scpi_t * context, const char * data, size_t len);
+    size_t SCPI_ResultBool(scpi_t * context, bool_t val);
 
     int32_t SCPI_ParamGetIntVal(scpi_t * context, scpi_parameter_t * parameter);
     double SCPI_ParamGetDoubleVal(scpi_t * context, scpi_parameter_t * parameter);
     void SCPI_ParamGetTextVal(scpi_t * context, scpi_parameter_t * parameter, const char ** data, int32_t * len);
 #define SCPI_ParamGetCharactersVal SCPI_ParamGetTextVal
 #define SCPI_ParamGetArbitraryBlockVal SCPI_ParamGetTextVal
+    bool_t SCPI_ParamGetBoolVal(scpi_t * context, scpi_parameter_t * parameter);
 
     bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, bool_t mandatory);
 
diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c
index cedce47..2a0eabf 100644
--- a/libscpi/src/parser.c
+++ b/libscpi/src/parser.c
@@ -342,6 +342,17 @@
     return result;
 }
 
+/**
+ * Write boolean value to the result
+ * @param context
+ * @param val
+ * @return
+ */
+size_t SCPI_ResultBool(scpi_t * context, bool_t val) {
+    return SCPI_ResultIntBase(context, val ? 1 : 0, 10);
+}
+
+
 /* parsing parameters */
 
 bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, bool_t mandatory) {
@@ -450,6 +461,26 @@
     *len = parameter->data.len;
 }
 
+/* SCPI-99 7.3 Boolean Program Data */
+bool_t SCPI_ParamGetBoolVal(scpi_t * context, scpi_parameter_t * parameter) {
+    switch (parameter->type) {
+        case TokDecimalNumericProgramData:
+            return parameter->number.value ? 1 : 0;
+        case TokProgramMnemonic:
+            if (compareStr("ON", 2, parameter->data.ptr, parameter->data.len)) {
+                return TRUE;
+            } else if (compareStr("OFF", 3, parameter->data.ptr, parameter->data.len)) {
+                return FALSE;
+            } else {
+                SCPI_ErrorPush(context, SCPI_ERROR_INVALID_PARAMETER);
+                return FALSE;
+            }
+        default:
+            SCPI_ErrorPush(context, SCPI_ERROR_INVALID_PARAMETER);
+            return FALSE;
+    }
+}
+
 int SCPI_ParseProgramData(lex_state_t * state, token_t * token) {
     token_t tmp;
     int result = 0;
diff --git a/libscpi/test/test_lexer_parser.c b/libscpi/test/test_lexer_parser.c
index a700717..0e99fe5 100644
--- a/libscpi/test/test_lexer_parser.c
+++ b/libscpi/test/test_lexer_parser.c
@@ -265,6 +265,17 @@
     TEST_DETECT("[\r\n", 0, 1, TokInvalid, 0, 0, PmutNone);
 }
 
+void testBoolParameter(void) {
+    TEST_TOKEN(" 1", SCPI_ParseProgramData, 1, 1, TokDecimalNumericProgramData);
+    TEST_TOKEN(" 0", SCPI_ParseProgramData, 1, 1, TokDecimalNumericProgramData);
+    TEST_TOKEN(" ON", SCPI_ParseProgramData, 1, 2, TokProgramMnemonic);
+    TEST_TOKEN("OFF ", SCPI_ParseProgramData, 0, 3, TokProgramMnemonic);
+    
+    // TODO: finish bool test
+}
+
+// TODO: SCPI_Parameter test
+
 int main() {
     CU_pSuite pSuite = NULL;
 
@@ -292,6 +303,7 @@
             || (NULL == CU_add_test(pSuite, "ProgramData", testProgramData))
             || (NULL == CU_add_test(pSuite, "AllProgramData", testAllProgramData))
             || (NULL == CU_add_test(pSuite, "DetectProgramMessageUnit", testDetectProgramMessageUnit))
+            || (NULL == CU_add_test(pSuite, "BoolParameter", testBoolParameter))
             ) {
         CU_cleanup_registry();
         return CU_get_error();

--
Gitblit v1.9.1