From 2751fbd15df39dee53fe8ac4d9c54fc8e258c457 Mon Sep 17 00:00:00 2001
From: Jan Breuer <jan.breuer@jaybee.cz>
Date: 周一, 26 11月 2012 22:48:15 +0800
Subject: [PATCH] SCPI units support + netbeans project

---
 netbeans/tests/test_scpi_utils.c         |  220 +++++++
 .gitignore                               |    3 
 test-parser.c                            |    7 
 netbeans/nbproject/Makefile-impl.mk      |  133 ++++
 scpi/scpi_error.h                        |    2 
 netbeans/.dep.inc                        |    5 
 netbeans/core                            |    0 
 netbeans/nbproject/Makefile-Debug.mk     |  238 +++++++
 netbeans/nbproject/Package-Release.bash  |   75 ++
 netbeans/nbproject/Makefile-variables.mk |   35 +
 netbeans/Makefile                        |  128 ++++
 netbeans/nbproject/Package-Debug.bash    |   75 ++
 scpi/scpi_units.h                        |  104 +++
 netbeans/nbproject/configurations.xml    |  167 +++++
 scpi/scpi_utils.c                        |  120 +++
 netbeans/nbproject/project.xml           |   25 
 netbeans/nbproject/Makefile-Release.mk   |  238 +++++++
 scpi/scpi_error.c                        |    2 
 scpi/scpi_utils.h                        |    5 
 scpi/scpi.c                              |   61 +
 scpi/scpi_units.c                        |  205 ++++++
 scpi/scpi_ieee488.c                      |    3 
 22 files changed, 1,811 insertions(+), 40 deletions(-)

diff --git a/.gitignore b/.gitignore
index c4d3af6..23c209e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,6 @@
 
 # Backup files
 *~
