From 2df8ee6c6f411e5fa0b774874e759c5e7b045121 Mon Sep 17 00:00:00 2001
From: Jan Breuer <jan.breuer@jaybee.cz>
Date: 周二, 27 11月 2012 19:52:23 +0800
Subject: [PATCH] Units parsing completition

---
 netbeans/tests/test_scpi_utils.c         |  105 +++++++-
 test-parser.c                            |   92 ++++---
 netbeans/nbproject/Makefile-Debug.mk     |   40 +-
 netbeans/nbproject/Makefile-variables.mk |    4 
 netbeans/nbproject/Package-Debug.bash    |    4 
 scpi/scpi_units.h                        |    2 
 scpi/scpi.h                              |    1 
 netbeans/nbproject/configurations.xml    |   28 -
 scpi/scpi_utils.c                        |  100 ++++++++
 scpi/scpi_error.c                        |   22 +
 scpi/scpi_utils.h                        |   13 +
 scpi/scpi.c                              |  118 ++++------
 scpi/scpi_units.c                        |  117 ++++++++--
 13 files changed, 434 insertions(+), 212 deletions(-)

diff --git a/netbeans/nbproject/Makefile-Debug.mk b/netbeans/nbproject/Makefile-Debug.mk
index c5583ab..c3a9616 100644
--- a/netbeans/nbproject/Makefile-Debug.mk
+++ b/netbeans/nbproject/Makefile-Debug.mk
@@ -63,50 +63,50 @@
 ASFLAGS=
 
 # Link Libraries and Options
-LDLIBSOPTIONS=-lcunit -lcunit
+LDLIBSOPTIONS=-lcunit -lcunit -lcunit
 
 # Build Targets
 .build-conf: ${BUILD_SUBPROJECTS}
-	"${MAKE}"  -f nbproject/Makefile-${CND_CONF}.mk ${TESTDIR}/TestFiles/f2
+	"${MAKE}"  -f nbproject/Makefile-${CND_CONF}.mk ${TESTDIR}/TestFiles/f1
 
-${TESTDIR}/TestFiles/f2: ${OBJECTFILES}
+${TESTDIR}/TestFiles/f1: ${OBJECTFILES}
 	${MKDIR} -p ${TESTDIR}/TestFiles
-	${LINK.c} -g3 -o ${TESTDIR}/TestFiles/f2 ${OBJECTFILES} ${LDLIBSOPTIONS} 
+	${LINK.c} -g3 -o ${TESTDIR}/TestFiles/f1 ${OBJECTFILES} ${LDLIBSOPTIONS} 
 
 ${OBJECTDIR}/_ext/760632520/scpi_utils.o: nbproject/Makefile-${CND_CONF}.mk ../scpi/scpi_utils.c 
 	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_utils.o ../scpi/scpi_utils.c
+	$(COMPILE.c) -Wall -I. -I. -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_utils.o ../scpi/scpi_utils.c
 
 ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o: nbproject/Makefile-${CND_CONF}.mk ../scpi/scpi_ieee488.c 
 	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o ../scpi/scpi_ieee488.c
+	$(COMPILE.c) -Wall -I. -I. -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o ../scpi/scpi_ieee488.c
 
 ${OBJECTDIR}/_ext/760632520/scpi.o: nbproject/Makefile-${CND_CONF}.mk ../scpi/scpi.c 
 	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi.o ../scpi/scpi.c
+	$(COMPILE.c) -Wall -I. -I. -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi.o ../scpi/scpi.c
 
 ${OBJECTDIR}/_ext/760632520/scpi_minimal.o: nbproject/Makefile-${CND_CONF}.mk ../scpi/scpi_minimal.c 
 	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_minimal.o ../scpi/scpi_minimal.c
+	$(COMPILE.c) -Wall -I. -I. -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_minimal.o ../scpi/scpi_minimal.c
 
 ${OBJECTDIR}/_ext/1472/test-parser.o: nbproject/Makefile-${CND_CONF}.mk ../test-parser.c 
 	${MKDIR} -p ${OBJECTDIR}/_ext/1472
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/1472/test-parser.o ../test-parser.c
+	$(COMPILE.c) -Wall -I. -I. -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/1472/test-parser.o ../test-parser.c
 
 ${OBJECTDIR}/_ext/760632520/scpi_units.o: nbproject/Makefile-${CND_CONF}.mk ../scpi/scpi_units.c 
 	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_units.o ../scpi/scpi_units.c
+	$(COMPILE.c) -Wall -I. -I. -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_units.o ../scpi/scpi_units.c
 
 ${OBJECTDIR}/_ext/760632520/scpi_error.o: nbproject/Makefile-${CND_CONF}.mk ../scpi/scpi_error.c 
 	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_error.o ../scpi/scpi_error.c
+	$(COMPILE.c) -Wall -I. -I. -I. -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_error.o ../scpi/scpi_error.c
 
 # Subprojects
 .build-subprojects:
@@ -121,7 +121,7 @@
 ${TESTDIR}/tests/test_scpi_utils.o: tests/test_scpi_utils.c 
 	${MKDIR} -p ${TESTDIR}/tests
 	${RM} $@.d
-	$(COMPILE.c) -Wall -I. -I. -MMD -MP -MF $@.d -o ${TESTDIR}/tests/test_scpi_utils.o tests/test_scpi_utils.c
+	$(COMPILE.c) -Wall -I. -I. -I. -I. -MMD -MP -MF $@.d -o ${TESTDIR}/tests/test_scpi_utils.o tests/test_scpi_utils.c
 
 
 ${OBJECTDIR}/_ext/760632520/scpi_utils_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_utils.o ../scpi/scpi_utils.c 
@@ -132,7 +132,7 @@
 	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
 	then  \
 	    ${RM} $@.d;\
-	    $(COMPILE.c) -Wall -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_utils_nomain.o ../scpi/scpi_utils.c;\
+	    $(COMPILE.c) -Wall -I. -I. -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_utils_nomain.o ../scpi/scpi_utils.c;\
 	else  \
 	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_utils.o ${OBJECTDIR}/_ext/760632520/scpi_utils_nomain.o;\
 	fi
