summaryrefslogtreecommitdiff
path: root/third_party/libscpi/inc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libscpi/inc')
-rw-r--r--third_party/libscpi/inc/scpi/cc.h211
-rw-r--r--third_party/libscpi/inc/scpi/config.h291
-rw-r--r--third_party/libscpi/inc/scpi/constants.h62
-rw-r--r--third_party/libscpi/inc/scpi/error.h208
-rw-r--r--third_party/libscpi/inc/scpi/expression.h62
-rw-r--r--third_party/libscpi/inc/scpi/ieee488.h94
-rw-r--r--third_party/libscpi/inc/scpi/minimal.h69
-rw-r--r--third_party/libscpi/inc/scpi/parser.h151
-rw-r--r--third_party/libscpi/inc/scpi/scpi.h51
-rw-r--r--third_party/libscpi/inc/scpi/types.h459
-rw-r--r--third_party/libscpi/inc/scpi/units.h60
-rw-r--r--third_party/libscpi/inc/scpi/utils.h62
12 files changed, 1780 insertions, 0 deletions
diff --git a/third_party/libscpi/inc/scpi/cc.h b/third_party/libscpi/inc/scpi/cc.h
new file mode 100644
index 00000000..3487ed1a
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/cc.h
@@ -0,0 +1,211 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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 cc.h
+ *
+ * @brief compiler detection
+ *
+ *
+ */
+
+#ifndef __SCPI_CC_H_
+#define __SCPI_CC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__STDC__)
+# define C89 1
+# if defined(__STDC_VERSION__)
+# define C90 1
+# if (__STDC_VERSION__ >= 199409L)
+# define C94 1
+# endif
+# if (__STDC_VERSION__ >= 199901L)
+# define C99 1
+# endif
+# endif
+#endif
+
+#if defined(__cplusplus)
+# if (__cplusplus >= 199711)
+# define CXX98 1
+# endif
+#endif
+
+#if (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200809L) || \
+ (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 700)
+ #define HAVE_STRNDUP 1
+ #define HAVE_STRNLEN 1
+#endif
+
+#if (defined _BSD_SOURCE && _BSD_SOURCE) || \
+ (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 500) || \
+ (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \
+ (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \
+ C99
+ #define HAVE_SNPRINTF 1
+#endif
+
+#if (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L)
+ #define HAVE_STRNCASECMP 1
+#endif
+
+#if (defined _BSD_SOURCE && _BSD_SOURCE) || \
+ (defined _SVID_SOURCE && _SVID_SOURCE) || \
+ (defined _XOPEN_SOURCE && _XOPEN_SOURCE) || \
+ (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \
+ (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) ||\
+ C99
+ #define HAVE_ISNAN 1
+#endif
+
+#if (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 600)|| \
+ (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \
+ (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \
+ C99
+ #define HAVE_ISFINITE 1
+ #define HAVE_SIGNBIT 1
+#endif
+
+#if (defined _XOPEN_SOURCE && XOPEN_SOURCE >= 600) || \
+ (defined _BSD_SOURCE && _BSD_SOURCE) || \
+ (defined _SVID_SOURCE && _SVID_SOURCE) || \
+ (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \
+ (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L)
+ #define HAVE_STRTOLL 1
+#endif
+
+#if (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 600) || \
+ (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \
+ (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \
+ C99
+ #define HAVE_STRTOF 1
+#endif
+
+#if (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || C99 || CXX98
+ #define HAVE_STDBOOL 1
+#endif
+
+/* Compiler specific */
+/* RealView/Keil ARM Compiler, e.g. Cortex-M CPUs */
+#if defined(__CC_ARM)
+#define HAVE_STRNCASECMP 1
+#endif
+
+/* National Instruments (R) CVI x86/x64 PC platform */
+#if defined(_CVI_)
+#define HAVE_STRNICMP 1
+#endif
+
+/* 8bit PIC - PIC16, etc */
+#if defined(_MPC_)
+#define HAVE_STRNICMP 1
+#endif
+
+/* PIC24 */
+#if defined(__C30__)
+#endif
+
+/* PIC32mx */
+#if defined(__C32__)
+#define HAVE_FINITE 1
+#endif
+
+/* AVR libc */
+#if defined(__AVR__)
+#include <stdlib.h>
+#define HAVE_DTOSTRE 1
+#undef HAVE_STRTOF
+#define HAVE_STRTOF 0
+#endif
+
+/* default values */
+#ifndef HAVE_STRNLEN
+#define HAVE_STRNLEN 0
+#endif
+
+#ifndef HAVE_STRDUP
+#define HAVE_STRDUP 0
+#endif
+
+#ifndef HAVE_STRNDUP
+#define HAVE_STRNDUP 0
+#endif
+
+#ifndef HAVE_STRNICMP
+#define HAVE_STRNICMP 0
+#endif
+
+#ifndef HAVE_STDBOOL
+#define HAVE_STDBOOL 0
+#endif
+
+#ifndef HAVE_SNPRINTF
+#define HAVE_SNPRINTF 0
+#endif
+
+#ifndef HAVE_STRNCASECMP
+#define HAVE_STRNCASECMP 0
+#endif
+
+#ifndef HAVE_ISNAN
+#define HAVE_ISNAN 0
+#endif
+
+#ifndef HAVE_ISFINITE
+#define HAVE_ISFINITE 0
+#endif
+
+#ifndef HAVE_FINITE
+#define HAVE_FINITE 0
+#endif
+
+#ifndef HAVE_SIGNBIT
+#define HAVE_SIGNBIT 0
+#endif
+
+#ifndef HAVE_STRTOLL
+#define HAVE_STRTOLL 0
+#endif
+
+#ifndef HAVE_STRTOF
+#define HAVE_STRTOF 0
+#endif
+
+#ifndef HAVE_DTOSTRE
+#define HAVE_DTOSTRE 0
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCPI_CC_H_ */
diff --git a/third_party/libscpi/inc/scpi/config.h b/third_party/libscpi/inc/scpi/config.h
new file mode 100644
index 00000000..2d3652e6
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/config.h
@@ -0,0 +1,291 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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 config.h
+ * @date Wed Mar 20 12:21:26 UTC 2013
+ *
+ * @brief SCPI Configuration
+ *
+ *
+ */
+
+#ifndef __SCPI_CONFIG_H_
+#define __SCPI_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cc.h"
+
+#ifdef SCPI_USER_CONFIG
+#include "scpi_user_config.h"
+#endif
+
+/* set the termination character(s) */
+#define LINE_ENDING_CR "\r" /* use a <CR> carriage return as termination charcter */
+#define LINE_ENDING_LF "\n" /* use a <LF> line feed as termination charcter */
+#define LINE_ENDING_CRLF "\r\n" /* use <CR><LF> carriage return + line feed as termination charcters */
+
+#ifndef SCPI_LINE_ENDING
+#define SCPI_LINE_ENDING LINE_ENDING_CRLF
+#endif
+
+#ifndef USE_CUSTOM_REGISTERS
+#define USE_CUSTOM_REGISTERS 0
+#endif
+
+/**
+ * Detect, if it has limited resources or it is running on a full blown operating system.
+ * All values can be overiden by scpi_user_config.h
+ */
+#define SYSTEM_BARE_METAL 0
+#define SYSTEM_FULL_BLOWN 1
+
+/* This should cover all windows compilers (msvc, mingw, cvi) and all Linux/OSX/BSD and other UNIX compatible systems (gcc, clang) */
+#if defined(_WIN32) || defined(_WIN64) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
+#define SYSTEM_TYPE SYSTEM_FULL_BLOWN
+#else
+#define SYSTEM_TYPE SYSTEM_BARE_METAL
+#endif
+
+/**
+ * Enable full error list
+ * 0 = Minimal set of errors
+ * 1 = Full set of errors
+ *
+ * For small systems, full set of errors will occupy large ammount of data
+ * It is enabled by default on full blown systems and disabled on limited bare metal systems
+ */
+#ifndef USE_FULL_ERROR_LIST
+#define USE_FULL_ERROR_LIST SYSTEM_TYPE
+#endif
+
+/**
+ * Enable also LIST_OF_USER_ERRORS to be included
+ * 0 = Use only library defined errors
+ * 1 = Use also LIST_OF_USER_ERRORS
+ */
+#ifndef USE_USER_ERROR_LIST
+#define USE_USER_ERROR_LIST 0
+#endif
+
+#ifndef USE_DEVICE_DEPENDENT_ERROR_INFORMATION
+#define USE_DEVICE_DEPENDENT_ERROR_INFORMATION SYSTEM_TYPE
+#endif
+
+#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION
+#ifndef USE_MEMORY_ALLOCATION_FREE
+#define USE_MEMORY_ALLOCATION_FREE 1
+#endif
+#else
+#ifndef USE_MEMORY_ALLOCATION_FREE
+#define USE_MEMORY_ALLOCATION_FREE 0
+#endif
+#endif
+
+#ifndef USE_COMMAND_TAGS
+#define USE_COMMAND_TAGS 1
+#endif
+
+#ifndef USE_DEPRECATED_FUNCTIONS
+#define USE_DEPRECATED_FUNCTIONS 1
+#endif
+
+#ifndef USE_CUSTOM_DTOSTRE
+#define USE_CUSTOM_DTOSTRE 0
+#endif
+
+#ifndef USE_UNITS_IMPERIAL
+#define USE_UNITS_IMPERIAL 0
+#endif
+
+#ifndef USE_UNITS_ANGLE
+#define USE_UNITS_ANGLE SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_PARTICLES
+#define USE_UNITS_PARTICLES SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_DISTANCE
+#define USE_UNITS_DISTANCE SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_MAGNETIC
+#define USE_UNITS_MAGNETIC SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_LIGHT
+#define USE_UNITS_LIGHT SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_ENERGY_FORCE_MASS
+#define USE_UNITS_ENERGY_FORCE_MASS SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_TIME
+#define USE_UNITS_TIME SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_TEMPERATURE
+#define USE_UNITS_TEMPERATURE SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_RATIO
+#define USE_UNITS_RATIO SYSTEM_TYPE
+#endif
+
+#ifndef USE_UNITS_POWER
+#define USE_UNITS_POWER 1
+#endif
+
+#ifndef USE_UNITS_FREQUENCY
+#define USE_UNITS_FREQUENCY 1
+#endif
+
+#ifndef USE_UNITS_ELECTRIC
+#define USE_UNITS_ELECTRIC 1
+#endif
+
+#ifndef USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE
+#define USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE SYSTEM_TYPE
+#endif
+
+/* define local macros depending on existance of strnlen */
+#if HAVE_STRNLEN
+#define SCPIDEFINE_strnlen(s, l) strnlen((s), (l))
+#else
+#define SCPIDEFINE_strnlen(s, l) BSD_strnlen((s), (l))
+#endif
+
+/* define local macros depending on existance of strncasecmp and strnicmp */
+#if HAVE_STRNCASECMP
+#define SCPIDEFINE_strncasecmp(s1, s2, l) strncasecmp((s1), (s2), (l))
+#elif HAVE_STRNICMP
+#define SCPIDEFINE_strncasecmp(s1, s2, l) strnicmp((s1), (s2), (l))
+#else
+#define SCPIDEFINE_strncasecmp(s1, s2, l) OUR_strncasecmp((s1), (s2), (l))
+#endif
+
+#if HAVE_DTOSTRE
+#define SCPIDEFINE_floatToStr(v, s, l) dtostre((double)(v), (s), 6, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE)
+#elif USE_CUSTOM_DTOSTRE
+#define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0)
+#elif HAVE_SNPRINTF
+#define SCPIDEFINE_floatToStr(v, s, l) snprintf((s), (l), "%g", (v))
+#else
+#define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0)
+#endif
+
+#if HAVE_DTOSTRE
+#define SCPIDEFINE_doubleToStr(v, s, l) dtostre((v), (s), 15, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE)
+#elif USE_CUSTOM_DTOSTRE
+#define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0)
+#elif HAVE_SNPRINTF
+#define SCPIDEFINE_doubleToStr(v, s, l) snprintf((s), (l), "%.15lg", (v))
+#else
+#define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0)
+#endif
+
+#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION
+
+ #if USE_MEMORY_ALLOCATION_FREE
+ #include <stdlib.h>
+ #include <string.h>
+ #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 2
+ #if HAVE_STRNDUP
+ #define SCPIDEFINE_strndup(h, s, l) strndup((s), (l))
+ #else
+ #define SCPIDEFINE_strndup(h, s, l) OUR_strndup((s), (l))
+ #endif
+ #define SCPIDEFINE_free(h, s, r) free((s))
+ #else
+ #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 3
+ #define SCPIDEFINE_strndup(h, s, l) scpiheap_strndup((h), (s), (l))
+ #define SCPIDEFINE_free(h, s, r) scpiheap_free((h), (s), (r))
+ #define SCPIDEFINE_get_parts(h, s, l1, s2, l2) scpiheap_get_parts((h), (s), (l1), (s2), (l2))
+ #endif
+#else
+ #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 1
+ #define SCPIDEFINE_strndup(h, s, l) NULL
+ #define SCPIDEFINE_free(h, s, r)
+#endif
+
+#if HAVE_SIGNBIT
+ #define SCPIDEFINE_signbit(n) signbit(n)
+#else
+ #define SCPIDEFINE_signbit(n) ((n)<0)
+#endif
+
+#if HAVE_FINITE
+ #define SCPIDEFINE_isfinite(n) finite(n)
+#elif HAVE_ISFINITE
+ #define SCPIDEFINE_isfinite(n) isfinite(n)
+#else
+ #define SCPIDEFINE_isfinite(n) (!SCPIDEFINE_isnan((n)) && ((n) < INFINITY) && ((n) > -INFINITY))
+#endif
+
+#if HAVE_STRTOF
+ #define SCPIDEFINE_strtof(n, p) strtof((n), (p))
+#else
+ #define SCPIDEFINE_strtof(n, p) strtod((n), (p))
+#endif
+
+#if HAVE_STRTOLL
+ #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b))
+ #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b))
+#else
+ #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b))
+ #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b))
+ extern long long int strtoll(const char *nptr, char **endptr, int base);
+ extern unsigned long long int strtoull(const char *nptr, char **endptr, int base);
+ /* TODO: implement OUR_strtoll and OUR_strtoull */
+ /* #warning "64bit string to int conversion not implemented" */
+#endif
+
+#if HAVE_ISNAN
+ #define SCPIDEFINE_isnan(n) isnan((n))
+#else
+ #define SCPIDEFINE_isnan(n) ((n) != (n))
+#endif
+
+#ifndef NAN
+ #define NAN (0.0 / 0.0)
+#endif
+
+#ifndef INFINITY
+ #define INFINITY (1.0 / 0.0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/third_party/libscpi/inc/scpi/constants.h b/third_party/libscpi/inc/scpi/constants.h
new file mode 100644
index 00000000..14b58b43
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/constants.h
@@ -0,0 +1,62 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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_constants.h
+ * @date Thu Nov 15 10:58:45 UTC 2012
+ *
+ * @brief SCPI Device constants
+ *
+ *
+ */
+
+#ifndef SCPI_CONSTANTS_H
+#define SCPI_CONSTANTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* 21.21 :VERSion?
+ * YYYY.V
+ * YYYY = SCPI year
+ * V = SCPI revision
+ */
+#define SCPI_STD_VERSION_REVISION "1999.0"
+
+/* 21.8 :ERRor Subsystem
+ * The maximum string length of <Error/event_description> plus <Device-dependent_info> is 255 characters.
+ */
+#define SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH 255
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_CONSTANTS_H */
+
diff --git a/third_party/libscpi/inc/scpi/error.h b/third_party/libscpi/inc/scpi/error.h
new file mode 100644
index 00000000..d931e4f8
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/error.h
@@ -0,0 +1,208 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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_error.h
+ * @date Thu Nov 15 10:58:45 UTC 2012
+ *
+ * @brief Error handling and storing routines
+ *
+ *
+ */
+
+#ifndef SCPI_ERROR_H
+#define SCPI_ERROR_H
+
+#include "scpi/config.h"
+#include "scpi/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size);
+ void SCPI_ErrorClear(scpi_t * context);
+ scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error);
+ void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info, size_t info_len);
+ void SCPI_ErrorPush(scpi_t * context, int16_t err);
+ int32_t SCPI_ErrorCount(scpi_t * context);
+ const char * SCPI_ErrorTranslate(int16_t err);
+
+
+ /* Using X-Macro technique to define everything once
+ * http://en.wikipedia.org/wiki/X_Macro
+ *
+ * X macro is for minimal set of errors for library itself
+ * XE macro is for full set of SCPI errors available to user application
+ */
+#define LIST_OF_ERRORS \
+ X(SCPI_ERROR_NO_ERROR, 0, "No error") \
+ XE(SCPI_ERROR_COMMAND, -100, "Command error") \
+ X(SCPI_ERROR_INVALID_CHARACTER, -101, "Invalid character") \
+ XE(SCPI_ERROR_SYNTAX, -102, "Syntax error") \
+ X(SCPI_ERROR_INVALID_SEPARATOR, -103, "Invalid separator") \
+ X(SCPI_ERROR_DATA_TYPE_ERROR, -104, "Data type error") \
+ XE(SCPI_ERROR_GET_NOT_ALLOWED, -105, "GET not allowed") \
+ X(SCPI_ERROR_PARAMETER_NOT_ALLOWED, -108, "Parameter not allowed") \
+ X(SCPI_ERROR_MISSING_PARAMETER, -109, "Missing parameter") \
+ XE(SCPI_ERROR_COMMAND_HEADER, -110, "Command header error") \
+ XE(SCPI_ERROR_HEADER_SEPARATOR, -111, "Header separator error") \
+ XE(SCPI_ERROR_PRG_MNEMONIC_TOO_LONG, -112, "Program mnemonic too long") \
+ X(SCPI_ERROR_UNDEFINED_HEADER, -113, "Undefined header") \
+ XE(SCPI_ERROR_HEADER_SUFFIX_OUTOFRANGE, -114, "Header suffix out of range") \
+ XE(SCPI_ERROR_UNEXP_NUM_OF_PARAMETER, -115, "Unexpected number of parameters") \
+ XE(SCPI_ERROR_NUMERIC_DATA_ERROR, -120, "Numeric data error") \
+ XE(SCPI_ERROR_INVAL_CHAR_IN_NUMBER, -121, "Invalid character in number") \
+ XE(SCPI_ERROR_EXPONENT_TOO_LONG, -123, "Exponent too large") \
+ XE(SCPI_ERROR_TOO_MANY_DIGITS, -124, "Too many digits") \
+ XE(SCPI_ERROR_NUMERIC_DATA_NOT_ALLOWED, -128, "Numeric data not allowed") \
+ XE(SCPI_ERROR_SUFFIX_ERROR, -130, "Suffix error") \
+ X(SCPI_ERROR_INVALID_SUFFIX, -131, "Invalid suffix") \
+ XE(SCPI_ERROR_SUFFIX_TOO_LONG, -134, "Suffix too long") \
+ X(SCPI_ERROR_SUFFIX_NOT_ALLOWED, -138, "Suffix not allowed") \
+ XE(SCPI_ERROR_CHARACTER_DATA_ERROR, -140, "Character data error") \
+ XE(SCPI_ERROR_INVAL_CHARACTER_DATA, -141, "Invalid character data") \
+ XE(SCPI_ERROR_CHARACTER_DATA_TOO_LONG, -144, "Character data too long") \
+ XE(SCPI_ERROR_CHARACTER_DATA_NOT_ALLOWED, -148, "Character data not allowed") \
+ XE(SCPI_ERROR_STRING_DATA_ERROR, -150, "String data error") \
+ X(SCPI_ERROR_INVALID_STRING_DATA, -151, "Invalid string data") \
+ XE(SCPI_ERROR_STRING_DATA_NOT_ALLOWED, -158, "String data not allowed") \
+ XE(SCPI_ERROR_BLOCK_DATA_ERROR, -160, "Block data error") \
+ XE(SCPI_ERROR_INVALID_BLOCK_DATA, -161, "Invalid block data") \
+ XE(SCPI_ERROR_BLOCK_DATA_NOT_ALLOWED, -168, "Block data not allowed") \
+ X(SCPI_ERROR_EXPRESSION_PARSING_ERROR, -170, "Expression error") \
+ XE(SCPI_ERROR_INVAL_EXPRESSION, -171, "Invalid expression") \
+ XE(SCPI_ERROR_EXPRESSION_DATA_NOT_ALLOWED, -178, "Expression data not allowed") \
+ XE(SCPI_ERROR_MACRO_DEFINITION_ERROR, -180, "Macro error") \
+ XE(SCPI_ERROR_INVAL_OUTSIDE_MACRO_DEF, -181, "Invalid outside macro definition") \
+ XE(SCPI_ERROR_INVAL_INSIDE_MACRO_DEF, -183, "Invalid inside macro definition") \
+ XE(SCPI_ERROR_MACRO_PARAMETER_ERROR, -184, "Macro parameter error") \
+ X(SCPI_ERROR_EXECUTION_ERROR, -200, "Execution error") \
+ XE(SCPI_ERROR_INVAL_WHILE_IN_LOCAL, -201, "Invalid while in local") \
+ XE(SCPI_ERROR_SETTINGS_LOST_DUE_TO_RTL, -202, "Settings lost due to rtl") \
+ XE(SCPI_ERROR_COMMAND_PROTECTED, -203, "Command protected") \
+ XE(SCPI_ERROR_TRIGGER_ERROR, -210, "Trigger error") \
+ XE(SCPI_ERROR_TRIGGER_IGNORED, -211, "Trigger ignored") \
+ XE(SCPI_ERROR_ARM_IGNORED, -212, "Arm ignored") \
+ XE(SCPI_ERROR_INIT_IGNORED, -213, "Init ignored") \
+ XE(SCPI_ERROR_TRIGGER_DEADLOCK, -214, "Trigger deadlock") \
+ XE(SCPI_ERROR_ARM_DEADLOCK, -215, "Arm deadlock") \
+ XE(SCPI_ERROR_PARAMETER_ERROR, -220, "Parameter error") \
+ XE(SCPI_ERROR_SETTINGS_CONFLICT, -221, "Settings conflict") \
+ XE(SCPI_ERROR_DATA_OUT_OF_RANGE, -222, "Data out of range") \
+ XE(SCPI_ERROR_TOO_MUCH_DATA, -223, "Too much data") \
+ X(SCPI_ERROR_ILLEGAL_PARAMETER_VALUE, -224, "Illegal parameter value") \
+ XE(SCPI_ERROR_OUT_OF_MEMORY_FOR_REQ_OP, -225, "Out of memory") \
+ XE(SCPI_ERROR_LISTS_NOT_SAME_LENGTH, -226, "Lists not same length") \
+ XE(SCPI_ERROR_DATA_CORRUPT, -230, "Data corrupt or stale") \
+ XE(SCPI_ERROR_DATA_QUESTIONABLE, -231, "Data questionable") \
+ XE(SCPI_ERROR_INVAL_VERSION, -233, "Invalid version") \
+ XE(SCPI_ERROR_HARDWARE_ERROR, -240, "Hardware error") \
+ XE(SCPI_ERROR_HARDWARE_MISSING, -241, "Hardware missing") \
+ XE(SCPI_ERROR_MASS_STORAGE_ERROR, -250, "Mass storage error") \
+ XE(SCPI_ERROR_MISSING_MASS_STORAGE, -251, "Missing mass storage") \
+ XE(SCPI_ERROR_MISSING_MASS_MEDIA, -252, "Missing media") \
+ XE(SCPI_ERROR_CORRUPT_MEDIA, -253, "Corrupt media") \
+ XE(SCPI_ERROR_MEDIA_FULL, -254, "Media full") \
+ XE(SCPI_ERROR_DIRECTORY_FULL, -255, "Directory full") \
+ XE(SCPI_ERROR_FILE_NAME_NOT_FOUND, -256, "File name not found") \
+ XE(SCPI_ERROR_FILE_NAME_ERROR, -257, "File name error") \
+ XE(SCPI_ERROR_MEDIA_PROTECTED, -258, "Media protected") \
+ XE(SCPI_ERROR_EXPRESSION_EXECUTING_ERROR, -260, "Expression error") \
+ XE(SCPI_ERROR_MATH_ERROR_IN_EXPRESSION, -261, "Math error in expression") \
+ XE(SCPI_ERROR_MACRO_UNDEF_EXEC_ERROR, -270, "Macro error") \
+ XE(SCPI_ERROR_MACRO_SYNTAX_ERROR, -271, "Macro syntax error") \
+ XE(SCPI_ERROR_MACRO_EXECUTION_ERROR, -272, "Macro execution error") \
+ XE(SCPI_ERROR_ILLEGAL_MACRO_LABEL, -273, "Illegal macro label") \
+ XE(SCPI_ERROR_IMPROPER_USED_MACRO_PARAM, -274, "Macro parameter error") \
+ XE(SCPI_ERROR_MACRO_DEFINITION_TOO_LONG, -275, "Macro definition too long") \
+ XE(SCPI_ERROR_MACRO_RECURSION_ERROR, -276, "Macro recursion error") \
+ XE(SCPI_ERROR_MACRO_REDEF_NOT_ALLOWED, -277, "Macro redefinition not allowed") \
+ XE(SCPI_ERROR_MACRO_HEADER_NOT_FOUND, -278, "Macro header not found") \
+ XE(SCPI_ERROR_PROGRAM_ERROR, -280, "Program error") \
+ XE(SCPI_ERROR_CANNOT_CREATE_PROGRAM, -281, "Cannot create program") \
+ XE(SCPI_ERROR_ILLEGAL_PROGRAM_NAME, -282, "Illegal program name") \
+ XE(SCPI_ERROR_ILLEGAL_VARIABLE_NAME, -283, "Illegal variable name") \
+ XE(SCPI_ERROR_PROGRAM_CURRENTLY_RUNNING, -284, "Program currently running") \
+ XE(SCPI_ERROR_PROGRAM_SYNTAX_ERROR, -285, "Program syntax error") \
+ XE(SCPI_ERROR_PROGRAM_RUNTIME_ERROR, -286, "Program runtime error") \
+ XE(SCPI_ERROR_MEMORY_USE_ERROR, -290, "Memory use error") \
+ XE(SCPI_ERROR_OUT_OF_MEMORY, -291, "Out of memory") \
+ XE(SCPI_ERROR_REF_NAME_DOES_NOT_EXIST, -292, "Referenced name does not exist") \
+ XE(SCPI_ERROR_REF_NAME_ALREADY_EXISTS, -293, "Referenced name already exists") \
+ XE(SCPI_ERROR_INCOMPATIBLE_TYPE, -294, "Incompatible type") \
+ XE(SCPI_ERROR_DEVICE_ERROR, -300, "Device specific error") \
+ X(SCPI_ERROR_SYSTEM_ERROR, -310, "System error") \
+ XE(SCPI_ERROR_MEMORY_ERROR, -311, "Memory error") \
+ XE(SCPI_ERROR_PUD_MEMORY_LOST, -312, "PUD memory lost") \
+ XE(SCPI_ERROR_CALIBRATION_MEMORY_LOST, -313, "Calibration memory lost") \
+ XE(SCPI_ERROR_SAVE_RECALL_MEMORY_LOST, -314, "Save/recall memory lost") \
+ XE(SCPI_ERROR_CONFIGURATION_MEMORY_LOST, -315, "Configuration memory lost") \
+ XE(SCPI_ERROR_STORAGE_FAULT, -320, "Storage fault") \
+ XE(SCPI_ERROR_OUT_OF_DEVICE_MEMORY, -321, "Out of memory") \
+ XE(SCPI_ERROR_SELF_TEST_FAILED, -330, "Self-test failed") \
+ XE(SCPI_ERROR_CALIBRATION_FAILED, -340, "Calibration failed") \
+ X(SCPI_ERROR_QUEUE_OVERFLOW, -350, "Queue overflow") \
+ XE(SCPI_ERROR_COMMUNICATION_ERROR, -360, "Communication error") \
+ XE(SCPI_ERROR_PARITY_ERROR_IN_CMD_MSG, -361, "Parity error in program message") \
+ XE(SCPI_ERROR_FRAMING_ERROR_IN_CMD_MSG, -362, "Framing error in program message") \
+ X(SCPI_ERROR_INPUT_BUFFER_OVERRUN, -363, "Input buffer overrun") \
+ XE(SCPI_ERROR_TIME_OUT, -365, "Time out error") \
+ XE(SCPI_ERROR_QUERY_ERROR, -400, "Query error") \
+ XE(SCPI_ERROR_QUERY_INTERRUPTED, -410, "Query INTERRUPTED") \
+ XE(SCPI_ERROR_QUERY_UNTERMINATED, -420, "Query UNTERMINATED") \
+ XE(SCPI_ERROR_QUERY_DEADLOCKED, -430, "Query DEADLOCKED") \
+ XE(SCPI_ERROR_QUERY_UNTERM_INDEF_RESP, -440, "Query UNTERMINATED after indefinite response") \
+ XE(SCPI_ERROR_POWER_ON, -500, "Power on") \
+ XE(SCPI_ERROR_USER_REQUEST, -600, "User request") \
+ XE(SCPI_ERROR_REQUEST_CONTROL, -700, "Request control") \
+ XE(SCPI_ERROR_OPERATION_COMPLETE, -800, "Operation complete") \
+
+
+ enum {
+#define X(def, val, str) def = val,
+#if USE_FULL_ERROR_LIST
+#define XE X
+#else
+#define XE(def, val, str)
+#endif
+ LIST_OF_ERRORS
+
+#if USE_USER_ERROR_LIST
+ LIST_OF_USER_ERRORS
+#endif
+#undef X
+#undef XE
+ };
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_ERROR_H */
+
diff --git a/third_party/libscpi/inc/scpi/expression.h b/third_party/libscpi/inc/scpi/expression.h
new file mode 100644
index 00000000..897eb14d
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/expression.h
@@ -0,0 +1,62 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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 expression.h
+ *
+ * @brief Expressions handling
+ *
+ *
+ */
+#ifndef SCPI_EXPRESSION_H
+#define SCPI_EXPRESSION_H
+
+#include "scpi/config.h"
+#include "scpi/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ enum _scpi_expr_result_t {
+ SCPI_EXPR_OK = 0,
+ SCPI_EXPR_ERROR,
+ SCPI_EXPR_NO_MORE,
+ };
+ typedef enum _scpi_expr_result_t scpi_expr_result_t;
+
+ scpi_expr_result_t SCPI_ExprNumericListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, scpi_parameter_t * valueFrom, scpi_parameter_t * valueTo);
+ scpi_expr_result_t SCPI_ExprNumericListEntryInt(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valueFrom, int32_t * valueTo);
+ scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo);
+ scpi_expr_result_t SCPI_ExprChannelListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valuesFrom, int32_t * valuesTo, size_t length, size_t * dimensions);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_EXPRESSION_H */
diff --git a/third_party/libscpi/inc/scpi/ieee488.h b/third_party/libscpi/inc/scpi/ieee488.h
new file mode 100644
index 00000000..15fb527d
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/ieee488.h
@@ -0,0 +1,94 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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_ieee488.h
+ * @date Thu Nov 15 10:58:45 UTC 2012
+ *
+ * @brief Implementation of IEEE488.2 commands and state model
+ *
+ *
+ */
+
+#ifndef SCPI_IEEE488_H
+#define SCPI_IEEE488_H
+
+#include "scpi/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ scpi_result_t SCPI_CoreCls(scpi_t * context);
+ scpi_result_t SCPI_CoreEse(scpi_t * context);
+ scpi_result_t SCPI_CoreEseQ(scpi_t * context);
+ scpi_result_t SCPI_CoreEsrQ(scpi_t * context);
+ scpi_result_t SCPI_CoreIdnQ(scpi_t * context);
+ scpi_result_t SCPI_CoreOpc(scpi_t * context);
+ scpi_result_t SCPI_CoreOpcQ(scpi_t * context);
+ scpi_result_t SCPI_CoreRst(scpi_t * context);
+ scpi_result_t SCPI_CoreSre(scpi_t * context);
+ scpi_result_t SCPI_CoreSreQ(scpi_t * context);
+ scpi_result_t SCPI_CoreStbQ(scpi_t * context);
+ scpi_result_t SCPI_CoreTstQ(scpi_t * context);
+ scpi_result_t SCPI_CoreWai(scpi_t * context);
+
+
+#define STB_R01 0x01 /* Not used */
+#define STB_PRO 0x02 /* Protection Event Flag */
+#define STB_QMA 0x04 /* Error/Event queue message available */
+#define STB_QES 0x08 /* Questionable status */
+#define STB_MAV 0x10 /* Message Available */
+#define STB_ESR 0x20 /* Standard Event Status Register */
+#define STB_SRQ 0x40 /* Service Request */
+#define STB_OPS 0x80 /* Operation Status Flag */
+
+
+#define ESR_OPC 0x01 /* Operation complete */
+#define ESR_REQ 0x02 /* Request Control */
+#define ESR_QER 0x04 /* Query Error */
+#define ESR_DER 0x08 /* Device Dependent Error */
+#define ESR_EER 0x10 /* Execution Error (e.g. range error) */
+#define ESR_CER 0x20 /* Command error (e.g. syntax error) */
+#define ESR_URQ 0x40 /* User Request */
+#define ESR_PON 0x80 /* Power On */
+
+
+ scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name);
+ void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val);
+ void SCPI_RegSetBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits);
+ void SCPI_RegClearBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits);
+
+ void SCPI_EventClear(scpi_t * context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_IEEE488_H */
+
diff --git a/third_party/libscpi/inc/scpi/minimal.h b/third_party/libscpi/inc/scpi/minimal.h
new file mode 100644
index 00000000..e14f1ed6
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/minimal.h
@@ -0,0 +1,69 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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_minimal.h
+ * @date Thu Nov 15 10:58:45 UTC 2012
+ *
+ * @brief SCPI minimal implementation
+ *
+ *
+ */
+
+#ifndef SCPI_MINIMAL_H
+#define SCPI_MINIMAL_H
+
+#include "scpi/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ scpi_result_t SCPI_Stub(scpi_t * context);
+ scpi_result_t SCPI_StubQ(scpi_t * context);
+
+ scpi_result_t SCPI_SystemVersionQ(scpi_t * context);
+ scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context);
+ scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context);
+ scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context);
+ scpi_result_t SCPI_StatusQuestionableConditionQ(scpi_t * context);
+ scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context);
+ scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context);
+ scpi_result_t SCPI_StatusOperationConditionQ(scpi_t * context);
+ scpi_result_t SCPI_StatusOperationEventQ(scpi_t * context);
+ scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context);
+ scpi_result_t SCPI_StatusOperationEnable(scpi_t * context);
+ scpi_result_t SCPI_StatusPreset(scpi_t * context);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_MINIMAL_H */
+
diff --git a/third_party/libscpi/inc/scpi/parser.h b/third_party/libscpi/inc/scpi/parser.h
new file mode 100644
index 00000000..643cec61
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/parser.h
@@ -0,0 +1,151 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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_parser.h
+ * @date Thu Nov 15 10:58:45 UTC 2012
+ *
+ * @brief SCPI parser implementation
+ *
+ *
+ */
+
+#ifndef SCPI_PARSER_H
+#define SCPI_PARSER_H
+
+#include <string.h>
+#include "scpi/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void SCPI_Init(scpi_t * context,
+ const scpi_command_t * commands,
+ scpi_interface_t * interface,
+ const scpi_unit_def_t * units,
+ const char * idn1, const char * idn2, const char * idn3, const char * idn4,
+ char * input_buffer, size_t input_buffer_length,
+ scpi_error_t * error_queue_data, int16_t error_queue_size);
+#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE
+ void SCPI_InitHeap(scpi_t * context, char * error_info_heap, size_t error_info_heap_length);
+#endif
+
+ scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len);
+ scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len);
+
+ size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len);
+#define SCPI_ResultMnemonic(context, data) SCPI_ResultCharacters((context), (data), strlen(data))
+#define SCPI_ResultUInt8Base(c, v, b) SCPI_ResultUInt32Base((c), (v), (uint8_t)(b))
+#define SCPI_ResultUInt8(c, v) SCPI_ResultUInt32Base((c), (uint8_t)(v), 10)
+#define SCPI_ResultInt8(c, v) SCPI_ResultInt32((c), (int8_t)(v))
+#define SCPI_ResultUInt16Base(c, v, b) SCPI_ResultUInt32Base((c), (uint16_t)(v), (b))
+#define SCPI_ResultUInt16(c, v) SCPI_ResultUInt32Base((c), (uint16_t)(v), 10)
+#define SCPI_ResultInt16(c, v) SCPI_ResultInt32((c), (int16_t)(v))
+ size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base);
+#define SCPI_ResultUInt32(c, v) SCPI_ResultUInt32Base((c), (v), 10)
+ size_t SCPI_ResultInt32(scpi_t * context, int32_t val);
+ size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base);
+#define SCPI_ResultUInt64(c, v) SCPI_ResultUInt64Base((c), (v), 10)
+ size_t SCPI_ResultInt64(scpi_t * context, int64_t val);
+ size_t SCPI_ResultFloat(scpi_t * context, float val);
+ size_t SCPI_ResultDouble(scpi_t * context, double val);
+ size_t SCPI_ResultText(scpi_t * context, const char * data);
+ size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error);
+ size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len);
+ size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len);
+ size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len);
+ size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val);
+
+ size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format);
+ size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format);
+
+ scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamIsValid(scpi_parameter_t * parameter);
+ scpi_bool_t SCPI_ParamErrorOccurred(scpi_t * context);
+ scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed);
+ scpi_bool_t SCPI_ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value);
+ scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value);
+ scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value);
+ scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value);
+ scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value);
+ scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value);
+ scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value);
+ scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text);
+
+ scpi_bool_t SCPI_ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamCopyText(scpi_t * context, char * buffer, size_t buffer_len, size_t * copy_len, scpi_bool_t mandatory);
+
+ extern const scpi_choice_def_t scpi_bool_def[];
+ scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory);
+
+ scpi_bool_t SCPI_ParamArrayInt32(scpi_t * context, int32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamArrayUInt32(scpi_t * context, uint32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamArrayInt64(scpi_t * context, int64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamArrayUInt64(scpi_t * context, uint64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamArrayFloat(scpi_t * context, float *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory);
+ scpi_bool_t SCPI_ParamArrayDouble(scpi_t * context, double *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory);
+
+ scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd);
+#if USE_COMMAND_TAGS
+ int32_t SCPI_CmdTag(scpi_t * context);
+#endif /* USE_COMMAND_TAGS */
+ scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len);
+ scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value);
+
+#if USE_DEPRECATED_FUNCTIONS
+ /* deprecated finction, should be removed later */
+#define SCPI_ResultIntBase(context, val, base) SCPI_ResultInt32Base ((context), (val), (base), TRUE)
+#define SCPI_ResultInt(context, val) SCPI_ResultInt32 ((context), (val))
+#define SCPI_ParamToInt(context, parameter, value) SCPI_ParamToInt32((context), (parameter), (value))
+#define SCPI_ParamToUnsignedInt(context, parameter, value) SCPI_ParamToUInt32((context), (parameter), (value))
+#define SCPI_ParamInt(context, value, mandatory) SCPI_ParamInt32((context), (value), (mandatory))
+#define SCPI_ParamUnsignedInt(context, value, mandatory) SCPI_ParamUInt32((context), (value), (mandatory))
+#endif /* USE_DEPRECATED_FUNCTIONS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_PARSER_H */
+
diff --git a/third_party/libscpi/inc/scpi/scpi.h b/third_party/libscpi/inc/scpi/scpi.h
new file mode 100644
index 00000000..ea28dd44
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/scpi.h
@@ -0,0 +1,51 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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.h
+ * @date Thu Nov 15 10:58:45 UTC 2012
+ *
+ * @brief SCPI library include file
+ *
+ *
+ */
+
+#ifndef SCPI_H
+#define SCPI_H
+
+#include "scpi/parser.h"
+#include "scpi/ieee488.h"
+#include "scpi/error.h"
+#include "scpi/constants.h"
+#include "scpi/minimal.h"
+#include "scpi/units.h"
+#include "scpi/utils.h"
+#include "scpi/expression.h"
+
+#endif /* SCPI_H */
+
diff --git a/third_party/libscpi/inc/scpi/types.h b/third_party/libscpi/inc/scpi/types.h
new file mode 100644
index 00000000..eb9b2153
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/types.h
@@ -0,0 +1,459 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, Jan Breuer, Richard.hmm
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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_types.h
+ * @date Thu Nov 15 10:58:45 UTC 2012
+ *
+ * @brief SCPI data types
+ *
+ *
+ */
+
+#ifndef SCPI_TYPES_H
+#define SCPI_TYPES_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include "scpi/config.h"
+
+#if HAVE_STDBOOL
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !HAVE_STDBOOL
+ typedef unsigned char bool;
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+ /* basic data types */
+ typedef bool scpi_bool_t;
+ /* typedef enum { FALSE = 0, TRUE } scpi_bool_t; */
+
+ /* IEEE 488.2 registers */
+ enum _scpi_reg_name_t {
+ SCPI_REG_STB = 0, /* Status Byte */
+ SCPI_REG_SRE, /* Service Request Enable Register */
+ SCPI_REG_ESR, /* Standard Event Status Register (ESR, SESR) */
+ SCPI_REG_ESE, /* Event Status Enable Register */
+ SCPI_REG_OPER, /* OPERation Status Register */
+ SCPI_REG_OPERE, /* OPERation Status Enable Register */
+ SCPI_REG_OPERC, /* OPERation Status Condition Register */
+ SCPI_REG_QUES, /* QUEStionable status register */
+ SCPI_REG_QUESE, /* QUEStionable status Enable Register */
+ SCPI_REG_QUESC, /* QUEStionable status Condition Register */
+
+#if USE_CUSTOM_REGISTERS
+#ifndef USER_REGISTERS
+#error "No user registers defined"
+#else
+ USER_REGISTERS
+#endif
+#endif
+
+ /* number of registers */
+ SCPI_REG_COUNT,
+ /* last definition - a value for no register */
+ SCPI_REG_NONE
+ };
+ typedef enum _scpi_reg_name_t scpi_reg_name_t;
+
+ enum _scpi_ctrl_name_t {
+ SCPI_CTRL_SRQ = 1, /* service request */
+ SCPI_CTRL_GTL, /* Go to local */
+ SCPI_CTRL_SDC, /* Selected device clear */
+ SCPI_CTRL_PPC, /* Parallel poll configure */
+ SCPI_CTRL_GET, /* Group execute trigger */
+ SCPI_CTRL_TCT, /* Take control */
+ SCPI_CTRL_LLO, /* Device clear */
+ SCPI_CTRL_DCL, /* Local lockout */
+ SCPI_CTRL_PPU, /* Parallel poll unconfigure */
+ SCPI_CTRL_SPE, /* Serial poll enable */
+ SCPI_CTRL_SPD, /* Serial poll disable */
+ SCPI_CTRL_MLA, /* My local address */
+ SCPI_CTRL_UNL, /* Unlisten */
+ SCPI_CTRL_MTA, /* My talk address */
+ SCPI_CTRL_UNT, /* Untalk */
+ SCPI_CTRL_MSA /* My secondary address */
+ };
+ typedef enum _scpi_ctrl_name_t scpi_ctrl_name_t;
+
+ typedef uint16_t scpi_reg_val_t;
+
+ enum _scpi_reg_class_t {
+ SCPI_REG_CLASS_STB = 0,
+ SCPI_REG_CLASS_SRE,
+ SCPI_REG_CLASS_EVEN,
+ SCPI_REG_CLASS_ENAB,
+ SCPI_REG_CLASS_COND,
+ SCPI_REG_CLASS_NTR,
+ SCPI_REG_CLASS_PTR,
+ };
+ typedef enum _scpi_reg_class_t scpi_reg_class_t;
+
+ enum _scpi_reg_group_t {
+ SCPI_REG_GROUP_STB = 0,
+ SCPI_REG_GROUP_ESR,
+ SCPI_REG_GROUP_OPER,
+ SCPI_REG_GROUP_QUES,
+
+#if USE_CUSTOM_REGISTERS
+#ifndef USER_REGISTER_GROUPS
+#error "No user register groups defined"
+#else
+ USER_REGISTER_GROUPS
+#endif
+#endif
+
+ /* last definition - number of register groups */
+ SCPI_REG_GROUP_COUNT
+ };
+ typedef enum _scpi_reg_group_t scpi_reg_group_t;
+
+ struct _scpi_reg_info_t {
+ scpi_reg_class_t type;
+ scpi_reg_group_t group;
+ };
+ typedef struct _scpi_reg_info_t scpi_reg_info_t;
+
+ struct _scpi_reg_group_info_t {
+ scpi_reg_name_t event;
+ scpi_reg_name_t enable;
+ scpi_reg_name_t condition;
+ scpi_reg_name_t ptfilt;
+ scpi_reg_name_t ntfilt;
+ scpi_reg_name_t parent_reg;
+ scpi_reg_val_t parent_bit;
+ };
+ typedef struct _scpi_reg_group_info_t scpi_reg_group_info_t;
+
+ /* scpi commands */
+ enum _scpi_result_t {
+ SCPI_RES_OK = 1,
+ SCPI_RES_ERR = -1
+ };
+ typedef enum _scpi_result_t scpi_result_t;
+
+ typedef struct _scpi_command_t scpi_command_t;
+
+#if USE_COMMAND_TAGS
+ #define SCPI_CMD_LIST_END {NULL, NULL, 0}
+#else
+ #define SCPI_CMD_LIST_END {NULL, NULL}
+#endif
+
+
+ /* scpi interface */
+ typedef struct _scpi_t scpi_t;
+ typedef struct _scpi_interface_t scpi_interface_t;
+
+ struct _scpi_buffer_t {
+ size_t length;
+ size_t position;
+ char * data;
+ };
+ typedef struct _scpi_buffer_t scpi_buffer_t;
+
+ struct _scpi_const_buffer_t {
+ size_t length;
+ size_t position;
+ const char * data;
+ };
+ typedef struct _scpi_const_buffer_t scpi_const_buffer_t;
+
+ typedef size_t(*scpi_write_t)(scpi_t * context, const char * data, size_t len);
+ typedef scpi_result_t(*scpi_write_control_t)(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val);
+ typedef int (*scpi_error_callback_t)(scpi_t * context, int_fast16_t error);
+
+ /* scpi lexer */
+ enum _scpi_token_type_t {
+ SCPI_TOKEN_COMMA,
+ SCPI_TOKEN_SEMICOLON,
+ SCPI_TOKEN_COLON,
+ SCPI_TOKEN_SPECIFIC_CHARACTER,
+ SCPI_TOKEN_QUESTION,
+ SCPI_TOKEN_NL,
+ SCPI_TOKEN_HEXNUM,
+ SCPI_TOKEN_OCTNUM,
+ SCPI_TOKEN_BINNUM,
+ SCPI_TOKEN_PROGRAM_MNEMONIC,
+ SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA,
+ SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX,
+ SCPI_TOKEN_SUFFIX_PROGRAM_DATA,
+ SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA,
+ SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA,
+ SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA,
+ SCPI_TOKEN_PROGRAM_EXPRESSION,
+ SCPI_TOKEN_COMPOUND_PROGRAM_HEADER,
+ SCPI_TOKEN_INCOMPLETE_COMPOUND_PROGRAM_HEADER,
+ SCPI_TOKEN_COMMON_PROGRAM_HEADER,
+ SCPI_TOKEN_INCOMPLETE_COMMON_PROGRAM_HEADER,
+ SCPI_TOKEN_COMPOUND_QUERY_PROGRAM_HEADER,
+ SCPI_TOKEN_COMMON_QUERY_PROGRAM_HEADER,
+ SCPI_TOKEN_WS,
+ SCPI_TOKEN_ALL_PROGRAM_DATA,
+ SCPI_TOKEN_INVALID,
+ SCPI_TOKEN_UNKNOWN,
+ };
+ typedef enum _scpi_token_type_t scpi_token_type_t;
+
+ struct _scpi_token_t {
+ scpi_token_type_t type;
+ char * ptr;
+ int len;
+ };
+ typedef struct _scpi_token_t scpi_token_t;
+
+ struct _lex_state_t {
+ char * buffer;
+ char * pos;
+ int len;
+ };
+ typedef struct _lex_state_t lex_state_t;
+
+ /* scpi parser */
+ enum _message_termination_t {
+ SCPI_MESSAGE_TERMINATION_NONE,
+ SCPI_MESSAGE_TERMINATION_NL,
+ SCPI_MESSAGE_TERMINATION_SEMICOLON,
+ };
+ typedef enum _message_termination_t message_termination_t;
+
+ struct _scpi_parser_state_t {
+ scpi_token_t programHeader;
+ scpi_token_t programData;
+ int numberOfParameters;
+ message_termination_t termination;
+ };
+ typedef struct _scpi_parser_state_t scpi_parser_state_t;
+
+ typedef scpi_result_t(*scpi_command_callback_t)(scpi_t *);
+
+ struct _scpi_error_info_heap_t {
+ size_t wr;
+ /* size_t rd; */
+ size_t count;
+ size_t size;
+ char * data;
+ };
+ typedef struct _scpi_error_info_heap_t scpi_error_info_heap_t;
+
+ struct _scpi_error_t {
+ int16_t error_code;
+#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION
+ char * device_dependent_info;
+#endif
+ };
+ typedef struct _scpi_error_t scpi_error_t;
+
+ struct _scpi_fifo_t {
+ int16_t wr;
+ int16_t rd;
+ int16_t count;
+ int16_t size;
+ scpi_error_t * data;
+ };
+ typedef struct _scpi_fifo_t scpi_fifo_t;
+
+ /* scpi units */
+ enum _scpi_unit_t {
+ SCPI_UNIT_NONE,
+ SCPI_UNIT_VOLT,
+ SCPI_UNIT_AMPER,
+ SCPI_UNIT_OHM,
+ SCPI_UNIT_HERTZ,
+ SCPI_UNIT_CELSIUS,
+ SCPI_UNIT_SECOND,
+ SCPI_UNIT_METER,
+ SCPI_UNIT_GRAY,
+ SCPI_UNIT_BECQUEREL,
+ SCPI_UNIT_MOLE,
+ SCPI_UNIT_DEGREE,
+ SCPI_UNIT_GRADE,
+ SCPI_UNIT_RADIAN,
+ SCPI_UNIT_REVOLUTION,
+ SCPI_UNIT_STERADIAN,
+ SCPI_UNIT_SIEVERT,
+ SCPI_UNIT_FARAD,
+ SCPI_UNIT_COULOMB,
+ SCPI_UNIT_SIEMENS,
+ SCPI_UNIT_ELECTRONVOLT,
+ SCPI_UNIT_JOULE,
+ SCPI_UNIT_NEWTON,
+ SCPI_UNIT_LUX,
+ SCPI_UNIT_HENRY,
+ SCPI_UNIT_ASTRONOMIC_UNIT,
+ SCPI_UNIT_INCH,
+ SCPI_UNIT_FOOT,
+ SCPI_UNIT_PARSEC,
+ SCPI_UNIT_MILE,
+ SCPI_UNIT_NAUTICAL_MILE,
+ SCPI_UNIT_LUMEN,
+ SCPI_UNIT_CANDELA,
+ SCPI_UNIT_WEBER,
+ SCPI_UNIT_TESLA,
+ SCPI_UNIT_ATOMIC_MASS,
+ SCPI_UNIT_KILOGRAM,
+ SCPI_UNIT_WATT,
+ SCPI_UNIT_DBM,
+ SCPI_UNIT_ATMOSPHERE,
+ SCPI_UNIT_INCH_OF_MERCURY,
+ SCPI_UNIT_MM_OF_MERCURY,
+ SCPI_UNIT_PASCAL,
+ SCPI_UNIT_TORT,
+ SCPI_UNIT_BAR,
+ SCPI_UNIT_DECIBEL,
+ SCPI_UNIT_UNITLESS,
+ SCPI_UNIT_FAHRENHEIT,
+ SCPI_UNIT_KELVIN,
+ SCPI_UNIT_DAY,
+ SCPI_UNIT_YEAR,
+ SCPI_UNIT_STROKES,
+ SCPI_UNIT_POISE,
+ SCPI_UNIT_LITER
+ };
+ typedef enum _scpi_unit_t scpi_unit_t;
+
+ struct _scpi_unit_def_t {
+ const char * name;
+ scpi_unit_t unit;
+ double mult;
+ };
+#define SCPI_UNITS_LIST_END {NULL, SCPI_UNIT_NONE, 0}
+ typedef struct _scpi_unit_def_t scpi_unit_def_t;
+
+ 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,
+ SCPI_NUM_AUTO
+ };
+ typedef enum _scpi_special_number_t scpi_special_number_t;
+
+ struct _scpi_choice_def_t {
+ const char * name;
+ int32_t tag;
+ };
+#define SCPI_CHOICE_LIST_END {NULL, -1}
+ typedef struct _scpi_choice_def_t scpi_choice_def_t;
+
+ struct _scpi_param_list_t {
+ const scpi_command_t * cmd;
+ lex_state_t lex_state;
+ scpi_const_buffer_t cmd_raw;
+ };
+ typedef struct _scpi_param_list_t scpi_param_list_t;
+
+ struct _scpi_number_parameter_t {
+ scpi_bool_t special;
+
+ union {
+ double value;
+ int32_t tag;
+ } content;
+ scpi_unit_t unit;
+ int8_t base;
+ };
+ typedef struct _scpi_number_parameter_t scpi_number_t;
+
+ struct _scpi_data_parameter_t {
+ const char * ptr;
+ int32_t len;
+ };
+ typedef struct _scpi_data_parameter_t scpi_data_parameter_t;
+
+ typedef scpi_token_t scpi_parameter_t;
+
+ struct _scpi_command_t {
+ const char * pattern;
+ scpi_command_callback_t callback;
+#if USE_COMMAND_TAGS
+ int32_t tag;
+#endif /* USE_COMMAND_TAGS */
+ };
+
+ struct _scpi_interface_t {
+ scpi_error_callback_t error;
+ scpi_write_t write;
+ scpi_write_control_t control;
+ scpi_command_callback_t flush;
+ scpi_command_callback_t reset;
+ };
+
+ struct _scpi_t {
+ const scpi_command_t * cmdlist;
+ scpi_buffer_t buffer;
+ scpi_param_list_t param_list;
+ scpi_interface_t * interface;
+ int_fast16_t output_count;
+ int_fast16_t input_count;
+ scpi_bool_t first_output;
+ scpi_bool_t cmd_error;
+ scpi_fifo_t error_queue;
+#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE
+ scpi_error_info_heap_t error_info_heap;
+#endif
+ scpi_reg_val_t registers[SCPI_REG_COUNT];
+ const scpi_unit_def_t * units;
+ void * user_context;
+ scpi_parser_state_t parser_state;
+ const char * idn[4];
+ size_t arbitrary_remaining;
+ };
+
+ enum _scpi_array_format_t {
+ SCPI_FORMAT_ASCII = 0,
+ SCPI_FORMAT_NORMAL = 1,
+ SCPI_FORMAT_SWAPPED = 2,
+ SCPI_FORMAT_BIGENDIAN = SCPI_FORMAT_NORMAL,
+ SCPI_FORMAT_LITTLEENDIAN = SCPI_FORMAT_SWAPPED,
+ };
+ typedef enum _scpi_array_format_t scpi_array_format_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_TYPES_H */
+
diff --git a/third_party/libscpi/inc/scpi/units.h b/third_party/libscpi/inc/scpi/units.h
new file mode 100644
index 00000000..345e9fa4
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/units.h
@@ -0,0 +1,60 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern const scpi_unit_def_t scpi_units_def[];
+ extern const scpi_choice_def_t scpi_special_numbers_def[];
+
+ scpi_bool_t SCPI_ParamNumber(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, scpi_bool_t mandatory);
+
+ scpi_bool_t SCPI_ParamTranslateNumberVal(scpi_t * context, scpi_parameter_t * parameter);
+ size_t SCPI_NumberToStr(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, char * str, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_UNITS_H */
+
diff --git a/third_party/libscpi/inc/scpi/utils.h b/third_party/libscpi/inc/scpi/utils.h
new file mode 100644
index 00000000..055e4683
--- /dev/null
+++ b/third_party/libscpi/inc/scpi/utils.h
@@ -0,0 +1,62 @@
+/*-
+ * BSD 2-Clause License
+ *
+ * Copyright (c) 2012-2018, 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:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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 utils.h
+ *
+ * @brief Conversion routines and string manipulation routines
+ *
+ *
+ */
+
+#ifndef SCPI_UTILS_H
+#define SCPI_UTILS_H
+
+#include <stdint.h>
+#include "scpi/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ size_t SCPI_UInt32ToStrBase(uint32_t val, char * str, size_t len, int8_t base);
+ size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len);
+ size_t SCPI_UInt64ToStrBase(uint64_t val, char * str, size_t len, int8_t base);
+ size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len);
+ size_t SCPI_FloatToStr(float val, char * str, size_t len);
+ size_t SCPI_DoubleToStr(double val, char * str, size_t len);
+
+ /* deprecated finction, should be removed later */
+#define SCPI_LongToStr(val, str, len, base) SCPI_Int32ToStr((val), (str), (len), (base), TRUE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SCPI_UTILS_H */
+