+/netbeans/nbproject/private/
+/netbeans/build/Debug/
+/netbeans/dist/Debug/
\ No newline at end of file
diff --git a/netbeans/.dep.inc b/netbeans/.dep.inc
new file mode 100644
index 0000000..4560e55
--- /dev/null
+++ b/netbeans/.dep.inc
@@ -0,0 +1,5 @@
+# This code depends on make tool being used
+DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
+ifneq (${DEPFILES},)
+include ${DEPFILES}
+endif
diff --git a/netbeans/Makefile b/netbeans/Makefile
new file mode 100644
index 0000000..ec9de69
--- /dev/null
+++ b/netbeans/Makefile
@@ -0,0 +1,128 @@
+#
+#  There exist several targets which are by default empty and which can be 
+#  used for execution of your targets. These targets are usually executed 
+#  before and after some main targets. They are: 
+#
+#     .build-pre:              called before 'build' target
+#     .build-post:             called after 'build' target
+#     .clean-pre:              called before 'clean' target
+#     .clean-post:             called after 'clean' target
+#     .clobber-pre:            called before 'clobber' target
+#     .clobber-post:           called after 'clobber' target
+#     .all-pre:                called before 'all' target
+#     .all-post:               called after 'all' target
+#     .help-pre:               called before 'help' target
+#     .help-post:              called after 'help' target
+#
+#  Targets beginning with '.' are not intended to be called on their own.
+#
+#  Main targets can be executed directly, and they are:
+#  
+#     build                    build a specific configuration
+#     clean                    remove built files from a configuration
+#     clobber                  remove all built files
+#     all                      build all configurations
+#     help                     print help mesage
+#  
+#  Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+#  .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+#  Available make variables:
+#
+#     CND_BASEDIR                base directory for relative paths
+#     CND_DISTDIR                default top distribution directory (build artifacts)
+#     CND_BUILDDIR               default top build directory (object files, ...)
+#     CONF                       name of current configuration
+#     CND_PLATFORM_${CONF}       platform name (current configuration)
+#     CND_ARTIFACT_DIR_${CONF}   directory of build artifact (current configuration)
+#     CND_ARTIFACT_NAME_${CONF}  name of build artifact (current configuration)
+#     CND_ARTIFACT_PATH_${CONF}  path to build artifact (current configuration)
+#     CND_PACKAGE_DIR_${CONF}    directory of package (current configuration)
+#     CND_PACKAGE_NAME_${CONF}   name of package (current configuration)
+#     CND_PACKAGE_PATH_${CONF}   path to package (current configuration)
+#
+# NOCDDL
+
+
+# Environment 
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+
+
+# build
+build: .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post: .build-impl
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post: .clean-impl
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post: .clobber-impl
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post: .all-impl
+# Add your post 'all' code here...
+
+
+# build tests
+build-tests: .build-tests-post
+
+.build-tests-pre:
+# Add your pre 'build-tests' code here...
+
+.build-tests-post: .build-tests-impl
+# Add your post 'build-tests' code here...
+
+
+# run tests
+test: .test-post
+
+.test-pre:
+# Add your pre 'test' code here...
+
+.test-post: .test-impl
+# Add your post 'test' code here...
+
+
+# help
+help: .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post: .help-impl
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
+
+# include project make variables
+include nbproject/Makefile-variables.mk
diff --git a/netbeans/core b/netbeans/core
new file mode 100644
index 0000000..7252066
--- /dev/null
+++ b/netbeans/core
Binary files differ
diff --git a/netbeans/nbproject/Makefile-Debug.mk b/netbeans/nbproject/Makefile-Debug.mk
new file mode 100644
index 0000000..c5583ab
--- /dev/null
+++ b/netbeans/nbproject/Makefile-Debug.mk
@@ -0,0 +1,238 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+	${OBJECTDIR}/_ext/760632520/scpi_utils.o \
+	${OBJECTDIR}/_ext/760632520/scpi_ieee488.o \
+	${OBJECTDIR}/_ext/760632520/scpi.o \
+	${OBJECTDIR}/_ext/760632520/scpi_minimal.o \
+	${OBJECTDIR}/_ext/1472/test-parser.o \
+	${OBJECTDIR}/_ext/760632520/scpi_units.o \
+	${OBJECTDIR}/_ext/760632520/scpi_error.o
+
+# Test Directory
+TESTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tests
+
+# Test Files
+TESTFILES= \
+	${TESTDIR}/TestFiles/f3
+
+# C Compiler Flags
+CFLAGS=-Wextra -g3 -O0
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=-lcunit -lcunit
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+	"${MAKE}"  -f nbproject/Makefile-${CND_CONF}.mk ${TESTDIR}/TestFiles/f2
+
+${TESTDIR}/TestFiles/f2: ${OBJECTFILES}
+	${MKDIR} -p ${TESTDIR}/TestFiles
+	${LINK.c} -g3 -o ${TESTDIR}/TestFiles/f2 ${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
+
+${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
+
+${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
+
+${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
+
+${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
+
+${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
+
+${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
+
+# Subprojects
+.build-subprojects:
+
+# Build Test Targets
+.build-tests-conf: .build-conf ${TESTFILES}
+${TESTDIR}/TestFiles/f3: ${TESTDIR}/tests/test_scpi_utils.o ${OBJECTFILES:%.o=%_nomain.o}
+	${MKDIR} -p ${TESTDIR}/TestFiles
+	${LINK.c}   -o ${TESTDIR}/TestFiles/f3 $^ ${LDLIBSOPTIONS} 
+
+
+${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
+
+
+${OBJECTDIR}/_ext/760632520/scpi_utils_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_utils.o ../scpi/scpi_utils.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_utils.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (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;\
+	else  \
+	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_utils.o ${OBJECTDIR}/_ext/760632520/scpi_utils_nomain.o;\
+	fi
+
+${OBJECTDIR}/_ext/760632520/scpi_ieee488_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o ../scpi/scpi_ieee488.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (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;\
+	else  \
+	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o ${OBJECTDIR}/_ext/760632520/scpi_ieee488_nomain.o;\
+	fi
+
+${OBJECTDIR}/_ext/760632520/scpi_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi.o ../scpi/scpi.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (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;\
+	else  \
+	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi.o ${OBJECTDIR}/_ext/760632520/scpi_nomain.o;\
+	fi
+
+${OBJECTDIR}/_ext/760632520/scpi_minimal_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_minimal.o ../scpi/scpi_minimal.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_minimal.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (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;\
+	else  \
+	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_minimal.o ${OBJECTDIR}/_ext/760632520/scpi_minimal_nomain.o;\
+	fi
+
+${OBJECTDIR}/_ext/1472/test-parser_nomain.o: ${OBJECTDIR}/_ext/1472/test-parser.o ../test-parser.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/1472
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/1472/test-parser.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (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;\
+	else  \
+	    ${CP} ${OBJECTDIR}/_ext/1472/test-parser.o ${OBJECTDIR}/_ext/1472/test-parser_nomain.o;\
+	fi
+
+${OBJECTDIR}/_ext/760632520/scpi_units_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_units.o ../scpi/scpi_units.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_units.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (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;\
+	else  \
+	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_units.o ${OBJECTDIR}/_ext/760632520/scpi_units_nomain.o;\
+	fi
+
+${OBJECTDIR}/_ext/760632520/scpi_error_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_error.o ../scpi/scpi_error.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_error.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (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;\
+	else  \
+	    ${CP} ${OBJECTDIR}/_ext/760632520/scpi_error.o ${OBJECTDIR}/_ext/760632520/scpi_error_nomain.o;\
+	fi
+
+# Run Test Targets
+.test-conf:
+	@if [ "${TEST}" = "" ]; \
+	then  \
+	    ${TESTDIR}/TestFiles/f3 || true; \
+	else  \
+	    ./${TEST} || true; \
+	fi
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+	${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+	${RM} ${TESTDIR}/TestFiles/f2
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/netbeans/nbproject/Makefile-Release.mk b/netbeans/nbproject/Makefile-Release.mk
new file mode 100644
index 0000000..107285b
--- /dev/null
+++ b/netbeans/nbproject/Makefile-Release.mk
@@ -0,0 +1,238 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+	${OBJECTDIR}/_ext/760632520/scpi_utils.o \
+	${OBJECTDIR}/_ext/760632520/scpi_ieee488.o \
+	${OBJECTDIR}/_ext/760632520/scpi.o \
+	${OBJECTDIR}/_ext/760632520/scpi_minimal.o \
+	${OBJECTDIR}/_ext/1472/test-parser.o \
+	${OBJECTDIR}/_ext/760632520/scpi_units.o \
+	${OBJECTDIR}/_ext/760632520/scpi_error.o
+
+# Test Directory
+TESTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tests
+
+# Test Files
+TESTFILES= \
+	${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/netbeans
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+	"${MAKE}"  -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/scpi_parser
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/scpi_parser: ${OBJECTFILES}
+	${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+	${LINK.c} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/scpi_parser ${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) -O2 -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) -O2 -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) -O2 -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) -O2 -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) -O2 -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) -O2 -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) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/760632520/scpi_error.o ../scpi/scpi_error.c
+
+# Subprojects
+.build-subprojects:
+
+# Build Test Targets
+.build-tests-conf: .build-conf ${TESTFILES}
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/netbeans: ${TESTDIR}/tests/test_scpi_utils.o ${OBJECTFILES:%.o=%_nomain.o}
+	${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+	${LINK.c}   -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/netbeans $^ ${LDLIBSOPTIONS} 
+
+
+${TESTDIR}/tests/test_scpi_utils.o: tests/test_scpi_utils.c 
+	${MKDIR} -p ${TESTDIR}/tests
+	${RM} $@.d
+	$(COMPILE.c) -O2 -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 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_utils.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
+	then  \
+	    ${RM} $@.d;\
+	    $(COMPILE.c) -O2 -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
+
+${OBJECTDIR}/_ext/760632520/scpi_ieee488_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o ../scpi/scpi_ieee488.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_ieee488.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
+	then  \
+	    ${RM} $@.d;\
+	    $(COMPILE.c) -O2 -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
+
+${OBJECTDIR}/_ext/760632520/scpi_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi.o ../scpi/scpi.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
+	then  \
+	    ${RM} $@.d;\
+	    $(COMPILE.c) -O2 -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
+
+${OBJECTDIR}/_ext/760632520/scpi_minimal_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_minimal.o ../scpi/scpi_minimal.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_minimal.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
+	then  \
+	    ${RM} $@.d;\
+	    $(COMPILE.c) -O2 -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
+
+${OBJECTDIR}/_ext/1472/test-parser_nomain.o: ${OBJECTDIR}/_ext/1472/test-parser.o ../test-parser.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/1472
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/1472/test-parser.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
+	then  \
+	    ${RM} $@.d;\
+	    $(COMPILE.c) -O2 -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
+
+${OBJECTDIR}/_ext/760632520/scpi_units_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_units.o ../scpi/scpi_units.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_units.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
+	then  \
+	    ${RM} $@.d;\
+	    $(COMPILE.c) -O2 -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
+
+${OBJECTDIR}/_ext/760632520/scpi_error_nomain.o: ${OBJECTDIR}/_ext/760632520/scpi_error.o ../scpi/scpi_error.c 
+	${MKDIR} -p ${OBJECTDIR}/_ext/760632520
+	@NMOUTPUT=`${NM} ${OBJECTDIR}/_ext/760632520/scpi_error.o`; \
+	if (echo "$$NMOUTPUT" | ${GREP} '|main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T main$$') || \
+	   (echo "$$NMOUTPUT" | ${GREP} 'T _main$$'); \
+	then  \
+	    ${RM} $@.d;\
+	    $(COMPILE.c) -O2 -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
+
+# Run Test Targets
+.test-conf:
+	@if [ "${TEST}" = "" ]; \
+	then  \
+	    ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/netbeans || true; \
+	else  \
+	    ./${TEST} || true; \
+	fi
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+	${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+	${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/scpi_parser
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/netbeans/nbproject/Makefile-impl.mk b/netbeans/nbproject/Makefile-impl.mk
new file mode 100644
index 0000000..ea0545f
--- /dev/null
+++ b/netbeans/nbproject/Makefile-impl.mk
@@ -0,0 +1,133 @@
+# 
+# Generated Makefile - do not edit! 
+# 
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a pre- and a post- target defined where you can add customization code.
+#
+# This makefile implements macros and targets common to all configurations.
+#
+# NOCDDL
+
+
+# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
+# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
+# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
+# and .clean-reqprojects-conf unless SUB has the value 'no'
+SUB_no=NO
+SUBPROJECTS=${SUB_${SUB}}
+BUILD_SUBPROJECTS_=.build-subprojects
+BUILD_SUBPROJECTS_NO=
+BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
+CLEAN_SUBPROJECTS_=.clean-subprojects
+CLEAN_SUBPROJECTS_NO=
+CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
+
+
+# Project Name
+PROJECTNAME=netbeans
+
+# Active Configuration
+DEFAULTCONF=Debug
+CONF=${DEFAULTCONF}
+
+# All Configurations
+ALLCONFS=Debug Release 
+
+
+# build
+.build-impl: .build-pre .validate-impl .depcheck-impl
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	"${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
+
+
+# clean
+.clean-impl: .clean-pre .validate-impl .depcheck-impl
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	"${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
+
+
+# clobber 
+.clobber-impl: .clobber-pre .depcheck-impl
+	@#echo "=> Running $@..."
+	for CONF in ${ALLCONFS}; \
+	do \
+	    "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
+	done
+
+# all 
+.all-impl: .all-pre .depcheck-impl
+	@#echo "=> Running $@..."
+	for CONF in ${ALLCONFS}; \
+	do \
+	    "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
+	done
+
+# build tests
+.build-tests-impl: .build-impl .build-tests-pre
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	"${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
+
+# run tests
+.test-impl: .build-tests-impl .test-pre
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	"${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
+
+# dependency checking support
+.depcheck-impl:
+	@echo "# This code depends on make tool being used" >.dep.inc
+	@if [ -n "${MAKE_VERSION}" ]; then \
+	    echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
+	    echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
+	    echo "include \$${DEPFILES}" >>.dep.inc; \
+	    echo "endif" >>.dep.inc; \
+	else \
+	    echo ".KEEP_STATE:" >>.dep.inc; \
+	    echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
+	fi
+
+# configuration validation
+.validate-impl:
+	@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+	then \
+	    echo ""; \
+	    echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
+	    echo "See 'make help' for details."; \
+	    echo "Current directory: " `pwd`; \
+	    echo ""; \
+	fi
+	@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+	then \
+	    exit 1; \
+	fi
+
+
+# help
+.help-impl: .help-pre
+	@echo "This makefile supports the following configurations:"
+	@echo "    ${ALLCONFS}"
+	@echo ""
+	@echo "and the following targets:"
+	@echo "    build  (default target)"
+	@echo "    clean"
+	@echo "    clobber"
+	@echo "    all"
+	@echo "    help"
+	@echo ""
+	@echo "Makefile Usage:"
+	@echo "    make [CONF=<CONFIGURATION>] [SUB=no] build"
+	@echo "    make [CONF=<CONFIGURATION>] [SUB=no] clean"
+	@echo "    make [SUB=no] clobber"
+	@echo "    make [SUB=no] all"
+	@echo "    make help"
+	@echo ""
+	@echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
+	@echo "    also build subprojects."
+	@echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
+	@echo "    also clean subprojects."
+	@echo "Target 'clobber' will remove all built files from all configurations and,"
+	@echo "    unless 'SUB=no', also from subprojects."
+	@echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
+	@echo "    also build subprojects."
+	@echo "Target 'help' prints this message."
+	@echo ""
+
diff --git a/netbeans/nbproject/Makefile-variables.mk b/netbeans/nbproject/Makefile-variables.mk
new file mode 100644
index 0000000..5e0a2ba
--- /dev/null
+++ b/netbeans/nbproject/Makefile-variables.mk
@@ -0,0 +1,35 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+CND_BASEDIR=`pwd`
+CND_BUILDDIR=build
+CND_DISTDIR=dist
+# 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_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
+# Release configuration
+CND_PLATFORM_Release=GNU-Linux-x86
+CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86
+CND_ARTIFACT_NAME_Release=scpi_parser
+CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/scpi_parser
+CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Release=scpi_parser.tar
+CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/scpi_parser.tar
+#
+# include compiler specific variables
+#
+# dmake command
+ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
+	(mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
+#
+# gmake command
+.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
+#
+include nbproject/private/Makefile-variables.mk
diff --git a/netbeans/nbproject/Package-Debug.bash b/netbeans/nbproject/Package-Debug.bash
new file mode 100644
index 0000000..c48b0b4
--- /dev/null
+++ b/netbeans/nbproject/Package-Debug.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${TESTDIR}/TestFiles/f2
+OUTPUT_BASENAME=f2
+PACKAGE_TOP_DIR=scpi_parser/
+
+# Functions
+function checkReturnCode
+{
+    rc=$?
+    if [ $rc != 0 ]
+    then
+        exit $rc
+    fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+    mkdir -p "$1"
+    checkReturnCode
+    if [ "$2" != "" ]
+    then
+      chmod $2 "$1"
+      checkReturnCode
+    fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+    cp "$1" "$2"
+    checkReturnCode
+    if [ "$3" != "" ]
+    then
+        chmod $3 "$2"
+        checkReturnCode
+    fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/scpi_parser/bin"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/scpi_parser.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/scpi_parser.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/netbeans/nbproject/Package-Release.bash b/netbeans/nbproject/Package-Release.bash
new file mode 100644
index 0000000..ee62e1f
--- /dev/null
+++ b/netbeans/nbproject/Package-Release.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/scpi_parser
+OUTPUT_BASENAME=scpi_parser
+PACKAGE_TOP_DIR=scpi_parser/
+
+# Functions
+function checkReturnCode
+{
+    rc=$?
+    if [ $rc != 0 ]
+    then
+        exit $rc
+    fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+    mkdir -p "$1"
+    checkReturnCode
+    if [ "$2" != "" ]
+    then
+      chmod $2 "$1"
+      checkReturnCode
+    fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+    cp "$1" "$2"
+    checkReturnCode
+    if [ "$3" != "" ]
+    then
+        chmod $3 "$2"
+        checkReturnCode
+    fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/scpi_parser/bin"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/scpi_parser.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/scpi_parser.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/netbeans/nbproject/configurations.xml b/netbeans/nbproject/configurations.xml
new file mode 100644
index 0000000..133b92f
--- /dev/null
+++ b/netbeans/nbproject/configurations.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+  <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+    <logicalFolder name="HeaderFiles"
+                   displayName="Header Files"
+                   projectFiles="true">
+      <logicalFolder name="f1" displayName="scpi" projectFiles="true">
+        <itemPath>../scpi/scpi.h</itemPath>
+        <itemPath>../scpi/scpi_constants.h</itemPath>
+        <itemPath>../scpi/scpi_error.h</itemPath>
+        <itemPath>../scpi/scpi_ieee488.h</itemPath>
+        <itemPath>../scpi/scpi_minimal.h</itemPath>
+        <itemPath>../scpi/scpi_utils.h</itemPath>
+      </logicalFolder>
+    </logicalFolder>
+    <logicalFolder name="ResourceFiles"
+                   displayName="Resource Files"
+                   projectFiles="true">
+    </logicalFolder>
+    <logicalFolder name="SourceFiles"
+                   displayName="Source Files"
+                   projectFiles="true">
+      <logicalFolder name="f1" displayName="scpi" projectFiles="true">
+        <itemPath>../scpi/scpi.c</itemPath>
+        <itemPath>../scpi/scpi_error.c</itemPath>
+        <itemPath>../scpi/scpi_ieee488.c</itemPath>
+        <itemPath>../scpi/scpi_minimal.c</itemPath>
+        <itemPath>../scpi/scpi_units.c</itemPath>
+        <itemPath>../scpi/scpi_utils.c</itemPath>
+      </logicalFolder>
+      <itemPath>../test-parser.c</itemPath>
+    </logicalFolder>
+    <logicalFolder name="TestFiles"
+                   displayName="Test Files"
+                   projectFiles="false"
+                   kind="TEST_LOGICAL_FOLDER">
+      <logicalFolder name="f3"
+                     displayName="Test SCPI utils"
+                     projectFiles="true"
+                     kind="TEST">
+        <itemPath>tests/test_scpi_utils.c</itemPath>
+      </logicalFolder>
+    </logicalFolder>
+    <logicalFolder name="ExternalFiles"
+                   displayName="Important Files"
+                   projectFiles="false"
+                   kind="IMPORTANT_FILES_FOLDER">
+      <itemPath>Makefile</itemPath>
+    </logicalFolder>
+  </logicalFolder>
+  <projectmakefile>Makefile</projectmakefile>
+  <confs>
+    <conf name="Debug" type="1">
+      <toolsSet>
+        <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+        <compilerSet>default</compilerSet>
+        <rebuildPropChanged>true</rebuildPropChanged>
+      </toolsSet>
+      <compileType>
+        <cTool>
+          <developmentMode>0</developmentMode>
+          <incDir>
+            <pElem>.</pElem>
+          </incDir>
+          <commandLine>-Wextra -g3 -O0</commandLine>
+          <warningLevel>2</warningLevel>
+        </cTool>
+        <ccTool>
+          <incDir>
+            <pElem>.</pElem>
+          </incDir>
+        </ccTool>
+        <linkerTool>
+          <output>${TESTDIR}/TestFiles/f2</output>
+          <linkerLibItems>
+            <linkerLibStdlibItem>CUnit</linkerLibStdlibItem>
+            <linkerLibStdlibItem>CUnit</linkerLibStdlibItem>
+          </linkerLibItems>
+          <commandLine>-g3</commandLine>
+        </linkerTool>
+      </compileType>
+      <packaging>
+        <packType>Tar</packType>
+        <output>${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/scpi_parser.tar</output>
+        <packFileList>
+          <packFileListElem type="File"
+                            to="${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}"
+                            from="${OUTPUT_PATH}"
+                            perm="755"
+                            owner="root"
+                            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>
+            <pElem>.</pElem>
+          </incDir>
+        </cTool>
+        <ccTool>
+          <incDir>
+            <pElem>.</pElem>
+          </incDir>
+        </ccTool>
+        <linkerTool>
+          <output>${TESTDIR}/TestFiles/f3</output>
+        </linkerTool>
+      </folder>
+    </conf>
+    <conf name="Release" type="1">
+      <toolsSet>
+        <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+        <compilerSet>default</compilerSet>
+        <rebuildPropChanged>true</rebuildPropChanged>
+      </toolsSet>
+      <compileType>
+        <cTool>
+          <developmentMode>5</developmentMode>
+        </cTool>
+        <ccTool>
+          <developmentMode>5</developmentMode>
+        </ccTool>
+        <fortranCompilerTool>
+          <developmentMode>5</developmentMode>
+        </fortranCompilerTool>
+        <asmTool>
+          <developmentMode>5</developmentMode>
+        </asmTool>
+        <linkerTool>
+          <output>${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/scpi_parser</output>
+        </linkerTool>
+      </compileType>
+      <packaging>
+        <packType>Tar</packType>
+        <output>${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/scpi_parser.tar</output>
+        <packFileList>
+          <packFileListElem type="File"
+                            to="${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}"
+                            from="${OUTPUT_PATH}"
+                            perm="755"
+                            owner="root"
+                            group="bin"/>
+        </packFileList>
+      </packaging>
+    </conf>
+  </confs>
+</configurationDescriptor>
diff --git a/netbeans/nbproject/project.xml b/netbeans/nbproject/project.xml
new file mode 100644
index 0000000..0b343d0
--- /dev/null
+++ b/netbeans/nbproject/project.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.cnd.makeproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/make-project/1">
+            <name>scpi_parser</name>
+            <c-extensions>c</c-extensions>
+            <cpp-extensions/>
+            <header-extensions>h</header-extensions>
+            <sourceEncoding>UTF-8</sourceEncoding>
+            <make-dep-projects/>
+            <sourceRootList/>
+            <confList>
+                <confElem>
+                    <name>Debug</name>
+                    <type>1</type>
+                </confElem>
+                <confElem>
+                    <name>Release</name>
+                    <type>1</type>
+                </confElem>
+            </confList>
+        </data>
+    </configuration>
+</project>
diff --git a/netbeans/tests/test_scpi_utils.c b/netbeans/tests/test_scpi_utils.c
new file mode 100644
index 0000000..2ced343
--- /dev/null
+++ b/netbeans/tests/test_scpi_utils.c
@@ -0,0 +1,220 @@
+/*
+ * File:   test_scpi_utils.c
+ * Author: Jan Breuer
+ *
+ * Created on 26.11.2012, 11:22:00
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "CUnit/Basic.h"
+
+#include "../scpi/scpi.h"
+#include "../scpi/scpi_utils.h"
+
+/*
+ * CUnit Test Suite
+ */
+
+int init_suite(void) {
+    return 0;
+}
+
+int clean_suite(void) {
+    return 0;
+}
+
+void test_strnpbrk() {
+    char str[] = "ahoj";
+
+    CU_ASSERT(strnpbrk(str, 4, "a") == (str + 0));
+    CU_ASSERT(strnpbrk(str, 4, "h") == (str + 1));
+    CU_ASSERT(strnpbrk(str, 4, "b") == NULL);
+    CU_ASSERT(strnpbrk(str, 1, "h") == NULL);
+    CU_ASSERT(strnpbrk(str, 4, "xo") == (str + 2));
+}
+
+void test_longToStr() {
+    char str[32];
+    size_t len;
+
+    len = longToStr(10, str, 32);
+    CU_ASSERT(len == 2);
+    CU_ASSERT(str[0] == '1');
+    CU_ASSERT(str[1] == '0');
+    CU_ASSERT(str[2] == '\0');
+}
+
+void test_doubleToStr() {
+    size_t result;
+    char str[50];
+    
+#define TEST_DOUBLE_TO_STR(v, r, s)                     \
+    do {                                                \
+        result = doubleToStr(v, str, sizeof(str));      \
+        CU_ASSERT_EQUAL(result, r);                     \
+        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");
+    TEST_DOUBLE_TO_STR(-1.1, 4, "-1.1");
+    TEST_DOUBLE_TO_STR(1e3, 4, "1000");
+    TEST_DOUBLE_TO_STR(1e30, 5, "1e+30");
+    TEST_DOUBLE_TO_STR(-1.3e30, 8, "-1.3e+30");
+    TEST_DOUBLE_TO_STR(-1.3e-30, 8, "-1.3e-30");
+}
+
+void test_strToLong() {
+    size_t result;
+    int32_t val;
+
+#define TEST_STR_TO_LONG(s, r, v)                       \
+    do {                                                \
+        result = strToLong(s, &val);                    \
+        CU_ASSERT_EQUAL(val, v);                        \
+        CU_ASSERT_EQUAL(result, r);                     \
+    } while(0)                                          \
+    
+    TEST_STR_TO_LONG("", 0, 0);
+    TEST_STR_TO_LONG("1", 1, 1);
+    TEST_STR_TO_LONG("10", 2, 10);
+    TEST_STR_TO_LONG("-50", 3, -50);
+    TEST_STR_TO_LONG("100MHz", 3, 100);
+    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
+}
+
+void test_strToDouble() {
+    double val;
+    size_t result;
+
+#define TEST_STR_TO_DOUBLE(s, r, v)                     \
+    do {                                                \
+        result = strToDouble(s, &val);                  \
+        CU_ASSERT_EQUAL(result, r);                     \
+        CU_ASSERT_DOUBLE_EQUAL(v, val, 0.000001);       \
+    } while(0);                                         \
+    
+    TEST_STR_TO_DOUBLE("", 0, 0.0);
+
+    TEST_STR_TO_DOUBLE(" 1", 2, 1.0);
+
+    TEST_STR_TO_DOUBLE("1", 1, 1.0);
+    TEST_STR_TO_DOUBLE("10", 2, 10.0);
+    TEST_STR_TO_DOUBLE("10MHz", 2, 10.0);
+    TEST_STR_TO_DOUBLE("MHz", 0, 0.0);
+    TEST_STR_TO_DOUBLE("1E", 1, 1.0);
+    TEST_STR_TO_DOUBLE("1E3", 3, 1000.0);
+
+    TEST_STR_TO_DOUBLE("1.2", 3, 1.2);
+    TEST_STR_TO_DOUBLE("10.2", 4, 10.2);
+    TEST_STR_TO_DOUBLE("10.2MHz", 4, 10.2);
+    TEST_STR_TO_DOUBLE("MHz", 0, 0.0);
+    TEST_STR_TO_DOUBLE("1.2E", 3, 1.2);
+    TEST_STR_TO_DOUBLE("1.2E3", 5, 1200.0);
+
+    TEST_STR_TO_DOUBLE("-1.2", 4, -1.2);
+
+}
+
+void test_compareStr() {
+
+    CU_ASSERT_TRUE(compareStr("abcd", 1, "afgh", 1));
+    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_locateStr() {
+
+    char * v;
+    char * b;
+    size_t l;
+    int result;
+
+
+#define TEST_LOCATE_STR(s, ex_res, ex_off, ex_len)      \
+    do {                                                \
+        v = (s);                                        \
+        b = NULL;                                       \
+        l = 0;                                          \
+        result = locateStr(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_STR("", TRUE, 0, 0);
+    TEST_LOCATE_STR("   ", TRUE, 3, 0);
+    TEST_LOCATE_STR("a", TRUE, 0, 1);
+    TEST_LOCATE_STR("ab", TRUE, 0, 2);
+    TEST_LOCATE_STR("abc", TRUE, 0, 3);
+    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(" 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);
+}
+
+int main() {
+    CU_pSuite pSuite = NULL;
+
+    /* Initialize the CUnit test registry */
+    if (CUE_SUCCESS != CU_initialize_registry())
+        return CU_get_error();
+
+    /* Add a suite to the registry */
+    pSuite = CU_add_suite("SCPI Utils", init_suite, clean_suite);
+    if (NULL == pSuite) {
+        CU_cleanup_registry();
+        return CU_get_error();
+    }
+
+    /* Add the tests to the suite */
+    if (0
+            || (NULL == CU_add_test(pSuite, "strnpbrk", test_strnpbrk))
+            || (NULL == CU_add_test(pSuite, "longToStr", test_longToStr))
+            || (NULL == CU_add_test(pSuite, "doubleToStr", test_doubleToStr))
+            || (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, "locateStr", test_locateStr))
+            ) {
+        CU_cleanup_registry();
+        return CU_get_error();
+    }
+
+    /* Run all tests using the CUnit Basic interface */
+    CU_basic_set_mode(CU_BRM_VERBOSE);
+    CU_basic_run_tests();
+    CU_cleanup_registry();
+    return CU_get_error();
+}
diff --git a/scpi/scpi.c b/scpi/scpi.c
index 8038405..7c377a2 100644
--- a/scpi/scpi.c
+++ b/scpi/scpi.c
@@ -51,7 +51,6 @@
 static char * cmdlineTerminator(const char * cmd, size_t len);
 static const char * cmdlineNext(const char * cmd, size_t len);
 static bool_t cmdMatch(const char * pattern, const char * cmd, size_t len);
-static size_t skipWhitespace(const char * cmd, size_t len);
 
 static void paramSkipBytes(scpi_context_t * context, size_t num);
 static void paramSkipWhitespace(scpi_context_t * context);
@@ -264,21 +263,6 @@
     return result;
 }
 
-/**
- * Count white spaces from the beggining
- * @param cmd - command
- * @param len - max search length
- * @return number of white spaces
- */
-size_t skipWhitespace(const char * cmd, size_t len) {
-    size_t i;
-    for (i = 0; i < len; i++) {
-        if (!isspace(cmd[i])) {
-            return i;
-        }
-    }
-    return len;
-}
 
 /**
  * Write data to SCPI output
@@ -571,11 +555,16 @@
 bool_t SCPI_ParamInt(scpi_context_t * context, int32_t * value, bool_t mandatory) {
     size_t len;
 
+    if (!value) {
+        return FALSE;
+    }
+
     if (!paramNext(context, mandatory)) {
         return FALSE;
     }
+       
     len = strToLong(context->paramlist.parameters, value);
-
+   
     if (len == 0) {
         if (mandatory) {
             SCPI_ErrorPush(context, SCPI_ERROR_SYNTAX);
@@ -585,6 +574,12 @@
         paramSkipBytes(context, len);
     }
 
+    paramSkipWhitespace(context);
+    if ((context->paramlist.length > 0) && (context->paramlist.parameters[0] != ',')) {
+        SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
+        return FALSE;
+    }
+    
     return TRUE;
 }
 
@@ -598,9 +593,14 @@
 bool_t SCPI_ParamDouble(scpi_context_t * context, double * value, bool_t mandatory) {
     size_t len;
 
+    if (!value) {
+        return FALSE;
+    }
+
     if (!paramNext(context, mandatory)) {
         return FALSE;
     }
+   
     len = strToDouble(context->paramlist.parameters, value);
 
     if (len == 0) {
@@ -612,6 +612,12 @@
         paramSkipBytes(context, len);
     }
 
+    paramSkipWhitespace(context);
+    if ((context->paramlist.length > 0) && (context->paramlist.parameters[0] != ',')) {
+        SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
+        return FALSE;
+    }
+    
     return TRUE;
 }
 
@@ -624,10 +630,23 @@
  * @return 
  */
 bool_t SCPI_ParamString(scpi_context_t * context, char ** value, size_t * len, bool_t mandatory) {
-    (void)context;
-    (void)value;
-    (void)len;
-    (void)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);
+        if (len) {
+            *len = length;
+        }
+        return TRUE;
+    }
+
     return FALSE;
 }
\ No newline at end of file
diff --git a/scpi/scpi_error.c b/scpi/scpi_error.c
index f72fdf6..5b67c5e 100644
--- a/scpi/scpi_error.c
+++ b/scpi/scpi_error.c
@@ -103,6 +103,8 @@
         case SCPI_ERROR_UNDEFINED_HEADER: return "Undefined header";
         case SCPI_ERROR_PARAMETER_NOT_ALLOWED: return "Parameter not allowed";
         case SCPI_ERROR_MISSING_PARAMETER: return "Missing parameter";
+        case SCPI_ERROR_INVALID_SUFFIX: return "Invalid suffix";
+        case SCPI_ERROR_SUFFIX_NOT_ALLOWED: return "Suffix not allowed";
         default: return "Unknown error";
     }
 }
\ No newline at end of file
diff --git a/scpi/scpi_error.h b/scpi/scpi_error.h
index 7014424..b5da831 100644
--- a/scpi/scpi_error.h
+++ b/scpi/scpi_error.h
@@ -51,6 +51,8 @@
 #define SCPI_ERROR_UNDEFINED_HEADER     -113
 #define SCPI_ERROR_PARAMETER_NOT_ALLOWED        -108
 #define SCPI_ERROR_MISSING_PARAMETER    -109
+#define SCPI_ERROR_INVALID_SUFFIX       -131
+#define SCPI_ERROR_SUFFIX_NOT_ALLOWED   -138
 
 #ifdef	__cplusplus
 }
diff --git a/scpi/scpi_ieee488.c b/scpi/scpi_ieee488.c
index 005ea90..7474643 100644
--- a/scpi/scpi_ieee488.c
+++ b/scpi/scpi_ieee488.c
@@ -157,7 +157,8 @@
 }
 
 /**
- * *CLS
+ * *CLS - This command clears all status data structures in a device. 
+ *        For a device which minimally complies with SCPI. (SCPI std 4.1.3.2)
  * @param context
  * @return 
  */
diff --git a/scpi/scpi_units.c b/scpi/scpi_units.c
new file mode 100644
index 0000000..205639b
--- /dev/null
+++ b/scpi/scpi_units.c
@@ -0,0 +1,205 @@
+/*-
+ * Copyright (c) 2012-2013 Jan Breuer,
+ *
+ * All Rights Reserved
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file   scpi_units.c
+ * @date   Thu Nov 15 10:58:45 UTC 2012
+ * 
+ * @brief  SCPI units
+ * 
+ * 
+ */
+
+#include <string.h>
+#include "scpi.h"
+#include "scpi_units.h"
+#include "scpi_utils.h"
+#include "scpi_error.h"
+
+
+/*
+ * multipliers IEEE 488.2-1992 tab 7-2
+ * 1E18         EX
+ * 1E15         PE
+ * 1E12         T
+ * 1E9          G
+ * 1E6          MA (use M for OHM and HZ)
+ * 1E3          K
+ * 1E-3         M (disaalowed for OHM and HZ)
+ * 1E-6         U
+ * 1E-9         N
+ * 1E-12        P
+ * 1E-15        F
+ * 1E-18        A
+ */
+
+/*
+ * units definition IEEE 488.2-1992 tab 7-1
+ */
+const scpi_unit_def_t scpi_units_def[] = {
+    /* voltage */
+    { .name = "UV", .unit = SCPI_UNIT_VOLT, .mult = 1e-6},
+    { .name = "MV", .unit = SCPI_UNIT_VOLT, .mult = 1e-3},
+    { .name = "V", .unit = SCPI_UNIT_VOLT, .mult = 1},
+    { .name = "KV", .unit = SCPI_UNIT_VOLT, .mult = 1e3},
+
+    /* current */
+    { .name = "UA", .unit = SCPI_UNIT_AMPER, .mult = 1e-6},
+    { .name = "MA", .unit = SCPI_UNIT_AMPER, .mult = 1e-3},
+    { .name = "A", .unit = SCPI_UNIT_AMPER, .mult = 1},
+    { .name = "KA", .unit = SCPI_UNIT_AMPER, .mult = 1e3},
+
+    /* resistance */
+    { .name = "OHM", .unit = SCPI_UNIT_OHM, .mult = 1},
+    { .name = "KOHM", .unit = SCPI_UNIT_OHM, .mult = 1e3},
+    { .name = "MOHM", .unit = SCPI_UNIT_OHM, .mult = 1e6},
+
+    /* frequency */
+    { .name = "HZ", .unit = SCPI_UNIT_HERTZ, .mult = 1},
+    { .name = "KHZ", .unit = SCPI_UNIT_HERTZ, .mult = 1e3},
+    { .name = "MHZ", .unit = SCPI_UNIT_HERTZ, .mult = 1e6},
+    { .name = "GHZ", .unit = SCPI_UNIT_HERTZ, .mult = 1e9},
+
+    /* temperature */
+    { .name = "CEL", .unit = SCPI_UNIT_CELSIUS, .mult = 1},
+
+    /* time */
+    { .name = "PS", .unit = SCPI_UNIT_SECONDS, .mult = 1e-12},
+    { .name = "NS", .unit = SCPI_UNIT_SECONDS, .mult = 1e-9},
+    { .name = "US", .unit = SCPI_UNIT_SECONDS, .mult = 1e-6},
+    { .name = "MS", .unit = SCPI_UNIT_SECONDS, .mult = 1e-3},
+    { .name = "S", .unit = SCPI_UNIT_SECONDS, .mult = 1},
+    { .name = "MIN", .unit = SCPI_UNIT_SECONDS, .mult = 60},
+    { .name = "HR", .unit = SCPI_UNIT_SECONDS, .mult = 3600},
+
+    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 = "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) {
+    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;
+        }
+    }
+
+    return SCPI_NUM_NUMBER;
+}
+
+static const scpi_unit_def_t * searchUnit(const char * unit, size_t len) {
+    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];
+        }
+    }
+    
+    return NULL;
+}
+
+static bool_t transformNumber(const char * unit, size_t len, scpi_number_t * value) {
+    size_t s;
+    const scpi_unit_def_t * unitDef;
+    s = skipWhitespace(unit, len);
+
+    if (s == len) {
+        value->unit = SCPI_UNIT_NONE;
+        return TRUE;
+    }
+    
+    unitDef = searchUnit(unit + s, len - s);
+    
+    if (unitDef == NULL) {
+        return FALSE;
+    }
+    
+    value->value *= unitDef->mult;
+    value->unit = unitDef->unit;
+    
+    return TRUE;
+}
+
+/**
+ * Parse parameter as number, number with unit or special value (min, max, default, ...)
+ * @param context
+ * @param value return value
+ * @param mandatory if the parameter is mandatory
+ * @return 
+ */
+bool_t SCPI_ParamNumber(scpi_context_t * context, scpi_number_t * value, bool_t mandatory) {
+    bool_t result;
+    char * param;
+    size_t len;
+    size_t numlen;
+
+    result = SCPI_ParamString(context, &param, &len, mandatory);
+
+    if (!result) {
+        return FALSE;
+    }
+
+    if (!value) {
+        return FALSE;
+    }
+
+    value->unit = SCPI_UNIT_NONE;
+    value->value = 0.0;
+    value->type = translateSpecialNumber(param, len);
+
+    if (value->type != SCPI_NUM_NUMBER) {
+        // found special type
+        return TRUE;
+    }
+
+    numlen = strToDouble(param, &value->value);
+
+    if (numlen <= len) {
+        if (transformNumber(param + numlen, len - numlen, value)) {
+            return TRUE;
+        } else {
+            SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SUFFIX);            
+        }
+    }
+    return FALSE;
+
+}
+
diff --git a/scpi/scpi_units.h b/scpi/scpi_units.h
new file mode 100644
index 0000000..7144728
--- /dev/null
+++ b/scpi/scpi_units.h
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2012-2013 Jan Breuer,
+ *
+ * All Rights Reserved
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file   scpi_units.h
+ * @date   Thu Nov 15 10:58:45 UTC 2012
+ * 
+ * @brief  SCPI Units
+ * 
+ * 
+ */
+
+#ifndef SCPI_UNITS_H
+#define	SCPI_UNITS_H
+
+#include "scpi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+    enum _scpi_unit_t {
+        SCPI_UNIT_NONE,
+        SCPI_UNIT_VOLT,
+        SCPI_UNIT_AMPER,
+        SCPI_UNIT_OHM,
+        SCPI_UNIT_HERTZ,
+        SCPI_UNIT_CELSIUS,
+        SCPI_UNIT_SECONDS,
+    };
+    typedef enum _scpi_unit_t scpi_unit_t;
+
+    struct _scpi_unit_def_t {
+        const char * name;
+        scpi_unit_t unit;
+        double mult;
+    };
+    typedef struct _scpi_unit_def_t scpi_unit_def_t;
+
+#define SCPI_UNITS_LIST_END       {.name = NULL, .unit = SCPI_UNIT_NONE, .mult = 0}
+
+    enum _scpi_special_number_t {
+        SCPI_NUM_NUMBER,
+        SCPI_NUM_MIN,
+        SCPI_NUM_MAX,
+        SCPI_NUM_DEF,
+        SCPI_NUM_UP,
+        SCPI_NUM_DOWN,
+        SCPI_NUM_NAN,
+        SCPI_NUM_INF,
+        SCPI_NUM_NINF,
+    };
+    typedef enum _scpi_special_number_t scpi_special_number_t;
+
+    struct _scpi_special_number_def_t {
+        const char * name;
+        scpi_special_number_t type;
+    };
+    typedef struct _scpi_special_number_def_t scpi_special_number_def_t;
+
+    struct _scpi_number_t {
+        double value;
+        scpi_unit_t unit;
+        scpi_special_number_t type;
+    };
+    typedef struct _scpi_number_t scpi_number_t;
+
+
+#define SCPI_SPECIAL_NUMBERS_LIST_END   {.name = NULL, .type = SCPI_NUM_NUMBER}
+
+
+    bool_t SCPI_ParamNumber(scpi_context_t * context, scpi_number_t * value, bool_t mandatory);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* SCPI_UNITS_H */
+
diff --git a/scpi/scpi_utils.c b/scpi/scpi_utils.c
index fb3dd83..0815a8c 100644
--- a/scpi/scpi_utils.c
+++ b/scpi/scpi_utils.c
@@ -39,6 +39,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 /**
  * Find the first occurrence in str of a character in set.
@@ -48,18 +49,17 @@
  * @return 
  */
 char * strnpbrk(const char *str, size_t size, const char *set) {
-        const char *scanp;
-        long c, sc;
-        const char * strend = str + size;
-        
-        while ((strend != str) && ((c = *str++) != 0)) {
-            for (scanp = set; (sc = *scanp++) != '\0';)
-                if (sc == c)                  
-                    return ((char *) (str - 1));
-        }
-        return (NULL);
-}
+    const char *scanp;
+    long c, sc;
+    const char * strend = str + size;
 
+    while ((strend != str) && ((c = *str++) != 0)) {
+        for (scanp = set; (sc = *scanp++) != '\0';)
+            if (sc == c)
+                return ((char *) (str - 1));
+    }
+    return (NULL);
+}
 
 /**
  * Converts signed 32b integer value to string
@@ -105,7 +105,7 @@
  * @return number of bytes written to str (without '\0')
  */
 size_t doubleToStr(double val, char * str, size_t len) {
-    return snprintf(str, len, "%lf", val);
+    return snprintf(str, len, "%lg", val);
 }
 
 /**
@@ -129,7 +129,7 @@
 size_t strToDouble(const char * str, double * val) {
     char * endptr;
     *val = strtod(str, &endptr);
-    return endptr - str;    
+    return endptr - str;
 }
 
 /**
@@ -150,4 +150,98 @@
     }
 
     return FALSE;
+}
+
+bool_t locateStr(const char * str1, size_t len1, char ** str2, size_t * len2) {
+    size_t i;
+    int quot = 0;
+    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) && !quot && (str1[i] == '"')) {
+            quot = 1;
+            continue;
+        }
+
+        if (strStart < 0) {
+            strStart = i;
+        }
+
+        if ((strStop < 0) && quot && (str1[i] == '"')) {
+            strStop = i;
+            valid = 1;
+            continue;
+        }
+
+        if ((strStop >= 0) && quot && (str1[i] == ',')) {
+            break;
+        }
+
+        if ((strStop >= 0) && quot && !isspace(str1[i])) {
+            valid = 0;
+        }
+
+        if (!quot && !isspace(str1[i]) && (str1[i] != ',')) {
+            strStop = i;
+        }
+
+        if (isspace(str1[i])) {
+            continue;
+        }
+
+        if ((strStop >= 0) && (str1[i] == ',')) {
+            valid = 1;
+            break;
+        }
+    }
+
+    if ((i == len1) && !quot) {
+        valid = 1;
+        if (strStop < 0) {
+            strStop = i;
+        } else {
+            strStop++;
+        }
+        if (strStart < 0) {
+            strStart = i;
+        }
+    } else if (!quot) {
+        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
+ * @param len - max search length
+ * @return number of white spaces
+ */
+size_t skipWhitespace(const char * cmd, size_t len) {
+    size_t i;
+    for (i = 0; i < len; i++) {
+        if (!isspace(cmd[i])) {
+            return i;
+        }
+    }
+    return len;
 }
\ No newline at end of file
diff --git a/scpi/scpi_utils.h b/scpi/scpi_utils.h
index c1cf6f7..348eeaf 100644
--- a/scpi/scpi_utils.h
+++ b/scpi/scpi_utils.h
@@ -49,8 +49,9 @@
     size_t longToStr(int32_t val, char * str, size_t len);
     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);    
-    
+    size_t strToDouble(const char * str, double * val);
+    bool_t locateStr(const char * str1, size_t len1, char ** str2, size_t * len2);
+    size_t skipWhitespace(const char * cmd, size_t len);
 
 #ifdef	__cplusplus
 }
diff --git a/test-parser.c b/test-parser.c
index e52ad26..640e5c2 100644
--- a/test-parser.c
+++ b/test-parser.c
@@ -63,7 +63,7 @@
 }
 
 scpi_command_t scpi_commands[] = {
-    /* Required IEEE488.2 Common Commands (see SCPI Standard V1999.0 ch4.1.1) */
+    /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */
     { .pattern = "*CLS", .callback = SCPI_CoreCls,},
     { .pattern = "*ESE", .callback = SCPI_CoreEse,},
     { .pattern = "*ESE?", .callback = SCPI_CoreEseQ,},
@@ -78,7 +78,7 @@
     { .pattern = "*TST?", .callback = SCPI_CoreTstQ,},
     { .pattern = "*WAI", .callback = SCPI_CoreWai,},
 
-    /* Required SCPI commands (see SCPI Standard V1999.0 ch 4.2.1) */
+    /* Required SCPI commands (SCPI std V1999.0 4.2.1) */
     {.pattern = "SYSTem:ERRor?", .callback = SCPI_SystemErrorNextQ,},
     {.pattern = "SYSTem:ERRor:NEXT?", .callback = SCPI_SystemErrorNextQ,},
     {.pattern = "SYSTem:VERSion?", .callback = SCPI_SystemVersionQ,},
@@ -144,11 +144,12 @@
 /*
  * 
  */
+#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);

--
Gitblit v1.9.1