@@ -145,7 +145,7 @@
 	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
 	then  \
 	    ${RM} $@.d;\
-	    $(COMPILE.c) -Wall -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_ieee488_nomain.o ../scpi/scpi_ieee488.c;\
+	    $(COMPILE.c) -Wall -I. -I. -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_ieee488_nomain.o ../scpi/scpi_ieee488.c;\
 	else  \
 	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o ${OBJECTDIR}/_ext/760632520/scpi_ieee488_nomain.o;\
 	fi
@@ -158,7 +158,7 @@
 	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
 	then  \
 	    ${RM} $@.d;\
-	    $(COMPILE.c) -Wall -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_nomain.o ../scpi/scpi.c;\
+	    $(COMPILE.c) -Wall -I. -I. -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_nomain.o ../scpi/scpi.c;\
 	else  \
 	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi.o ${OBJECTDIR}/_ext/760632520/scpi_nomain.o;\
 	fi
@@ -171,7 +171,7 @@
 	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
 	then  \
 	    ${RM} $@.d;\
-	    $(COMPILE.c) -Wall -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_minimal_nomain.o ../scpi/scpi_minimal.c;\
+	    $(COMPILE.c) -Wall -I. -I. -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_minimal_nomain.o ../scpi/scpi_minimal.c;\
 	else  \
 	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_minimal.o ${OBJECTDIR}/_ext/760632520/scpi_minimal_nomain.o;\
 	fi
@@ -184,7 +184,7 @@
 	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
 	then  \
 	    ${RM} $@.d;\
-	    $(COMPILE.c) -Wall -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/1472/test-parser_nomain.o ../test-parser.c;\
+	    $(COMPILE.c) -Wall -I. -I. -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/1472/test-parser_nomain.o ../test-parser.c;\
 	else  \
 	    ${CP} ${OBJECTDIR}/_ext/1472/test-parser.o ${OBJECTDIR}/_ext/1472/test-parser_nomain.o;\
 	fi
@@ -197,7 +197,7 @@
 	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
 	then  \
 	    ${RM} $@.d;\
-	    $(COMPILE.c) -Wall -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_units_nomain.o ../scpi/scpi_units.c;\
+	    $(COMPILE.c) -Wall -I. -I. -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_units_nomain.o ../scpi/scpi_units.c;\
 	else  \
 	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_units.o ${OBJECTDIR}/_ext/760632520/scpi_units_nomain.o;\
 	fi
@@ -210,7 +210,7 @@
 	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
 	then  \
 	    ${RM} $@.d;\
-	    $(COMPILE.c) -Wall -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_error_nomain.o ../scpi/scpi_error.c;\
+	    $(COMPILE.c) -Wall -I. -I. -I. -Dmain=__nomain -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_error_nomain.o ../scpi/scpi_error.c;\
 	else  \
 	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_error.o ${OBJECTDIR}/_ext/760632520/scpi_error_nomain.o;\
 	fi
@@ -227,7 +227,7 @@
 # Clean Targets
 .clean-conf: ${CLEAN_SUBPROJECTS}
 	${RM} -r ${CND_BUILDDIR}/${CND_CONF}
-	${RM} ${TESTDIR}/TestFiles/f2
+	${RM} ${TESTDIR}/TestFiles/f1
 
 # Subprojects
 .clean-subprojects:
diff --git a/netbeans/nbproject/Makefile-variables.mk b/netbeans/nbproject/Makefile-variables.mk
index 5e0a2ba..59d1e9a 100644
--- a/netbeans/nbproject/Makefile-variables.mk
+++ b/netbeans/nbproject/Makefile-variables.mk
@@ -9,8 +9,8 @@
 # Debug configuration
 CND_PLATFORM_Debug=GNU-Linux-x86
 CND_ARTIFACT_DIR_Debug=build/Debug/GNU-Linux-x86/tests/TestFiles
-CND_ARTIFACT_NAME_Debug=f2
-CND_ARTIFACT_PATH_Debug=build/Debug/GNU-Linux-x86/tests/TestFiles/f2
+CND_ARTIFACT_NAME_Debug=f1
+CND_ARTIFACT_PATH_Debug=build/Debug/GNU-Linux-x86/tests/TestFiles/f1
 CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package
 CND_PACKAGE_NAME_Debug=scpi_parser.tar
 CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/scpi_parser.tar
diff --git a/netbeans/nbproject/Package-Debug.bash b/netbeans/nbproject/Package-Debug.bash
index c48b0b4..2d5be5c 100644
--- a/netbeans/nbproject/Package-Debug.bash
+++ b/netbeans/nbproject/Package-Debug.bash
@@ -12,8 +12,8 @@
 CND_BUILDDIR=build
 NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
 TMPDIRNAME=tmp-packaging
-OUTPUT_PATH=${TESTDIR}/TestFiles/f2
-OUTPUT_BASENAME=f2
+OUTPUT_PATH=${TESTDIR}/TestFiles/f1
+OUTPUT_BASENAME=f1
 PACKAGE_TOP_DIR=scpi_parser/
 
 # Functions
diff --git a/netbeans/nbproject/configurations.xml b/netbeans/nbproject/configurations.xml
index 133b92f..229ffad 100644
--- a/netbeans/nbproject/configurations.xml
+++ b/netbeans/nbproject/configurations.xml
@@ -10,6 +10,7 @@
         <itemPath>../scpi/scpi_error.h</itemPath>
         <itemPath>../scpi/scpi_ieee488.h</itemPath>
         <itemPath>../scpi/scpi_minimal.h</itemPath>
+        <itemPath>../scpi/scpi_units.h</itemPath>
         <itemPath>../scpi/scpi_utils.h</itemPath>
       </logicalFolder>
     </logicalFolder>
@@ -61,6 +62,8 @@
           <developmentMode>0</developmentMode>
           <incDir>
             <pElem>.</pElem>
+            <pElem>.</pElem>
+            <pElem>.</pElem>
           </incDir>
           <commandLine>-Wextra -g3 -O0</commandLine>
           <warningLevel>2</warningLevel>
@@ -68,11 +71,14 @@
         <ccTool>
           <incDir>
             <pElem>.</pElem>
+            <pElem>.</pElem>
+            <pElem>.</pElem>
           </incDir>
         </ccTool>
         <linkerTool>
-          <output>${TESTDIR}/TestFiles/f2</output>
+          <output>${TESTDIR}/TestFiles/f1</output>
           <linkerLibItems>
+            <linkerLibStdlibItem>CUnit</linkerLibStdlibItem>
             <linkerLibStdlibItem>CUnit</linkerLibStdlibItem>
             <linkerLibStdlibItem>CUnit</linkerLibStdlibItem>
           </linkerLibItems>
@@ -91,26 +97,6 @@
                             group="bin"/>
         </packFileList>
       </packaging>
-      <folder path="TestFiles/f1">
-        <cTool>
-          <incDir>
-            <pElem>.</pElem>
-            <pElem>.</pElem>
-          </incDir>
-        </cTool>
-        <ccTool>
-          <incDir>
-            <pElem>.</pElem>
-            <pElem>.</pElem>
-          </incDir>
-        </ccTool>
-        <linkerTool>
-          <output>${TESTDIR}/TestFiles/f1</output>
-          <linkerLibItems>
-            <linkerLibStdlibItem>CUnit</linkerLibStdlibItem>
-          </linkerLibItems>
-        </linkerTool>
-      </folder>
       <folder path="TestFiles/f3">
         <cTool>
           <incDir>
diff --git a/netbeans/tests/test_scpi_utils.c b/netbeans/tests/test_scpi_utils.c
index 2ced343..63b9eaa 100644
--- a/netbeans/tests/test_scpi_utils.c
+++ b/netbeans/tests/test_scpi_utils.c
@@ -48,7 +48,7 @@
 void test_doubleToStr() {
     size_t result;
     char str[50];
-    
+
 #define TEST_DOUBLE_TO_STR(v, r, s)                     \
     do {                                                \
         result = doubleToStr(v, str, sizeof(str));      \
@@ -56,7 +56,7 @@
         CU_ASSERT_STRING_EQUAL(str, s);                 \
     } while(0)                                          \
 
-    
+
     TEST_DOUBLE_TO_STR(1, 1, "1");
     TEST_DOUBLE_TO_STR(-1, 2, "-1");
     TEST_DOUBLE_TO_STR(1.1, 3, "1.1");
@@ -86,10 +86,10 @@
     TEST_STR_TO_LONG("MHz", 0, 0);
     TEST_STR_TO_LONG("1.4", 1, 1);
     TEST_STR_TO_LONG(" 1", 2, 1);
-    TEST_STR_TO_LONG(" +100", 5, 100);  // space and +
-    TEST_STR_TO_LONG("0xFF", 4, 255);   // hexadecimal FF
-    TEST_STR_TO_LONG("077", 3, 63);     // octal 77
-    TEST_STR_TO_LONG("018", 2, 1);      // octal 1, 8 is ignored
+    TEST_STR_TO_LONG(" +100", 5, 100); // space and +
+    TEST_STR_TO_LONG("0xFF", 4, 255); // hexadecimal FF
+    TEST_STR_TO_LONG("077", 3, 63); // octal 77
+    TEST_STR_TO_LONG("018", 2, 1); // octal 1, 8 is ignored
 }
 
 void test_strToDouble() {
@@ -131,9 +131,57 @@
     CU_ASSERT_TRUE(compareStr("ABCD", 4, "abcd", 4));
     CU_ASSERT_TRUE(compareStr("AbCd", 3, "AbCE", 3));
     CU_ASSERT_TRUE(compareStr("ABCD", 1, "a", 1));
-    
+
     CU_ASSERT_FALSE(compareStr("abcd", 1, "efgh", 1));
     CU_ASSERT_FALSE(compareStr("ABCD", 4, "abcd", 3));
+}
+
+void test_locateText() {
+
+    char * v;
+    char * b;
+    size_t l;
+    int result;
+
+
+#define TEST_LOCATE_TEXT(s, ex_res, ex_off, ex_len)      \
+    do {                                                \
+        v = (s);                                        \
+        b = NULL;                                       \
+        l = 0;                                          \
+        result = locateText(v, strlen(v), &b, &l);       \
+        CU_ASSERT(result == ex_res);                    \
+        if (result == TRUE) {                           \
+                CU_ASSERT(b == (s + ex_off));           \
+                CU_ASSERT(l == ex_len);                 \
+        } else {                                        \
+                CU_ASSERT(b == NULL);                   \
+                CU_ASSERT(l == 0);                      \
+        }                                               \
+    } while(0)                                          \
+
+
+    TEST_LOCATE_TEXT("", TRUE, 0, 0);
+    TEST_LOCATE_TEXT("   ", TRUE, 3, 0);
+    TEST_LOCATE_TEXT("a", TRUE, 0, 1);
+    TEST_LOCATE_TEXT("ab", TRUE, 0, 2);
+    TEST_LOCATE_TEXT("abc", TRUE, 0, 3);
+    TEST_LOCATE_TEXT(" abc", TRUE, 1, 3);
+    TEST_LOCATE_TEXT(" abc def", TRUE, 1, 7);
+    TEST_LOCATE_TEXT(" abc def ", TRUE, 1, 7);
+    TEST_LOCATE_TEXT("\"\"", TRUE, 1, 0);
+    TEST_LOCATE_TEXT("\"a\"", TRUE, 1, 1);
+    TEST_LOCATE_TEXT(" \"a\" ", TRUE, 2, 1);
+    TEST_LOCATE_TEXT(" \"a\"  ", TRUE, 2, 1);
+    TEST_LOCATE_TEXT(" \"a\"  ,", TRUE, 2, 1);
+    TEST_LOCATE_TEXT(" \"a,b\"", TRUE, 2, 3);
+    TEST_LOCATE_TEXT(" \"a,b\"     ,", TRUE, 2, 3);
+    TEST_LOCATE_TEXT(" a b    ", TRUE, 1, 3);
+    TEST_LOCATE_TEXT(" a b   ,", TRUE, 1, 3);
+    TEST_LOCATE_TEXT(" \"a \" ", TRUE, 2, 2);
+    TEST_LOCATE_TEXT(" \"a  ", FALSE, 0, 0);
+    TEST_LOCATE_TEXT(" \"a\" a, a ", FALSE, 0, 0);
+    TEST_LOCATE_TEXT(" \"a\" , a ", TRUE, 2, 1);
 }
 
 void test_locateStr() {
@@ -159,8 +207,7 @@
                 CU_ASSERT(l == 0);                      \
         }                                               \
     } while(0)                                          \
-
-
+    
     TEST_LOCATE_STR("", TRUE, 0, 0);
     TEST_LOCATE_STR("   ", TRUE, 3, 0);
     TEST_LOCATE_STR("a", TRUE, 0, 1);
@@ -169,19 +216,35 @@
     TEST_LOCATE_STR(" abc", TRUE, 1, 3);
     TEST_LOCATE_STR(" abc def", TRUE, 1, 7);
     TEST_LOCATE_STR(" abc def ", TRUE, 1, 7);
-    TEST_LOCATE_STR("\"\"", TRUE, 1, 0);
-    TEST_LOCATE_STR("\"a\"", TRUE, 1, 1);
-    TEST_LOCATE_STR(" \"a\" ", TRUE, 2, 1);
-    TEST_LOCATE_STR(" \"a\"  ", TRUE, 2, 1);
-    TEST_LOCATE_STR(" \"a\"  ,", TRUE, 2, 1);
-    TEST_LOCATE_STR(" \"a,b\"", TRUE, 2, 3);
-    TEST_LOCATE_STR(" \"a,b\"     ,", TRUE, 2, 3);
+    TEST_LOCATE_STR("\"\"", TRUE, 0, 2);
+    TEST_LOCATE_STR("\"a\"", TRUE, 0, 3);
+    TEST_LOCATE_STR(" \"a\" ", TRUE, 1, 3);
+    TEST_LOCATE_STR(" \"a\"  ", TRUE, 1, 3);
+    TEST_LOCATE_STR(" \"a\"  ,", TRUE, 1, 3);
+    TEST_LOCATE_STR(" \"a,b\"", TRUE, 1, 2);
+    TEST_LOCATE_STR(" \"a,b\"     ,", TRUE, 1, 2);
     TEST_LOCATE_STR(" a b    ", TRUE, 1, 3);
     TEST_LOCATE_STR(" a b   ,", TRUE, 1, 3);
-    TEST_LOCATE_STR(" \"a \" ", TRUE, 2, 2);
-    TEST_LOCATE_STR(" \"a  ", FALSE, 0, 0);
-    TEST_LOCATE_STR(" \"a\" a, a ", FALSE, 0, 0);
-    TEST_LOCATE_STR(" \"a\" , a ", TRUE, 2, 1);
+    TEST_LOCATE_STR(" \"a \" ", TRUE, 1, 4);
+    TEST_LOCATE_STR(" \"a  ", TRUE, 1, 2);
+    TEST_LOCATE_STR(" \"a\" a, a ", TRUE, 1, 5);
+    TEST_LOCATE_STR(" \"a\" , a ", TRUE, 1, 3);
+}
+
+void test_matchPattern() {
+    bool_t result;
+    
+#define TEST_MATCH_PATTERN(p, s, r)                             \
+    do {                                                        \
+        result = matchPattern(p, strlen(p), s, strlen(s));      \
+        CU_ASSERT_EQUAL(result, r);                             \
+    } while(0)                                                  \
+
+    TEST_MATCH_PATTERN("A", "a", TRUE);
+    TEST_MATCH_PATTERN("Ab", "a", TRUE);
+    TEST_MATCH_PATTERN("Ab", "ab", TRUE);
+    TEST_MATCH_PATTERN("Ab", "aB", TRUE);
+    TEST_MATCH_PATTERN("AB", "a", FALSE);
 }
 
 int main() {
@@ -206,7 +269,9 @@
             || (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, "locateText", test_locateText))
             || (NULL == CU_add_test(pSuite, "locateStr", test_locateStr))
+            || (NULL == CU_add_test(pSuite, "matchPattern", test_matchPattern))
             ) {
         CU_cleanup_registry();
         return CU_get_error();
diff --git a/scpi/scpi.c b/scpi/scpi.c
index 7c377a2..19487a0 100644
--- a/scpi/scpi.c
+++ b/scpi/scpi.c
@@ -43,7 +43,6 @@
 #include <stdint.h>
 
 static size_t patternSeparatorPos(const char * pattern, size_t len);
-static size_t patternSeparatorShortPos(const char * pattern, size_t len);
 static size_t cmdSeparatorPos(const char * cmd, size_t len);
 static size_t cmdTerminatorPos(const char * cmd, size_t len);
 static size_t cmdlineSeparatorPos(const char * cmd, size_t len);
@@ -55,16 +54,6 @@
 static void paramSkipBytes(scpi_context_t * context, size_t num);
 static void paramSkipWhitespace(scpi_context_t * context);
 static bool_t paramNext(scpi_context_t * context, bool_t mandatory);
-
-#define max(a,b) \
-   ({ __typeof__ (a) _a = (a); \
-       __typeof__ (b) _b = (b); \
-     _a > _b ? _a : _b; })
-
-#define min(a,b) \
-   ({ __typeof__ (a) _a = (a); \
-       __typeof__ (b) _b = (b); \
-     _a < _b ? _a : _b; })
 
 /*
 int _strnicmp(const char* s1, const char* s2, size_t len) {
@@ -98,23 +87,6 @@
     } else {
         return separator - pattern;
     }
-}
-
-/**
- * Pattern is composed from upper case an lower case letters. This function
- * search the first lowercase letter
- * @param pattern
- * @param len - max search length
- * @return position of separator or len
- */
-size_t patternSeparatorShortPos(const char * pattern, size_t len) {
-    size_t i;
-    for (i = 0; (i < len) && pattern[i]; i++) {
-        if (islower(pattern[i])) {
-            return i;
-        }
-    }
-    return i;
 }
 
 /**
@@ -221,10 +193,8 @@
     while (1) {
         int pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_end - pattern_ptr);
         int cmd_sep_pos = cmdSeparatorPos(cmd_ptr, cmd_end - cmd_ptr);
-        int pattern_sep_pos_short = patternSeparatorShortPos(pattern_ptr, pattern_sep_pos);
 
-        if (compareStr(pattern_ptr, pattern_sep_pos, cmd_ptr, cmd_sep_pos) ||
-                compareStr(pattern_ptr, pattern_sep_pos_short, cmd_ptr, cmd_sep_pos)) {
+        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;
@@ -262,7 +232,6 @@
 
     return result;
 }
-
 
 /**
  * Write data to SCPI output
@@ -326,6 +295,7 @@
             for (i = 0; context->cmdlist[i].pattern != NULL; i++) {
                 if (cmdMatch(context->cmdlist[i].pattern, cmdline_ptr, cmd_len)) {
                     if (context->cmdlist[i].callback != NULL) {
+                        context->error = FALSE;
                         context->paramlist.cmd = &context->cmdlist[i];
                         context->paramlist.parameters = cmdline_ptr + cmd_len;
                         context->paramlist.length = cmdlineSeparatorPos(context->paramlist.parameters, cmdline_end - context->paramlist.parameters);
@@ -338,7 +308,7 @@
                         writeNewLine(context); // conditionaly write new line
 
                         paramSkipWhitespace(context);
-                        if (context->paramlist.length != 0) {
+                        if (context->paramlist.length != 0 && !context->error) {
                             SCPI_ErrorPush(context, SCPI_ERROR_PARAMETER_NOT_ALLOWED);
                         }
 
@@ -537,6 +507,7 @@
             paramSkipBytes(context, 1);
             paramSkipWhitespace(context);
         } else {
+            printf("******** :%c:\r\n", context->paramlist.parameters[0]);
             SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SEPARATOR);
             return FALSE;
         }
@@ -553,33 +524,25 @@
  * @return 
  */
 bool_t SCPI_ParamInt(scpi_context_t * context, int32_t * value, bool_t mandatory) {
-    size_t len;
+    char * param;
+    size_t param_len;
+    size_t num_len;
 
     if (!value) {
         return FALSE;
     }
 
-    if (!paramNext(context, mandatory)) {
+    if (!SCPI_ParamString(context, &param, &param_len, mandatory)) {
         return FALSE;
-    }
-       
-    len = strToLong(context->paramlist.parameters, value);
-   
-    if (len == 0) {
-        if (mandatory) {
-            SCPI_ErrorPush(context, SCPI_ERROR_SYNTAX);
-        }
-        return FALSE;
-    } else {
-        paramSkipBytes(context, len);
     }
 
-    paramSkipWhitespace(context);
-    if ((context->paramlist.length > 0) && (context->paramlist.parameters[0] != ',')) {
+    num_len = strToLong(param, value);
+
+    if (num_len != param_len) {
         SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
         return FALSE;
     }
-    
+
     return TRUE;
 }
 
@@ -591,33 +554,25 @@
  * @return 
  */
 bool_t SCPI_ParamDouble(scpi_context_t * context, double * value, bool_t mandatory) {
-    size_t len;
+    char * param;
+    size_t param_len;
+    size_t num_len;
 
     if (!value) {
         return FALSE;
     }
 
-    if (!paramNext(context, mandatory)) {
+    if (!SCPI_ParamString(context, &param, &param_len, mandatory)) {
         return FALSE;
     }
-   
-    len = strToDouble(context->paramlist.parameters, value);
 
-    if (len == 0) {
-        if (mandatory) {
-            SCPI_ErrorPush(context, SCPI_ERROR_SYNTAX);
-        }
-        return FALSE;
-    } else {
-        paramSkipBytes(context, len);
-    }
+    num_len = strToDouble(param, value);
 
-    paramSkipWhitespace(context);
-    if ((context->paramlist.length > 0) && (context->paramlist.parameters[0] != ',')) {
+    if (num_len != param_len) {
         SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
         return FALSE;
     }
-    
+
     return TRUE;
 }
 
@@ -631,17 +586,48 @@
  */
 bool_t SCPI_ParamString(scpi_context_t * context, char ** value, size_t * len, bool_t mandatory) {
     size_t length;
-    
+
     if (!value || !len) {
         return FALSE;
     }
-    
+
     if (!paramNext(context, mandatory)) {
         return FALSE;
     }
 
     if (locateStr(context->paramlist.parameters, context->paramlist.length, value, &length)) {
         paramSkipBytes(context, length);
+        paramSkipWhitespace(context);
+        if (len) {
+            *len = length;
+        }
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/**
+ * Parse text parameter (can be inside "")
+ * @param context
+ * @param value
+ * @param len
+ * @param mandatory
+ * @return 
+ */
+bool_t SCPI_ParamText(scpi_context_t * context, char ** value, size_t * len, bool_t mandatory) {
+    size_t length;
+
+    if (!value || !len) {
+        return FALSE;
+    }
+
+    if (!paramNext(context, mandatory)) {
+        return FALSE;
+    }
+
+    if (locateText(context->paramlist.parameters, context->paramlist.length, value, &length)) {
+        paramSkipBytes(context, length);
         if (len) {
             *len = length;
         }
diff --git a/scpi/scpi.h b/scpi/scpi.h
index f981665..1f9f4c3 100644
--- a/scpi/scpi.h
+++ b/scpi/scpi.h
@@ -90,6 +90,7 @@
         scpi_interface_t * interface;
         int_fast16_t output_count;
         int_fast16_t input_count;
+        bool_t error;
     };
 
 
diff --git a/scpi/scpi_error.c b/scpi/scpi_error.c
index 5b67c5e..ca80239 100644
--- a/scpi/scpi_error.c
+++ b/scpi/scpi_error.c
@@ -46,7 +46,7 @@
  * @param context - scpi context
  */
 void SCPI_ErrorClear(scpi_context_t * context) {
-    (void)context;
+    (void) context;
     scpi_err = 0;
 }
 
@@ -57,8 +57,8 @@
  */
 void SCPI_ErrorPush(scpi_context_t * context, int16_t err) {
     scpi_err = err;
-    
-     // Command error (e.g. syntax error)
+
+    // Command error (e.g. syntax error)
     if ((err < -101) && (err > -158)) {
         SCPI_RegSetBits(SCPI_REG_ESR, ESR_CER);
     }
@@ -71,10 +71,14 @@
     // Device Dependent Error
     if ((err < -501) && (err > -748)) {
         SCPI_RegSetBits(SCPI_REG_ESR, ESR_DER);
-    }  
-    
-    if (context && context->interface && context->interface->error) {
-        context->interface->error(context, err);
+    }
+
+    if (context) {
+        if (context->interface && context->interface->error) {
+            context->interface->error(context, err);
+        }
+
+        context->error = TRUE;
     }
 }
 
@@ -84,7 +88,7 @@
  * @return error number
  */
 int16_t SCPI_ErrorPop(scpi_context_t * context) {
-    (void)context;
+    (void) context;
     int16_t result = scpi_err;
     scpi_err = 0;
     return result;
@@ -96,7 +100,7 @@
  * @return Error string representation
  */
 const char * SCPI_ErrorTranslate(int16_t err) {
-    switch(err) {
+    switch (err) {
         case 0: return "No error";
         case SCPI_ERROR_SYNTAX: return "Syntax error";
         case SCPI_ERROR_INVALID_SEPARATOR: return "Invalid separator";
diff --git a/scpi/scpi_units.c b/scpi/scpi_units.c
index 205639b..723e0d9 100644
--- a/scpi/scpi_units.c
+++ b/scpi/scpi_units.c
@@ -99,44 +99,65 @@
     SCPI_UNITS_LIST_END,
 };
 
-
 const scpi_special_number_def_t scpi_special_numbers_def[] = {
-    { .name = "MIN", .type = SCPI_NUM_MIN},
-    { .name = "MINIMUM", .type = SCPI_NUM_MIN},
-    { .name = "MAX", .type = SCPI_NUM_MAX},
-    { .name = "MAXIMUM", .type = SCPI_NUM_MAX},
-    { .name = "DEF", .type = SCPI_NUM_DEF},
-    { .name = "DEFAULT", .type = SCPI_NUM_DEF},
+    { .name = "MINimum", .type = SCPI_NUM_MIN},
+    { .name = "MAXimum", .type = SCPI_NUM_MAX},
+    { .name = "DEFault", .type = SCPI_NUM_DEF},
+    { .name = "UP", .type = SCPI_NUM_UP},
+    { .name = "DOWN", .type = SCPI_NUM_DOWN},
     { .name = "NAN", .type = SCPI_NUM_NAN},
     { .name = "INF", .type = SCPI_NUM_INF},
     { .name = "NINF", .type = SCPI_NUM_NINF},
     SCPI_SPECIAL_NUMBERS_LIST_END,
 };
 
-static scpi_special_number_t translateSpecialNumber(const char * str, size_t len) {
+static scpi_special_number_t translateSpecialNumber(const scpi_special_number_def_t * specs, const char * str, size_t len) {
     int i;
 
-    for (i = 0; scpi_special_numbers_def[i].name != NULL; i++) {
-        if (compareStr(str, len, scpi_special_numbers_def[i].name, strlen(scpi_special_numbers_def[i].name))) {
-            return scpi_special_numbers_def[i].type;
+    for (i = 0; specs[i].name != NULL; i++) {
+        if (matchPattern(specs[i].name, strlen(specs[i].name), str, len)) {
+            return specs[i].type;
         }
     }
 
     return SCPI_NUM_NUMBER;
 }
 
-static const scpi_unit_def_t * searchUnit(const char * unit, size_t len) {
+static const char * translateSpecialNumberInverse(const scpi_special_number_def_t * specs, scpi_special_number_t type) {
     int i;
-    for(i = 0; scpi_units_def[i].name != NULL; i++) {
-        if (compareStr(unit, len, scpi_units_def[i].name, strlen(scpi_units_def[i].name))) {
-            return &scpi_units_def[i];
+
+    for (i = 0; specs[i].name != NULL; i++) {
+        if (specs[i].type == type) {
+            return specs[i].name;
         }
     }
-    
+
     return NULL;
 }
 
-static bool_t transformNumber(const char * unit, size_t len, scpi_number_t * value) {
+static const scpi_unit_def_t * translateUnit(const scpi_unit_def_t * units, const char * unit, size_t len) {
+    int i;
+    for (i = 0; units[i].name != NULL; i++) {
+        if (compareStr(unit, len, units[i].name, strlen(units[i].name))) {
+            return &units[i];
+        }
+    }
+
+    return NULL;
+}
+
+static const char * translateUnitInverse(const scpi_unit_def_t * units, const scpi_unit_t unit) {
+    int i;
+    for (i = 0; units[i].name != NULL; i++) {
+        if ((units[i].unit == unit) && (units[i].mult == 1)) {
+            return units[i].name;
+        }
+    }
+
+    return NULL;
+}
+
+static bool_t transformNumber(const scpi_unit_def_t * units, const char * unit, size_t len, scpi_number_t * value) {
     size_t s;
     const scpi_unit_def_t * unitDef;
     s = skipWhitespace(unit, len);
@@ -145,16 +166,16 @@
         value->unit = SCPI_UNIT_NONE;
         return TRUE;
     }
-    
-    unitDef = searchUnit(unit + s, len - s);
-    
+
+    unitDef = translateUnit(units, unit + s, len - s);
+
     if (unitDef == NULL) {
         return FALSE;
     }
-    
+
     value->value *= unitDef->mult;
     value->unit = unitDef->unit;
-    
+
     return TRUE;
 }
 
@@ -171,19 +192,26 @@
     size_t len;
     size_t numlen;
 
-    result = SCPI_ParamString(context, &param, &len, mandatory);
+    // TODO: get scpi_special_numbers_def and scpi_units_def from context    
 
-    if (!result) {
-        return FALSE;
-    }
+    result = SCPI_ParamString(context, &param, &len, mandatory);
 
     if (!value) {
         return FALSE;
     }
 
+    if (!result) {
+        if (mandatory) {
+            return FALSE;
+        } else {
+            value->type = SCPI_NUM_DEF;
+            return TRUE;
+        }
+    }
+
     value->unit = SCPI_UNIT_NONE;
     value->value = 0.0;
-    value->type = translateSpecialNumber(param, len);
+    value->type = translateSpecialNumber(scpi_special_numbers_def, param, len);
 
     if (value->type != SCPI_NUM_NUMBER) {
         // found special type
@@ -193,13 +221,44 @@
     numlen = strToDouble(param, &value->value);
 
     if (numlen <= len) {
-        if (transformNumber(param + numlen, len - numlen, value)) {
+        if (transformNumber(scpi_units_def, param + numlen, len - numlen, value)) {
             return TRUE;
         } else {
-            SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SUFFIX);            
+            SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SUFFIX);
         }
     }
     return FALSE;
 
 }
 
+size_t SCPI_NumberToStr(scpi_context_t * context, scpi_number_t * value, char * str, size_t len) {
+    const char * type;
+    const char * unit;
+    size_t result;
+
+    (void) context; // TODO: get scpi_special_numbers_def and scpi_units_def from context
+
+
+    if (!value || !str) {
+        return 0;
+    }
+
+    type = translateSpecialNumberInverse(scpi_special_numbers_def, value->type);
+
+    if (type) {
+        strncpy(str, type, len);
+        return min(strlen(type), len);
+    }
+
+    result = doubleToStr(value->value, str, len);
+
+    unit = translateUnitInverse(scpi_units_def, value->unit);
+
+    if (unit) {
+        strncat(str, " ", len);
+        strncat(str, unit, len);
+        result += strlen(unit) + 1;
+    }
+
+    return result;
+}
\ No newline at end of file
diff --git a/scpi/scpi_units.h b/scpi/scpi_units.h
index 7144728..072eb18 100644
--- a/scpi/scpi_units.h
+++ b/scpi/scpi_units.h
@@ -94,7 +94,7 @@
 
 
     bool_t SCPI_ParamNumber(scpi_context_t * context, scpi_number_t * value, bool_t mandatory);
-
+    size_t SCPI_NumberToStr(scpi_context_t * context, scpi_number_t * value, char * str, size_t len);
 
 #ifdef	__cplusplus
 }
diff --git a/scpi/scpi_utils.c b/scpi/scpi_utils.c
index 0815a8c..94aaf8f 100644
--- a/scpi/scpi_utils.c
+++ b/scpi/scpi_utils.c
@@ -41,6 +41,8 @@
 #include <string.h>
 #include <ctype.h>
 
+static size_t patternSeparatorShortPos(const char * pattern, size_t len);
+
 /**
  * Find the first occurrence in str of a character in set.
  * @param str
@@ -152,7 +154,7 @@
     return FALSE;
 }
 
-bool_t locateStr(const char * str1, size_t len1, char ** str2, size_t * len2) {
+bool_t locateText(const char * str1, size_t len1, char ** str2, size_t * len2) {
     size_t i;
     int quot = 0;
     int32_t strStart = -1;
@@ -230,6 +232,68 @@
     return valid;
 }
 
+bool_t locateStr(const char * str1, size_t len1, char ** str2, size_t * len2) {
+    size_t i;
+    int32_t strStart = -1;
+    int32_t strStop = -1;
+    int valid = 0;
+
+
+    for (i = 0; i < len1; i++) {
+        if ((strStart < 0) && isspace(str1[i])) {
+            continue;
+        }
+
+        if (strStart < 0) {
+            strStart = i;
+        }
+
+        if (!isspace(str1[i]) && (str1[i] != ',')) {
+            strStop = i;
+        }
+
+        if (isspace(str1[i])) {
+            continue;
+        }
+
+        if (str1[i] == ',') {
+            valid = 1;
+
+            if (strStop < 0) {
+                strStop = i;
+            }
+            break;
+        }
+    }
+
+    if (i == len1) {
+        valid = 1;
+        if (strStop < 0) {
+            strStop = i;
+        } else {
+            strStop++;
+        }
+        if (strStart < 0) {
+            strStart = i;
+        }
+    } else {
+        strStop++;
+    }
+
+
+    if (valid) {
+        if (str2) {
+            *str2 = (char *) &str1[strStart];
+        }
+
+        if (len2) {
+            *len2 = strStop - strStart;
+        }
+    }
+
+    return valid;
+}
+
 /**
  * Count white spaces from the beggining
  * @param cmd - command
@@ -244,4 +308,36 @@
         }
     }
     return len;
-}
\ No newline at end of file
+}
+
+
+/**
+ * Pattern is composed from upper case an lower case letters. This function
+ * search the first lowercase letter
+ * @param pattern
+ * @param len - max search length
+ * @return position of separator or len
+ */
+size_t patternSeparatorShortPos(const char * pattern, size_t len) {
+    size_t i;
+    for (i = 0; (i < len) && pattern[i]; i++) {
+        if (islower(pattern[i])) {
+            return i;
+        }
+    }
+    return i;
+}
+
+/**
+ * Match pattern and str. Pattern is in format UPPERCASElowercase
+ * @param pattern
+ * @param pattern_len
+ * @param str
+ * @param str_len
+ * @return 
+ */
+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);
+}
diff --git a/scpi/scpi_utils.h b/scpi/scpi_utils.h
index 348eeaf..521fe87 100644
--- a/scpi/scpi_utils.h
+++ b/scpi/scpi_utils.h
@@ -50,8 +50,21 @@
     size_t doubleToStr(double val, char * str, size_t len);
     size_t strToLong(const char * str, int32_t * val);
     size_t strToDouble(const char * str, double * val);
+    bool_t locateText(const char * str1, size_t len1, char ** str2, size_t * len2);
     bool_t locateStr(const char * str1, size_t len1, char ** str2, size_t * len2);
     size_t skipWhitespace(const char * cmd, size_t len);
+    bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len);
+
+
+#define max(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a > _b ? _a : _b; })
+
+#define min(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a < _b ? _a : _b; })
 
 #ifdef	__cplusplus
 }
diff --git a/test-parser.c b/test-parser.c
index 640e5c2..2bc38dc 100644
--- a/test-parser.c
+++ b/test-parser.c
@@ -42,22 +42,26 @@
 #include "scpi/scpi_error.h"
 #include "scpi/scpi_constants.h"
 #include "scpi/scpi_minimal.h"
+#include "scpi/scpi_utils.h"
+#include "scpi/scpi_units.h"
 
 int DMM_MeasureVoltageDcQ(scpi_context_t * context) {
-    double param1, param2;
-    fprintf(stderr, "meas:volt:dc "); // debug command name
-    
-    // read first parameter
-    if (SCPI_ParamDouble(context, &param1, false)) {
-        fprintf(stderr, "P1=%lf ", param1);
-    }
-    
-    // read second paraeter
-    if (SCPI_ParamDouble(context, &param2, false)) {
-        fprintf(stderr, "P2=%lf ", param2);
+    scpi_number_t param1, param2;
+    char bf[15];
+    fprintf(stderr, "meas:volt:dc\r\n"); // debug command name   
+
+    // read first parameter if present
+    if (SCPI_ParamNumber(context, &param1, false)) {
+        SCPI_NumberToStr(context, &param1, bf, 15);
+        fprintf(stderr, "\tP1=%s\r\n", bf);
     }
 
-    fprintf(stderr, "\r\n");
+    // read second paraeter if present
+    if (SCPI_ParamNumber(context, &param2, false)) {
+        SCPI_NumberToStr(context, &param2, bf, 15);
+        fprintf(stderr, "\tP2=%s\r\n", bf);
+    }
+
     SCPI_ResultDouble(context, 0);
     return 0;
 }
@@ -118,7 +122,7 @@
 
 int SCPI_Error(scpi_context_t * context, int_fast16_t err) {
     (void) context;
-    
+
     fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int32_t) err, SCPI_ErrorTranslate(err));
     return 0;
 }
@@ -144,42 +148,50 @@
 /*
  * 
  */
-#include "scpi/scpi_utils.h"
 int main(int argc, char** argv) {
     (void) argc;
     (void) argv;
     int result;
-   
-    //printf("%.*s %s\r\n",  3, "asdadasdasdasdas", "b");
-    
+
     SCPI_Init(&scpi_context, scpi_commands, &scpi_buffer, &scpi_interface);
 
-    // // interactive demo
-    //  char smbuffer[10];
-    //  while(1) {
-    //          fgets(smbuffer, 10, stdin);
-    //          SCPI_Input(&scpi_context, smbuffer, strlen(smbuffer));      
-    //  }
-       
-    result = SCPI_Input(&scpi_context, "*CLS\r\n", 6);
-    result = SCPI_Input(&scpi_context, "*RST\r\n", 6);
-    result = SCPI_Input(&scpi_context, "MEAS:volt:DC? 12,50;*OPC\r\n", 26);
-    result = SCPI_Input(&scpi_context, "*IDN?\r\n", 7);
-    result = SCPI_Input(&scpi_context, "SYST:VERS?", 10);
-    result = SCPI_Input(&scpi_context, "\r\n*ID", 5);
-    result = SCPI_Input(&scpi_context, "N?", 2);
-    result = SCPI_Input(&scpi_context, NULL, 0); // emulate command timeout
+#define TEST_SCPI_INPUT(cmd)    result = SCPI_Input(&scpi_context, cmd, strlen(cmd))
 
-    result = SCPI_Input(&scpi_context, "*ESE\r\n", 6);
-    result = SCPI_Input(&scpi_context, "*ESE 0x20\r\n", 11);
+    TEST_SCPI_INPUT("*CLS\r\n");
+    TEST_SCPI_INPUT("*RST\r\n");
+    TEST_SCPI_INPUT("MEAS:volt:DC? 12,50;*OPC\r\n");
+    TEST_SCPI_INPUT("*IDN?\r\n");
+    TEST_SCPI_INPUT("SYST:VERS?");
+    TEST_SCPI_INPUT("\r\n*ID");
+    TEST_SCPI_INPUT("N?");
+    TEST_SCPI_INPUT(""); // emulate command timeout
 
-    result = SCPI_Input(&scpi_context, "IDN?\r\n", 6); // cause error -113, undefined header
+    TEST_SCPI_INPUT("*ESE\r\n"); // cause error -109, missing parameter
+    TEST_SCPI_INPUT("*ESE 0x20\r\n");
 
-    result = SCPI_Input(&scpi_context, "SYST:ERR?\r\n", 11);
-    result = SCPI_Input(&scpi_context, "SYST:ERR?\r\n", 11);
-    result = SCPI_Input(&scpi_context, "*STB?\r\n", 6);
-    result = SCPI_Input(&scpi_context, "*ESR?\r\n", 6);
-    result = SCPI_Input(&scpi_context, "*STB?\r\n", 6);
+    TEST_SCPI_INPUT("IDN?\r\n"); // cause error -113, undefined header
+
+    TEST_SCPI_INPUT("SYST:ERR?\r\n");
+    TEST_SCPI_INPUT("SYST:ERR?\r\n");
+    TEST_SCPI_INPUT("*STB?\r\n");
+    TEST_SCPI_INPUT("*ESR?\r\n");
+    TEST_SCPI_INPUT("*STB?\r\n");
+
+    TEST_SCPI_INPUT("meas:volt:dc? 0.01 V, Default\r\n");
+    TEST_SCPI_INPUT("meas:volt:dc?\r\n");
+    TEST_SCPI_INPUT("meas:volt:dc? def, 0.00001\r\n");
+    TEST_SCPI_INPUT("meas:volt:dc? 0.00001\r\n");
+
+
+    //printf("%.*s %s\r\n",  3, "asdadasdasdasdas", "b");
+    // interactive demo
+    //char smbuffer[10];
+    //while (1) {
+    //    fgets(smbuffer, 10, stdin);
+    //    SCPI_Input(&scpi_context, smbuffer, strlen(smbuffer));
+    //}
+
+
     return (EXIT_SUCCESS);
 }
 

--
Gitblit v1.9.1