├── .github └── workflows │ └── main.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── examples ├── Makefile ├── common-cxx │ ├── scpi-def.cpp │ └── scpi-def.h ├── common │ ├── scpi-def.c │ └── scpi-def.h ├── test-CVI_w_GUI │ ├── .gitignore │ ├── TestLibSCPI_GUI.prj │ ├── TestLibscpi.h │ ├── TestLibscpi.uir │ ├── main.c │ └── scpi_user_config.h ├── test-LwIP-netconn │ ├── scpi_server.c │ └── scpi_server.h ├── test-interactive-cxx │ ├── Makefile │ └── main.cpp ├── test-interactive │ ├── Makefile │ └── main.c ├── test-parser │ ├── Makefile │ └── main.c ├── test-tcp-srq │ ├── Makefile │ └── main.c ├── test-tcp │ ├── Makefile │ └── main.c └── test-vxi11 │ ├── Makefile │ ├── main.c │ └── vxi11_xdr.c ├── library.json └── libscpi ├── Makefile ├── inc └── scpi │ ├── cc.h │ ├── config.h │ ├── constants.h │ ├── error.h │ ├── expression.h │ ├── ieee488.h │ ├── minimal.h │ ├── parser.h │ ├── scpi.h │ ├── types.h │ ├── units.h │ └── utils.h ├── src ├── error.c ├── expression.c ├── fifo.c ├── fifo_private.h ├── ieee488.c ├── lexer.c ├── lexer_private.h ├── minimal.c ├── parser.c ├── parser_private.h ├── scpi.g ├── units.c ├── utils.c └── utils_private.h └── test ├── test_fifo.c ├── test_lexer_parser.c ├── test_parser.c └── test_scpi_utils.c /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v2 9 | 10 | - name: install_dependencies 11 | run: sudo apt-get install libcunit1-dev clang 12 | 13 | - name: make 14 | run: make clean all test 15 | 16 | - name: clang_sanitize_address 17 | env: 18 | CC: clang 19 | CFLAGS: -g -O0 -fsanitize=address 20 | LDFLAGS: -g -fsanitize=address 21 | run: make clean test 22 | 23 | - name: clang_sanitize_address_device_errors 24 | env: 25 | CC: clang 26 | CFLAGS: -g -O0 -fsanitize=address -DUSE_DEVICE_DEPENDENT_ERROR_INFORMATION=0 27 | LDFLAGS: -g -fsanitize=address 28 | run: make clean test 29 | 30 | - name: clang_sanitize_address_nomalloc 31 | env: 32 | CC: clang 33 | CFLAGS: -g -O0 -fsanitize=address -DUSE_MEMORY_ALLOCATION_FREE=0 34 | LDFLAGS: -g -fsanitize=address 35 | run: make clean test 36 | 37 | - name: gcc-c89 38 | env: 39 | CFLAGS: -std=c89 40 | run: make clean all test 41 | 42 | - name: gcc-c90 43 | env: 44 | CFLAGS: -std=c90 45 | run: make clean all test 46 | 47 | - name: gcc-c99 48 | env: 49 | CFLAGS: -std=c99 50 | run: make clean all test 51 | 52 | - name: gcc-gnu99 53 | env: 54 | CFLAGS: -std=gnu99 55 | run: make clean all test 56 | 57 | build-arm: 58 | runs-on: ubuntu-latest 59 | steps: 60 | - uses: actions/checkout@v2 61 | 62 | - uses: uraimo/run-on-arch-action@v2 63 | name: Run commands 64 | id: runcmd 65 | with: 66 | arch: armv7 67 | distro: ubuntu_latest 68 | install: | 69 | apt-get update -q -y 70 | apt-get install -q -y build-essential libcunit1-dev 71 | run: make clean all test 72 | 73 | coverage: 74 | runs-on: ubuntu-latest 75 | steps: 76 | - uses: actions/checkout@v2 77 | 78 | - name: install_dependencies 79 | run: sudo apt-get install libcunit1-dev lcov 80 | 81 | - name: coverage 82 | env: 83 | CFLAGS: -fprofile-arcs -ftest-coverage 84 | CXXFLAGS: -fprofile-arcs -ftest-coverage 85 | LDFLAGS: -lgcov 86 | run: make clean all test 87 | 88 | - name: lcov_capture 89 | run: lcov --capture --directory libscpi/ --output-file lcov.info 90 | 91 | - name: lcov_cleanup 92 | run: lcov --remove lcov.info '*/test/*' --output-file lcov.info 93 | 94 | - name: Coveralls 95 | uses: coverallsapp/github-action@master 96 | with: 97 | github-token: ${{ secrets.GITHUB_TOKEN }} 98 | path-to-lcov: ./lcov.info 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VIM/KDevelop Files 2 | *.swp 3 | *.kdev4 4 | .kdev4/ 5 | *.kate-swp 6 | 7 | # Object files 8 | *.o 9 | 10 | # Libraries 11 | *.lib 12 | *.a 13 | 14 | # Shared objects (inc. Windows DLLs) 15 | *.dll 16 | *.so 17 | *.so.* 18 | *.dylib 19 | 20 | # Executables 21 | *.exe 22 | *.out 23 | *.app 24 | *.test 25 | examples/*/test 26 | 27 | # Backup files 28 | *~ 29 | /libscpi/obj/ 30 | /libscpi/dist/ 31 | 32 | /nbproject/ 33 | *.bak 34 | 35 | # Code coverage files 36 | *.gcno 37 | *.gcda 38 | *.gcov 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2012-2018, Jan Breuer 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean all test install 2 | 3 | all: 4 | $(MAKE) -C libscpi 5 | $(MAKE) -C examples 6 | 7 | clean: 8 | $(MAKE) clean -C libscpi 9 | $(MAKE) clean -C examples 10 | 11 | test: 12 | $(MAKE) test -C libscpi 13 | 14 | install: 15 | $(MAKE) install -C libscpi -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SCPI parser library v2 2 | =========== 3 | 4 | ![Build status](https://github.com/j123b567/scpi-parser/actions/workflows/main.yml/badge.svg) [![Coverage Status](https://coveralls.io/repos/j123b567/scpi-parser/badge.svg?branch=master&service=github)](https://coveralls.io/github/j123b567/scpi-parser?branch=master) 5 | 6 | Documentation 7 | -------- 8 | Documentation is available at [http://j123b567.github.io/scpi-parser](http://j123b567.github.io/scpi-parser). 9 | 10 | Examples 11 | -------- 12 | Library contains several [examples](https://github.com/j123b567/scpi-parser/tree/master/examples) of usage but please note, that this code is just for educational purpose and not production ready. 13 | Examples are from several contributors and they are not tested and it is also not known, if they really work or can compile at all. 14 | 15 | The core library itself is well tested and has more then 93% of the code covered by unit tests and integration tests and tries to be SCPI-99 compliant as much as possible. 16 | 17 | About 18 | -------- 19 | 20 | [SCPI](http://en.wikipedia.org/wiki/Standard_Commands_for_Programmable_Instruments) Parser library aims to provide parsing ability of SCPI commands on **instrument side**. All commands are defined by its patterns eg: `"STATus:QUEStionable:EVENt?"`. 21 | 22 | Source codes are published with open source BSD 2-Clause License. 23 | 24 | SCPI parser library is based on these standards 25 | 26 | * [SCPI-99](https://www.ivifoundation.org/downloads/SCPI/scpi-99.pdf) 27 | * [IEEE 488.2-2004](http://dx.doi.org/10.1109/IEEESTD.2004.95390) 28 | 29 | 30 | **SCPI version compliance** 31 | 32 | 33 |
SCPI versionv1999.0
34 | 35 | 36 | **Supported command patterns** 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
FeaturePattern example
Short and long formMEASure means MEAS or MEASURE command
Common command*CLS
Compound commandCONFigure:VOLTage
Query commandMEASure:VOLTage?, *IDN?
Optional keywordsMEASure:VOLTage[:DC]?
Numeric keyword suffix
Multiple identical capabilities
OUTput#:FREQuency
46 | 47 | **Supported parameter types** 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
TypeExample
Decimal10, 10.5
Decimal with suffix-5.5 V, 1.5 KOHM
Hexadecimal#HFF
Octal#Q77
Binary#B11
String"text", 'text'
Arbitrary block#12AB
Program expression(1)
Numeric list(1,2:50,80)
Channel list(@1!2:3!4,5!6)
Character dataMINimum, DEFault, INFinity
62 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean all cli tcp 2 | 3 | all: cli tcp 4 | 5 | cli: 6 | $(MAKE) -C test-interactive 7 | $(MAKE) -C test-interactive-cxx 8 | $(MAKE) -C test-parser 9 | 10 | tcp: 11 | $(MAKE) -C test-tcp 12 | $(MAKE) -C test-tcp-srq 13 | 14 | clean: 15 | $(MAKE) clean -C test-interactive 16 | $(MAKE) clean -C test-interactive-cxx 17 | $(MAKE) clean -C test-parser 18 | $(MAKE) clean -C test-tcp 19 | $(MAKE) clean -C test-tcp-srq 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/common-cxx/scpi-def.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __SCPI_DEF_H_ 30 | #define __SCPI_DEF_H_ 31 | 32 | 33 | #include "scpi/scpi.h" 34 | 35 | #define SCPI_INPUT_BUFFER_LENGTH 256 36 | #define SCPI_ERROR_QUEUE_SIZE 17 37 | #define SCPI_IDN1 "MANUFACTURE" 38 | #define SCPI_IDN2 "INSTR2013" 39 | #define SCPI_IDN3 NULL 40 | #define SCPI_IDN4 "01-02" 41 | 42 | extern const scpi_command_t scpi_commands[]; 43 | extern scpi_interface_t scpi_interface; 44 | extern char scpi_input_buffer[]; 45 | extern scpi_error_t scpi_error_queue_data[]; 46 | extern scpi_t scpi_context; 47 | 48 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len); 49 | int SCPI_Error(scpi_t * context, int_fast16_t err); 50 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val); 51 | scpi_result_t SCPI_Reset(scpi_t * context); 52 | scpi_result_t SCPI_Flush(scpi_t * context); 53 | 54 | 55 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context); 56 | 57 | #endif /* __SCPI_DEF_H_ */ 58 | 59 | -------------------------------------------------------------------------------- /examples/common/scpi-def.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __SCPI_DEF_H_ 30 | #define __SCPI_DEF_H_ 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #include "scpi/scpi.h" 36 | 37 | #define SCPI_INPUT_BUFFER_LENGTH 256 38 | #define SCPI_ERROR_QUEUE_SIZE 17 39 | #define SCPI_IDN1 "MANUFACTURE" 40 | #define SCPI_IDN2 "INSTR2013" 41 | #define SCPI_IDN3 NULL 42 | #define SCPI_IDN4 "01-02" 43 | 44 | extern const scpi_command_t scpi_commands[]; 45 | extern scpi_interface_t scpi_interface; 46 | extern char scpi_input_buffer[]; 47 | extern scpi_error_t scpi_error_queue_data[]; 48 | extern scpi_t scpi_context; 49 | 50 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len); 51 | int SCPI_Error(scpi_t * context, int_fast16_t err); 52 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val); 53 | scpi_result_t SCPI_Reset(scpi_t * context); 54 | scpi_result_t SCPI_Flush(scpi_t * context); 55 | 56 | 57 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | #endif /* __SCPI_DEF_H_ */ 63 | 64 | -------------------------------------------------------------------------------- /examples/test-CVI_w_GUI/.gitignore: -------------------------------------------------------------------------------- 1 | cvibuild.TestLibSCPI_GUI 2 | *.cdb 3 | *.cws 4 | -------------------------------------------------------------------------------- /examples/test-CVI_w_GUI/TestLibSCPI_GUI.prj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j123b567/scpi-parser/698eabe62eca0d9df5663a2ebb3fcab80e72d5d3/examples/test-CVI_w_GUI/TestLibSCPI_GUI.prj -------------------------------------------------------------------------------- /examples/test-CVI_w_GUI/TestLibscpi.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /* LabWindows/CVI User Interface Resource (UIR) Include File */ 3 | /* Copyright (c) National Instruments 2015. All Rights Reserved. */ 4 | /* */ 5 | /* WARNING: Do not add to, delete from, or otherwise modify the contents */ 6 | /* of this include file. */ 7 | /**************************************************************************/ 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /* Panels and Controls: */ 16 | 17 | #define PANEL 1 18 | #define PANEL_OUTPUTDEBUG 2 /* control type: textBox, callback function: (none) */ 19 | #define PANEL_OUTPUTERR 3 /* control type: textBox, callback function: (none) */ 20 | #define PANEL_OUTPUT 4 /* control type: textBox, callback function: (none) */ 21 | #define PANEL_INPUT 5 /* control type: string, callback function: cb_scpi_input */ 22 | #define PANEL_SREHEX 6 /* control type: string, callback function: (none) */ 23 | #define PANEL_SRE0 7 /* control type: radioButton, callback function: (none) */ 24 | #define PANEL_STBHEX 8 /* control type: string, callback function: (none) */ 25 | #define PANEL_SRE1 9 /* control type: radioButton, callback function: (none) */ 26 | #define PANEL_STB0 10 /* control type: radioButton, callback function: (none) */ 27 | #define PANEL_SRE2 11 /* control type: radioButton, callback function: (none) */ 28 | #define PANEL_STBTEXT0 12 /* control type: textMsg, callback function: (none) */ 29 | #define PANEL_SRE3 13 /* control type: radioButton, callback function: (none) */ 30 | #define PANEL_STB1 14 /* control type: radioButton, callback function: (none) */ 31 | #define PANEL_SRE4 15 /* control type: radioButton, callback function: (none) */ 32 | #define PANEL_STBTEXT1 16 /* control type: textMsg, callback function: (none) */ 33 | #define PANEL_SRE5 17 /* control type: radioButton, callback function: (none) */ 34 | #define PANEL_STB2 18 /* control type: radioButton, callback function: (none) */ 35 | #define PANEL_SRE6 19 /* control type: radioButton, callback function: (none) */ 36 | #define PANEL_STBTEXT2 20 /* control type: textMsg, callback function: (none) */ 37 | #define PANEL_SRE7 21 /* control type: radioButton, callback function: (none) */ 38 | #define PANEL_STB3 22 /* control type: radioButton, callback function: (none) */ 39 | #define PANEL_STBTEXT3 23 /* control type: textMsg, callback function: (none) */ 40 | #define PANEL_STB4 24 /* control type: radioButton, callback function: (none) */ 41 | #define PANEL_STBTEXT4 25 /* control type: textMsg, callback function: (none) */ 42 | #define PANEL_STB5 26 /* control type: radioButton, callback function: (none) */ 43 | #define PANEL_STBTEXT5 27 /* control type: textMsg, callback function: (none) */ 44 | #define PANEL_STB6 28 /* control type: radioButton, callback function: (none) */ 45 | #define PANEL_STBTEXT6 29 /* control type: textMsg, callback function: (none) */ 46 | #define PANEL_STB7 30 /* control type: radioButton, callback function: (none) */ 47 | #define PANEL_STBTEXT7 31 /* control type: textMsg, callback function: (none) */ 48 | #define PANEL_ESEHEX 32 /* control type: string, callback function: (none) */ 49 | #define PANEL_ESRHEX 33 /* control type: string, callback function: (none) */ 50 | #define PANEL_ESE0 34 /* control type: radioButton, callback function: (none) */ 51 | #define PANEL_ESR0 35 /* control type: radioButton, callback function: (none) */ 52 | #define PANEL_ESE1 36 /* control type: radioButton, callback function: (none) */ 53 | #define PANEL_ESRTEXT0 37 /* control type: textMsg, callback function: (none) */ 54 | #define PANEL_ESE2 38 /* control type: radioButton, callback function: (none) */ 55 | #define PANEL_ESR1 39 /* control type: radioButton, callback function: (none) */ 56 | #define PANEL_ESE3 40 /* control type: radioButton, callback function: (none) */ 57 | #define PANEL_ESRTEXT1 41 /* control type: textMsg, callback function: (none) */ 58 | #define PANEL_ESE4 42 /* control type: radioButton, callback function: (none) */ 59 | #define PANEL_ESR2 43 /* control type: radioButton, callback function: (none) */ 60 | #define PANEL_ESE5 44 /* control type: radioButton, callback function: (none) */ 61 | #define PANEL_ESRTEXT2 45 /* control type: textMsg, callback function: (none) */ 62 | #define PANEL_ESE6 46 /* control type: radioButton, callback function: (none) */ 63 | #define PANEL_ESR3 47 /* control type: radioButton, callback function: (none) */ 64 | #define PANEL_ESE7 48 /* control type: radioButton, callback function: (none) */ 65 | #define PANEL_ESRTEXT3 49 /* control type: textMsg, callback function: (none) */ 66 | #define PANEL_ESR4 50 /* control type: radioButton, callback function: (none) */ 67 | #define PANEL_ESRTEXT4 51 /* control type: textMsg, callback function: (none) */ 68 | #define PANEL_ESR5 52 /* control type: radioButton, callback function: (none) */ 69 | #define PANEL_ESRTEXT5 53 /* control type: textMsg, callback function: (none) */ 70 | #define PANEL_ESR6 54 /* control type: radioButton, callback function: (none) */ 71 | #define PANEL_ESRTEXT6 55 /* control type: textMsg, callback function: (none) */ 72 | #define PANEL_ESR7 56 /* control type: radioButton, callback function: (none) */ 73 | #define PANEL_ESRTEXT7 57 /* control type: textMsg, callback function: (none) */ 74 | #define PANEL_QUIT 58 /* control type: command, callback function: cb_quit */ 75 | #define PANEL_LEDSRQ 59 /* control type: LED, callback function: (none) */ 76 | 77 | 78 | /* Control Arrays: */ 79 | 80 | /* (no control arrays in the resource file) */ 81 | 82 | 83 | /* Menu Bars, Menus, and Menu Items: */ 84 | 85 | /* (no menu bars in the resource file) */ 86 | 87 | 88 | /* Callback Prototypes: */ 89 | 90 | int CVICALLBACK cb_quit(int panel, int control, int event, void *callbackData, int eventData1, int eventData2); 91 | int CVICALLBACK cb_scpi_input(int panel, int control, int event, void *callbackData, int eventData1, int eventData2); 92 | 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | -------------------------------------------------------------------------------- /examples/test-CVI_w_GUI/TestLibscpi.uir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j123b567/scpi-parser/698eabe62eca0d9df5663a2ebb3fcab80e72d5d3/examples/test-CVI_w_GUI/TestLibscpi.uir -------------------------------------------------------------------------------- /examples/test-CVI_w_GUI/main.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2015 Lutz Hoerl, Thorlabs GmbH 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file main.c 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief SCPI parser test with a little GUI built with NI-CVI (Lutz Hoerl, Thorlabs) 33 | * You can build this example using CVI 2012SP1, an eval version is available here: 34 | * ftp://ftp.ni.com/evaluation/labview/ekit/other/downloader/NILWCVI2012SP1.exe 35 | * Size is about 550 MB 36 | * 37 | */ 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include "scpi/scpi.h" 44 | #include "../common/scpi-def.h" 45 | 46 | /* NI-CVI specific stuff */ 47 | #include 48 | #include 49 | #include "TestLibscpi.h" /* this is the include for the GUI constants */ 50 | 51 | /* GLOBAL VARIABLES */ 52 | static int panelHandle; 53 | 54 | /* PROTOTYPES */ 55 | void gui_updateSTB(uint8_t newSTB); 56 | void gui_updateSRE(uint8_t newSTB); 57 | void gui_updateESR(uint8_t newSTB); 58 | void gui_updateESE(uint8_t newSTB); 59 | void updateSSCPIRegister(void); 60 | void updateSTB(void); 61 | void updateSRE(void); 62 | void updateESR(void); 63 | void updateESE(void); 64 | 65 | /* a global output buffer to collect output data until it will be 'flushed' */ 66 | #define SCPI_OUPUT_BUFFER_SIZE (256) 67 | char SCPI_outputBuffer[SCPI_OUPUT_BUFFER_SIZE]; 68 | unsigned int SCPI_outputBuffer_idx = 0; 69 | 70 | /* helper function to remove and from the end of a string */ 71 | /* this is needed only here for the GUI, there is a 'insert line to a text box' function */ 72 | 73 | /* that automatically adds a new line, so this prohibits double line feeds for the GUI */ 74 | void removeTrailingEndcodes(char *buf) { 75 | int len; 76 | len = strlen(buf); 77 | 78 | while (len > 0) { 79 | len--; 80 | switch (buf[len]) { 81 | case '\n': 82 | case '\r': 83 | buf[len] = '\0'; 84 | break; 85 | default: 86 | len = 0; /* stop loop */ 87 | break; 88 | } 89 | } 90 | } 91 | 92 | /* wrapper for debugging output, collects debug output until a */ 93 | 94 | /* is received, then removes the and outputs the line on the GUI */ 95 | void debug_output(char *buf) { 96 | static char pbuf[512]; 97 | static int pos = 0; 98 | int len; 99 | 100 | len = strlen(buf); 101 | if (buf[len - 1] == '\n') { 102 | buf[len - 1] == '\0'; 103 | len--; 104 | memcpy(&pbuf[pos], buf, len); 105 | pos = 0; 106 | InsertTextBoxLine(panelHandle, PANEL_OUTPUTDEBUG, -1, pbuf); 107 | } else { 108 | memcpy(&pbuf[pos], buf, len); 109 | pos += len; 110 | } 111 | 112 | } 113 | 114 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 115 | if ((SCPI_outputBuffer_idx + len) > (SCPI_OUPUT_BUFFER_SIZE - 1)) { 116 | len = (SCPI_OUPUT_BUFFER_SIZE - 1) - SCPI_outputBuffer_idx; /* limit length to left over space */ 117 | /* apparently there is no mechanism to cope with buffers that are too small */ 118 | } 119 | memcpy(&SCPI_outputBuffer[SCPI_outputBuffer_idx], data, len); 120 | SCPI_outputBuffer_idx += len; 121 | 122 | SCPI_outputBuffer[SCPI_outputBuffer_idx] = '\0'; 123 | /* return fwrite(data, 1, len, stdout); */ 124 | return len; 125 | } 126 | 127 | scpi_result_t SCPI_Flush(scpi_t * context) { 128 | /* fwrite(SCPI_outputBuffer, 1, SCPI_outputBuffer_idx, stdout); */ 129 | removeTrailingEndcodes(SCPI_outputBuffer); 130 | InsertTextBoxLine(panelHandle, PANEL_OUTPUT, -1, SCPI_outputBuffer); 131 | SCPI_outputBuffer_idx = 0; 132 | return SCPI_RES_OK; 133 | } 134 | 135 | int SCPI_Error(scpi_t * context, int_fast16_t err) { 136 | char buf[512]; 137 | 138 | /* fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int16_t) err, SCPI_ErrorTranslate(err)); */ 139 | sprintf(buf, "**ERROR: %d, \"%s\"", (int16_t) err, SCPI_ErrorTranslate(err)); 140 | InsertTextBoxLine(panelHandle, PANEL_OUTPUTERR, -1, buf); 141 | return 0; 142 | } 143 | 144 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 145 | if (SCPI_CTRL_SRQ == ctrl) { 146 | /* fprintf(stderr, "**SRQ: 0x%X (%d)\r\n", val, val); */ 147 | SetCtrlVal(panelHandle, PANEL_LEDSRQ, 1); 148 | } else { 149 | fprintf(stderr, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); 150 | } 151 | return SCPI_RES_OK; 152 | } 153 | 154 | scpi_result_t SCPI_Reset(scpi_t * context) { 155 | char buf[256]; 156 | /* fprintf(stderr, "**Reset\r\n"); */ 157 | sprintf(buf, "**Reset\r\n"); 158 | debug_output(buf); 159 | return SCPI_RES_OK; 160 | } 161 | 162 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) { 163 | return SCPI_RES_ERR; 164 | } 165 | 166 | /* 167 | * 168 | */ 169 | int main(int argc, char** argv) { 170 | int result; 171 | 172 | SCPI_Init(&scpi_context, 173 | scpi_commands, 174 | &scpi_interface, 175 | scpi_units_def, 176 | SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4, 177 | scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, 178 | scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); 179 | 180 | if (InitCVIRTE(0, argv, 0) == 0) 181 | return -1; /* out of memory */ 182 | if ((panelHandle = LoadPanel(0, "TestLibscpi.uir", PANEL)) < 0) 183 | return -1; 184 | DisplayPanel(panelHandle); 185 | 186 | updateSSCPIRegister(); 187 | 188 | RunUserInterface(); 189 | DiscardPanel(panelHandle); 190 | 191 | return (EXIT_SUCCESS); 192 | } 193 | 194 | void updateSSCPIRegister(void) { 195 | updateSTB(); 196 | updateSRE(); 197 | updateESR(); 198 | updateESE(); 199 | } 200 | 201 | void updateSTB(void) { 202 | scpi_reg_val_t regVal; 203 | 204 | regVal = SCPI_RegGet(&scpi_context, SCPI_REG_STB); 205 | 206 | gui_updateSTB((uint8_t) (0x00FF & regVal)); 207 | } 208 | 209 | void updateESR(void) { 210 | scpi_reg_val_t regVal; 211 | 212 | regVal = SCPI_RegGet(&scpi_context, SCPI_REG_ESR); 213 | 214 | gui_updateESR((uint8_t) (0x00FF & regVal)); 215 | } 216 | 217 | void updateESE(void) { 218 | scpi_reg_val_t regVal; 219 | 220 | regVal = SCPI_RegGet(&scpi_context, SCPI_REG_ESE); 221 | 222 | gui_updateESE((uint8_t) (0x00FF & regVal)); 223 | } 224 | 225 | void updateSRE(void) { 226 | scpi_reg_val_t regVal; 227 | 228 | regVal = SCPI_RegGet(&scpi_context, SCPI_REG_SRE); 229 | 230 | gui_updateSRE((uint8_t) (0x00FF & regVal)); 231 | } 232 | 233 | /* 234 | * The CALLBACK functions below are called from the CVI runtime engine when 235 | * user clicks on buttons, inputs data on the GUI etc. 236 | */ 237 | int CVICALLBACK cb_scpi_input(int panel, int control, int event, 238 | void *callbackData, int eventData1, int eventData2) { 239 | char buf[256]; 240 | int len; 241 | 242 | switch (event) { 243 | case EVENT_COMMIT: 244 | GetCtrlVal(panel, control, buf); 245 | /* we have to add a endcode to make SCPI accept the string, here a is added */ 246 | len = strlen(buf); 247 | buf[len] = '\n'; 248 | len++; 249 | SCPI_Input(&scpi_context, buf, len); 250 | 251 | updateSSCPIRegister(); 252 | break; 253 | } 254 | return 0; 255 | } 256 | 257 | int CVICALLBACK cb_quit(int panel, int control, int event, 258 | void *callbackData, int eventData1, int eventData2) { 259 | switch (event) { 260 | case EVENT_COMMIT: 261 | QuitUserInterface(0); 262 | break; 263 | } 264 | return 0; 265 | } 266 | 267 | /* 268 | * Helper functions for GUI 269 | */ 270 | void gui_updateSTB(uint8_t newSTB) { 271 | char buf[5]; 272 | 273 | sprintf(buf, "0x%02X", newSTB); 274 | SetCtrlVal(panelHandle, PANEL_STBHEX, buf); 275 | 276 | SetCtrlVal(panelHandle, PANEL_STB0, (newSTB & 0x01)); 277 | SetCtrlVal(panelHandle, PANEL_STB1, (newSTB & 0x02)); 278 | SetCtrlVal(panelHandle, PANEL_STB2, (newSTB & 0x04)); 279 | SetCtrlVal(panelHandle, PANEL_STB3, (newSTB & 0x08)); 280 | SetCtrlVal(panelHandle, PANEL_STB4, (newSTB & 0x10)); 281 | SetCtrlVal(panelHandle, PANEL_STB5, (newSTB & 0x20)); 282 | SetCtrlVal(panelHandle, PANEL_STB6, (newSTB & 0x40)); 283 | SetCtrlVal(panelHandle, PANEL_STB7, (newSTB & 0x80)); 284 | 285 | if (0x00 == (newSTB & 0x40)) SetCtrlVal(panelHandle, PANEL_LEDSRQ, 0); 286 | 287 | } 288 | 289 | void gui_updateESR(uint8_t newESR) { 290 | char buf[5]; 291 | 292 | sprintf(buf, "0x%02X", newESR); 293 | SetCtrlVal(panelHandle, PANEL_ESRHEX, buf); 294 | 295 | SetCtrlVal(panelHandle, PANEL_ESR0, (newESR & 0x01)); 296 | SetCtrlVal(panelHandle, PANEL_ESR1, (newESR & 0x02)); 297 | SetCtrlVal(panelHandle, PANEL_ESR2, (newESR & 0x04)); 298 | SetCtrlVal(panelHandle, PANEL_ESR3, (newESR & 0x08)); 299 | SetCtrlVal(panelHandle, PANEL_ESR4, (newESR & 0x10)); 300 | SetCtrlVal(panelHandle, PANEL_ESR5, (newESR & 0x20)); 301 | SetCtrlVal(panelHandle, PANEL_ESR6, (newESR & 0x40)); 302 | SetCtrlVal(panelHandle, PANEL_ESR7, (newESR & 0x80)); 303 | } 304 | 305 | void gui_updateESE(uint8_t newESE) { 306 | char buf[5]; 307 | 308 | sprintf(buf, "0x%02X", newESE); 309 | SetCtrlVal(panelHandle, PANEL_ESEHEX, buf); 310 | 311 | SetCtrlVal(panelHandle, PANEL_ESE0, (newESE & 0x01)); 312 | SetCtrlVal(panelHandle, PANEL_ESE1, (newESE & 0x02)); 313 | SetCtrlVal(panelHandle, PANEL_ESE2, (newESE & 0x04)); 314 | SetCtrlVal(panelHandle, PANEL_ESE3, (newESE & 0x08)); 315 | SetCtrlVal(panelHandle, PANEL_ESE4, (newESE & 0x10)); 316 | SetCtrlVal(panelHandle, PANEL_ESE5, (newESE & 0x20)); 317 | SetCtrlVal(panelHandle, PANEL_ESE6, (newESE & 0x40)); 318 | SetCtrlVal(panelHandle, PANEL_ESE7, (newESE & 0x80)); 319 | } 320 | 321 | void gui_updateSRE(uint8_t newSRE) { 322 | char buf[5]; 323 | 324 | sprintf(buf, "0x%02X", newSRE); 325 | SetCtrlVal(panelHandle, PANEL_SREHEX, buf); 326 | 327 | SetCtrlVal(panelHandle, PANEL_SRE0, (newSRE & 0x01)); 328 | SetCtrlVal(panelHandle, PANEL_SRE1, (newSRE & 0x02)); 329 | SetCtrlVal(panelHandle, PANEL_SRE2, (newSRE & 0x04)); 330 | SetCtrlVal(panelHandle, PANEL_SRE3, (newSRE & 0x08)); 331 | SetCtrlVal(panelHandle, PANEL_SRE4, (newSRE & 0x10)); 332 | SetCtrlVal(panelHandle, PANEL_SRE5, (newSRE & 0x20)); 333 | SetCtrlVal(panelHandle, PANEL_SRE6, (newSRE & 0x40)); 334 | SetCtrlVal(panelHandle, PANEL_SRE7, (newSRE & 0x80)); 335 | } 336 | -------------------------------------------------------------------------------- /examples/test-CVI_w_GUI/scpi_user_config.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Lutz Hoerl, Thorlabs GmbH 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_user_config.h 30 | * @date Wed Aug 05 10:00:00 UTC 2015 31 | * 32 | * @brief User resp. device dependent SCPI Configuration 33 | * 34 | * 35 | */ 36 | 37 | #ifndef __SCPI_USER_CONFIG_H_ 38 | #define __SCPI_USER_CONFIG_H_ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | #define SCPI_LINE_ENDING "\r\n" /* use carriage return + line feed as termination charcters */ 45 | 46 | #define USE_FULL_ERROR_LIST 1 47 | #define USE_USER_ERROR_LIST 1 48 | 49 | #define LIST_OF_USER_ERRORS \ 50 | X(SCPI_USER_ERROR_WARMUP_NOT_FINISHED, 101, "The device has not finished the warm up process yet") \ 51 | X(SCPI_USER_ERROR_INTERLOCK_OPEN, 102, "Switching output to on is not allowed when interlock is open") \ 52 | 53 | 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif /* #define __SCPI_USER_CONFIG_H_ */ 60 | -------------------------------------------------------------------------------- /examples/test-LwIP-netconn/scpi_server.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _SCPI_SERVER_H_ 30 | #define _SCPI_SERVER_H_ 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #define SCPI_KEEP_IDLE 2000 // (ms) keepalive quiet time after last TCP packet 36 | #define SCPI_KEEP_INTVL 1000 // (ms) keepalive repeat interval 37 | #define SCPI_KEEP_CNT 4 // Retry count before terminating connection (SCPI_KEEP_INTVL * SCPI_KEEP_INTVL (ms)). 38 | 39 | #define SCPI_DEVICE_PORT 5025 // scpi-raw standard port 40 | #define SCPI_CONTROL_PORT 5026 // libscpi control port (not part of the standard) 41 | 42 | #include 43 | #include "lwip/api.h" 44 | #include "scpi/types.h" 45 | 46 | void scpi_server_init(void); 47 | 48 | void SCPI_AddError(int16_t err); 49 | void SCPI_RequestControl(void); 50 | 51 | // optional event handlers 52 | void SCPI_Event_DeviceConnected(scpi_t * context, struct netconn * conn); 53 | void SCPI_Event_DeviceDisconnected(scpi_t * context, struct netconn * conn); 54 | void SCPI_Event_ControlConnected(scpi_t * context, struct netconn * conn); 55 | void SCPI_Event_ControlDisconnected(scpi_t * context, struct netconn * conn); 56 | void SCPI_Event_ErrorIndicatorOn(scpi_t * context, int_fast16_t err); 57 | void SCPI_Event_ErrorIndicatorOff(scpi_t * context, int_fast16_t err); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | #endif /* _SCPI_SERVER_H_ */ 63 | -------------------------------------------------------------------------------- /examples/test-interactive-cxx/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROG = test 3 | 4 | SRCS = main.cpp ../common-cxx/scpi-def.cpp 5 | CPPFLAGS += -I ../../libscpi/inc/ 6 | CXXFLAGS += -Wextra 7 | LDFLAGS += -lm ../../libscpi/dist/libscpi.a -Wl,--as-needed 8 | 9 | .PHONY: clean all 10 | 11 | all: $(PROG) 12 | 13 | OBJS = $(SRCS:.cpp=.o) 14 | 15 | %.o: %.cpp 16 | $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< 17 | 18 | $(PROG): $(OBJS) 19 | $(CXX) -o $@ $(OBJS) $(CXXFLAGS) $(LDFLAGS) 20 | 21 | clean: 22 | $(RM) $(PROG) $(OBJS) 23 | -------------------------------------------------------------------------------- /examples/test-interactive-cxx/main.cpp: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file main.c 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI parser test 34 | * 35 | * 36 | */ 37 | #include 38 | #include "scpi/scpi.h" 39 | #include "../common-cxx/scpi-def.h" 40 | 41 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 42 | (void) context; 43 | std::cout.write(data, len); 44 | return len; 45 | } 46 | 47 | scpi_result_t SCPI_Flush(scpi_t * context) { 48 | (void) context; 49 | std::cout << std::flush; 50 | return SCPI_RES_OK; 51 | } 52 | 53 | int SCPI_Error(scpi_t * context, int_fast16_t err) { 54 | (void) context; 55 | std::cerr << "**ERROR: " << err << ", \"" << SCPI_ErrorTranslate(err) << "\"" << std::endl; 56 | return 0; 57 | } 58 | 59 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 60 | (void) context; 61 | 62 | if (SCPI_CTRL_SRQ == ctrl) { 63 | std::cerr << "**SRQ: 0x" << std::hex << val << "(" << std::dec << val << ")" << std::endl; 64 | } else { 65 | std::cerr << "**CTRL: " << std::hex << ctrl << ": 0x" << std::hex << val << "(" << std::dec << val << ")" << std::endl; 66 | } 67 | return SCPI_RES_OK; 68 | } 69 | 70 | scpi_result_t SCPI_Reset(scpi_t * context) { 71 | (void) context; 72 | 73 | std::cerr << "**Reset" << std::endl; 74 | return SCPI_RES_OK; 75 | } 76 | 77 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) { 78 | (void) context; 79 | 80 | return SCPI_RES_ERR; 81 | } 82 | 83 | /* 84 | * 85 | */ 86 | int main(int argc, char** argv) { 87 | (void) argc; 88 | (void) argv; 89 | 90 | SCPI_Init(&scpi_context, 91 | scpi_commands, 92 | &scpi_interface, 93 | scpi_units_def, 94 | SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4, 95 | scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, 96 | scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); 97 | 98 | std::cerr << "SCPI Interactive demo" << std::endl; 99 | 100 | while (1) { 101 | char ch = std::cin.get(); 102 | SCPI_Input(&scpi_context, &ch, 1); 103 | } 104 | 105 | 106 | return (EXIT_SUCCESS); 107 | } 108 | 109 | -------------------------------------------------------------------------------- /examples/test-interactive/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROG = test 3 | 4 | SRCS = main.c ../common/scpi-def.c 5 | CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -I ../../libscpi/inc/ 6 | LDFLAGS += -lm ../../libscpi/dist/libscpi.a -Wl,--as-needed 7 | 8 | .PHONY: clean all 9 | 10 | all: $(PROG) 11 | 12 | OBJS = $(SRCS:.c=.o) 13 | 14 | .c.o: 15 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 16 | 17 | $(PROG): $(OBJS) 18 | $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) 19 | 20 | clean: 21 | $(RM) $(PROG) $(OBJS) 22 | -------------------------------------------------------------------------------- /examples/test-interactive/main.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file main.c 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI parser test 34 | * 35 | * 36 | */ 37 | 38 | #include 39 | #include 40 | #include 41 | #include "scpi/scpi.h" 42 | #include "../common/scpi-def.h" 43 | 44 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 45 | (void) context; 46 | return fwrite(data, 1, len, stdout); 47 | } 48 | 49 | scpi_result_t SCPI_Flush(scpi_t * context) { 50 | (void) context; 51 | return SCPI_RES_OK; 52 | } 53 | 54 | int SCPI_Error(scpi_t * context, int_fast16_t err) { 55 | (void) context; 56 | 57 | fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int16_t) err, SCPI_ErrorTranslate(err)); 58 | return 0; 59 | } 60 | 61 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 62 | (void) context; 63 | 64 | if (SCPI_CTRL_SRQ == ctrl) { 65 | fprintf(stderr, "**SRQ: 0x%X (%d)\r\n", val, val); 66 | } else { 67 | fprintf(stderr, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); 68 | } 69 | return SCPI_RES_OK; 70 | } 71 | 72 | scpi_result_t SCPI_Reset(scpi_t * context) { 73 | (void) context; 74 | 75 | fprintf(stderr, "**Reset\r\n"); 76 | return SCPI_RES_OK; 77 | } 78 | 79 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) { 80 | (void) context; 81 | 82 | return SCPI_RES_ERR; 83 | } 84 | 85 | /* 86 | * 87 | */ 88 | int main(int argc, char** argv) { 89 | (void) argc; 90 | (void) argv; 91 | 92 | SCPI_Init(&scpi_context, 93 | scpi_commands, 94 | &scpi_interface, 95 | scpi_units_def, 96 | SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4, 97 | scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, 98 | scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); 99 | 100 | /* printf("%.*s %s\r\n", 3, "asdadasdasdasdas", "b"); */ 101 | printf("SCPI Interactive demo\r\n"); 102 | char smbuffer[10]; 103 | while (1) { 104 | if (NULL == fgets(smbuffer, 10, stdin)) { 105 | break; 106 | } 107 | SCPI_Input(&scpi_context, smbuffer, strlen(smbuffer)); 108 | } 109 | 110 | 111 | return (EXIT_SUCCESS); 112 | } 113 | 114 | -------------------------------------------------------------------------------- /examples/test-parser/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROG = test 3 | 4 | SRCS = main.c ../common/scpi-def.c 5 | CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -I ../../libscpi/inc/ 6 | LDFLAGS += -lm ../../libscpi/dist/libscpi.a -Wl,--as-needed 7 | 8 | .PHONY: clean all 9 | 10 | all: $(PROG) 11 | 12 | OBJS = $(SRCS:.c=.o) 13 | 14 | .c.o: 15 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 16 | 17 | $(PROG): $(OBJS) 18 | $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) 19 | 20 | clean: 21 | $(RM) $(PROG) $(OBJS) 22 | -------------------------------------------------------------------------------- /examples/test-parser/main.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file main.c 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI parser test 34 | * 35 | * 36 | */ 37 | 38 | #include 39 | #include 40 | #include 41 | #include "scpi/scpi.h" 42 | #include "../common/scpi-def.h" 43 | 44 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 45 | (void) context; 46 | return fwrite(data, 1, len, stdout); 47 | } 48 | 49 | scpi_result_t SCPI_Flush(scpi_t * context) { 50 | (void) context; 51 | 52 | return SCPI_RES_OK; 53 | } 54 | 55 | int SCPI_Error(scpi_t * context, int_fast16_t err) { 56 | (void) context; 57 | 58 | fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int16_t) err, SCPI_ErrorTranslate(err)); 59 | return 0; 60 | } 61 | 62 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 63 | (void) context; 64 | 65 | if (SCPI_CTRL_SRQ == ctrl) { 66 | fprintf(stderr, "**SRQ: 0x%X (%d)\r\n", val, val); 67 | } else { 68 | fprintf(stderr, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); 69 | } 70 | return SCPI_RES_OK; 71 | } 72 | 73 | scpi_result_t SCPI_Reset(scpi_t * context) { 74 | (void) context; 75 | 76 | fprintf(stderr, "**Reset\r\n"); 77 | return SCPI_RES_OK; 78 | } 79 | 80 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) { 81 | (void) context; 82 | 83 | return SCPI_RES_ERR; 84 | } 85 | 86 | /* 87 | * 88 | */ 89 | int main(int argc, char** argv) { 90 | (void) argc; 91 | (void) argv; 92 | int result; 93 | 94 | SCPI_Init(&scpi_context, 95 | scpi_commands, 96 | &scpi_interface, 97 | scpi_units_def, 98 | SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4, 99 | scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, 100 | scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); 101 | 102 | #define TEST_SCPI_INPUT(cmd) result = SCPI_Input(&scpi_context, cmd, strlen(cmd)) 103 | 104 | TEST_SCPI_INPUT("*CLS\r\n"); 105 | TEST_SCPI_INPUT("*RST\r\n"); 106 | TEST_SCPI_INPUT("MEAS:volt:DC? 12,50;*OPC\r\n"); 107 | TEST_SCPI_INPUT("*IDN?\r\n"); 108 | TEST_SCPI_INPUT("SYST:VERS?"); 109 | TEST_SCPI_INPUT("\r\n*ID"); 110 | TEST_SCPI_INPUT("N?"); 111 | TEST_SCPI_INPUT(""); /* emulate command timeout */ 112 | 113 | TEST_SCPI_INPUT("*ESE\r\n"); /* cause error -109, missing parameter */ 114 | TEST_SCPI_INPUT("*ESE #H20\r\n"); 115 | 116 | TEST_SCPI_INPUT("*SRE #HFF\r\n"); 117 | 118 | TEST_SCPI_INPUT("IDN?\r\n"); /* cause error -113, undefined header */ 119 | 120 | TEST_SCPI_INPUT("SYST:ERR?\r\n"); 121 | TEST_SCPI_INPUT("SYST:ERR?\r\n"); 122 | TEST_SCPI_INPUT("*STB?\r\n"); 123 | TEST_SCPI_INPUT("*ESR?\r\n"); 124 | TEST_SCPI_INPUT("*STB?\r\n"); 125 | 126 | TEST_SCPI_INPUT("meas:volt:dc? 0.01 V, Default\r\n"); 127 | TEST_SCPI_INPUT("meas:volt:dc?\r\n"); 128 | TEST_SCPI_INPUT("meas:volt:dc? def, 0.00001\r\n"); 129 | TEST_SCPI_INPUT("meas:volt:dc? 0.00001\r\n"); 130 | 131 | TEST_SCPI_INPUT("test:text 'a'\r\n"); 132 | TEST_SCPI_INPUT("test:text 'a a'\r\n"); 133 | TEST_SCPI_INPUT("test:text 'aa a'\r\n"); 134 | TEST_SCPI_INPUT("test:text 'aaa aaaa'\r\n"); 135 | TEST_SCPI_INPUT("TEST:CHANnellist (@9!2:3!4,5!6)\r\n"); 136 | /* printf("%.*s %s\r\n", 3, "asdadasdasdasdas", "b"); 137 | * interactive demo 138 | * char smbuffer[10]; 139 | * while (1) { 140 | * fgets(smbuffer, 10, stdin); 141 | * SCPI_Input(&scpi_context, smbuffer, strlen(smbuffer)); 142 | * } 143 | */ 144 | 145 | 146 | return (EXIT_SUCCESS); 147 | } 148 | 149 | -------------------------------------------------------------------------------- /examples/test-tcp-srq/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROG = test 3 | 4 | SRCS = main.c ../common/scpi-def.c 5 | CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -I ../../libscpi/inc/ 6 | LDFLAGS += -lm ../../libscpi/dist/libscpi.a -Wl,--as-needed 7 | 8 | .PHONY: clean all 9 | 10 | all: $(PROG) 11 | 12 | OBJS = $(SRCS:.c=.o) 13 | 14 | .c.o: 15 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 16 | 17 | $(PROG): $(OBJS) 18 | $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) 19 | 20 | clean: 21 | $(RM) $(PROG) $(OBJS) 22 | -------------------------------------------------------------------------------- /examples/test-tcp-srq/main.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file main.c 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief TCP/IP SCPI Server 34 | * 35 | * 36 | */ 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include "scpi/scpi.h" 51 | #include "../common/scpi-def.h" 52 | 53 | #define CONTROL_PORT 5026 54 | 55 | typedef struct { 56 | int io; 57 | int io_listen; 58 | int control_io; 59 | int control_io_listen; 60 | FILE * fio; 61 | fd_set fds; 62 | } user_data_t; 63 | 64 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 65 | if (context->user_context != NULL) { 66 | user_data_t * u = (user_data_t *) (context->user_context); 67 | if (u->fio) { 68 | return fwrite(data, 1, len, u->fio); 69 | } 70 | } 71 | return 0; 72 | } 73 | 74 | scpi_result_t SCPI_Flush(scpi_t * context) { 75 | if (context->user_context != NULL) { 76 | user_data_t * u = (user_data_t *) (context->user_context); 77 | if (u->fio) { 78 | return fflush(u->fio) == 0 ? SCPI_RES_OK : SCPI_RES_ERR; 79 | } 80 | } 81 | return SCPI_RES_OK; 82 | } 83 | 84 | int SCPI_Error(scpi_t * context, int_fast16_t err) { 85 | (void) context; 86 | /* BEEP */ 87 | fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int16_t) err, SCPI_ErrorTranslate(err)); 88 | return 0; 89 | } 90 | 91 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 92 | char b[16]; 93 | 94 | if (SCPI_CTRL_SRQ == ctrl) { 95 | fprintf(stderr, "**SRQ: 0x%X (%d)\r\n", val, val); 96 | } else { 97 | fprintf(stderr, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); 98 | } 99 | 100 | if (context->user_context != NULL) { 101 | user_data_t * u = (user_data_t *) (context->user_context); 102 | if (u->control_io >= 0) { 103 | sprintf(b, "SRQ%d\r\n", val); 104 | return write(u->control_io, b, strlen(b)) > 0 ? SCPI_RES_OK : SCPI_RES_ERR; 105 | } 106 | } 107 | return SCPI_RES_OK; 108 | } 109 | 110 | scpi_result_t SCPI_Reset(scpi_t * context) { 111 | (void) context; 112 | 113 | fprintf(stderr, "**Reset\r\n"); 114 | return SCPI_RES_OK; 115 | } 116 | 117 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) { 118 | SCPI_ResultInt32(context, CONTROL_PORT); 119 | return SCPI_RES_OK; 120 | } 121 | 122 | static int createServer(int port) { 123 | int fd; 124 | int rc; 125 | int on = 1; 126 | struct sockaddr_in servaddr; 127 | 128 | /* Configure TCP Server */ 129 | memset(&servaddr, 0, sizeof (servaddr)); 130 | servaddr.sin_family = AF_INET; 131 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 132 | servaddr.sin_port = htons(port); 133 | 134 | /* Create socket */ 135 | fd = socket(AF_INET, SOCK_STREAM, 0); 136 | if (fd < 0) { 137 | perror("socket() failed"); 138 | exit(-1); 139 | } 140 | 141 | /* Set address reuse enable */ 142 | rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)); 143 | if (rc < 0) { 144 | perror("setsockopt() failed"); 145 | close(fd); 146 | exit(-1); 147 | } 148 | 149 | /* Set non blocking */ 150 | rc = ioctl(fd, FIONBIO, (char *) &on); 151 | if (rc < 0) { 152 | perror("ioctl() failed"); 153 | close(fd); 154 | exit(-1); 155 | } 156 | 157 | /* Bind to socket */ 158 | rc = bind(fd, (struct sockaddr *) &servaddr, sizeof (servaddr)); 159 | if (rc < 0) { 160 | perror("bind() failed"); 161 | close(fd); 162 | exit(-1); 163 | } 164 | 165 | /* Listen on socket */ 166 | listen(fd, 1); 167 | if (rc < 0) { 168 | perror("listen() failed"); 169 | close(fd); 170 | exit(-1); 171 | } 172 | 173 | return fd; 174 | } 175 | 176 | static int waitServer(user_data_t * user_data) { 177 | struct timeval timeout; 178 | int rc; 179 | 180 | FD_ZERO(&user_data->fds); 181 | 182 | if (user_data->io >= 0) { 183 | FD_SET(user_data->io, &user_data->fds); 184 | } 185 | 186 | if (user_data->io_listen >= 0) { 187 | FD_SET(user_data->io_listen, &user_data->fds); 188 | } 189 | 190 | if (user_data->control_io >= 0) { 191 | FD_SET(user_data->control_io, &user_data->fds); 192 | } 193 | 194 | if (user_data->control_io_listen >= 0) { 195 | FD_SET(user_data->control_io_listen, &user_data->fds); 196 | } 197 | 198 | timeout.tv_sec = 5; 199 | timeout.tv_usec = 0; 200 | 201 | rc = select(FD_SETSIZE, &user_data->fds, NULL, NULL, &timeout); 202 | 203 | return rc; 204 | } 205 | 206 | static void processIoListen(user_data_t * user_data) { 207 | struct sockaddr_in cliaddr; 208 | socklen_t clilen; 209 | clilen = sizeof (cliaddr); 210 | 211 | user_data->io = accept(user_data->io_listen, (struct sockaddr *) &cliaddr, &clilen); 212 | user_data->fio = fdopen(user_data->io, "r+"); 213 | 214 | printf("Connection established %s\r\n", inet_ntoa(cliaddr.sin_addr)); 215 | } 216 | 217 | static void processSrqIoListen(user_data_t * user_data) { 218 | struct sockaddr_in cliaddr; 219 | socklen_t clilen; 220 | clilen = sizeof (cliaddr); 221 | 222 | user_data->control_io = accept(user_data->control_io_listen, (struct sockaddr *) &cliaddr, &clilen); 223 | printf("Control Connection established %s\r\n", inet_ntoa(cliaddr.sin_addr)); 224 | } 225 | 226 | static void closeIo(user_data_t * user_data) { 227 | fclose(user_data->fio); 228 | user_data->fio = NULL; 229 | user_data->io = -1; 230 | } 231 | 232 | static void closeSrqIo(user_data_t * user_data) { 233 | close(user_data->control_io); 234 | user_data->control_io = -1; 235 | } 236 | 237 | static void processIo(user_data_t * user_data) { 238 | int rc; 239 | char smbuffer[10]; 240 | rc = recv(user_data->io, smbuffer, sizeof (smbuffer), 0); 241 | if (rc < 0) { 242 | if (errno != EWOULDBLOCK) { 243 | closeIo(user_data); 244 | perror(" recv() failed"); 245 | } 246 | } else if (rc == 0) { 247 | closeIo(user_data); 248 | printf("Connection closed\r\n"); 249 | } else { 250 | SCPI_Input(&scpi_context, smbuffer, rc); 251 | } 252 | } 253 | 254 | static void processSrqIo(user_data_t * user_data) { 255 | int rc; 256 | char smbuffer[10]; 257 | rc = recv(user_data->control_io, smbuffer, sizeof (smbuffer), 0); 258 | if (rc < 0) { 259 | if (errno != EWOULDBLOCK) { 260 | closeSrqIo(user_data); 261 | perror(" recv() failed"); 262 | } 263 | } else if (rc == 0) { 264 | closeSrqIo(user_data); 265 | printf("Control Connection closed\r\n"); 266 | } else { 267 | /* nothing to do */ 268 | } 269 | } 270 | 271 | /* 272 | * 273 | */ 274 | int main(int argc, char** argv) { 275 | (void) argc; 276 | (void) argv; 277 | int rc; 278 | 279 | #ifdef __cplusplus 280 | user_data_t user_data = { 281 | /*.io_listen =*/ -1, 282 | /*.io =*/ -1, 283 | /*.control_io_listen =*/ -1, 284 | /*.control_io =*/ -1, 285 | /*.fio =*/ NULL, 286 | /*.fds =*/ 0, 287 | }; 288 | #else 289 | user_data_t user_data = { 290 | .io_listen = -1, 291 | .io = -1, 292 | .control_io_listen = -1, 293 | .control_io = -1, 294 | .fio = NULL, 295 | }; 296 | #endif 297 | 298 | /* user_context will be pointer to socket */ 299 | SCPI_Init(&scpi_context, 300 | scpi_commands, 301 | &scpi_interface, 302 | scpi_units_def, 303 | SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4, 304 | scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, 305 | scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); 306 | scpi_context.user_context = &user_data; 307 | 308 | user_data.io_listen = createServer(5025); 309 | user_data.control_io_listen = createServer(CONTROL_PORT); 310 | 311 | while (1) { 312 | rc = waitServer(&user_data); 313 | 314 | if (rc < 0) { /* failed */ 315 | perror("select failed"); 316 | exit(-1); 317 | } 318 | 319 | if (rc == 0) { /* timeout */ 320 | SCPI_Input(&scpi_context, NULL, 0); 321 | } 322 | 323 | if ((user_data.io_listen >= 0) && FD_ISSET(user_data.io_listen, &user_data.fds)) { 324 | processIoListen(&user_data); 325 | } 326 | 327 | if ((user_data.control_io_listen >= 0) && FD_ISSET(user_data.control_io_listen, &user_data.fds)) { 328 | processSrqIoListen(&user_data); 329 | } 330 | 331 | if ((user_data.io >= 0) && FD_ISSET(user_data.io, &user_data.fds)) { 332 | processIo(&user_data); 333 | } 334 | 335 | if ((user_data.control_io >= 0) && FD_ISSET(user_data.control_io, &user_data.fds)) { 336 | processSrqIo(&user_data); 337 | } 338 | 339 | } 340 | 341 | return (EXIT_SUCCESS); 342 | } 343 | 344 | -------------------------------------------------------------------------------- /examples/test-tcp/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROG = test 3 | 4 | SRCS = main.c ../common/scpi-def.c 5 | CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -I ../../libscpi/inc/ 6 | LDFLAGS += -lm ../../libscpi/dist/libscpi.a -Wl,--as-needed 7 | 8 | .PHONY: clean all 9 | 10 | all: $(PROG) 11 | 12 | OBJS = $(SRCS:.c=.o) 13 | 14 | .c.o: 15 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 16 | 17 | $(PROG): $(OBJS) 18 | $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) 19 | 20 | clean: 21 | $(RM) $(PROG) $(OBJS) 22 | -------------------------------------------------------------------------------- /examples/test-tcp/main.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | /** 29 | * @file main.c 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief TCP/IP SCPI Server 33 | * 34 | * 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include "scpi/scpi.h" 51 | #include "../common/scpi-def.h" 52 | 53 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 54 | if (context->user_context != NULL) { 55 | int fd = *(int *) (context->user_context); 56 | 57 | int state = 1; 58 | setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); 59 | 60 | return write(fd, data, len); 61 | } 62 | return 0; 63 | } 64 | 65 | scpi_result_t SCPI_Flush(scpi_t * context) { 66 | if (context->user_context != NULL) { 67 | int fd = *(int *) (context->user_context); 68 | 69 | int state = 0; 70 | setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); 71 | } 72 | 73 | return SCPI_RES_OK; 74 | } 75 | 76 | int SCPI_Error(scpi_t * context, int_fast16_t err) { 77 | (void) context; 78 | /* BEEP */ 79 | fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int16_t) err, SCPI_ErrorTranslate(err)); 80 | return 0; 81 | } 82 | 83 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 84 | (void) context; 85 | 86 | if (SCPI_CTRL_SRQ == ctrl) { 87 | fprintf(stderr, "**SRQ: 0x%X (%d)\r\n", val, val); 88 | } else { 89 | fprintf(stderr, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); 90 | } 91 | return SCPI_RES_OK; 92 | } 93 | 94 | scpi_result_t SCPI_Reset(scpi_t * context) { 95 | (void) context; 96 | 97 | fprintf(stderr, "**Reset\r\n"); 98 | return SCPI_RES_OK; 99 | } 100 | 101 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) { 102 | (void) context; 103 | 104 | return SCPI_RES_ERR; 105 | } 106 | 107 | static int createServer(int port) { 108 | int fd; 109 | int rc; 110 | int on = 1; 111 | struct sockaddr_in servaddr; 112 | 113 | /* Configure TCP Server */ 114 | memset(&servaddr, 0, sizeof (servaddr)); 115 | servaddr.sin_family = AF_INET; 116 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 117 | servaddr.sin_port = htons(port); 118 | 119 | /* Create socket */ 120 | fd = socket(AF_INET, SOCK_STREAM, 0); 121 | if (fd < 0) { 122 | perror("socket() failed"); 123 | exit(-1); 124 | } 125 | 126 | /* Set address reuse enable */ 127 | rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)); 128 | if (rc < 0) { 129 | perror("setsockopt() failed"); 130 | close(fd); 131 | exit(-1); 132 | } 133 | 134 | /* Set non blocking */ 135 | rc = ioctl(fd, FIONBIO, (char *) &on); 136 | if (rc < 0) { 137 | perror("ioctl() failed"); 138 | close(fd); 139 | exit(-1); 140 | } 141 | 142 | /* Bind to socket */ 143 | rc = bind(fd, (struct sockaddr *) &servaddr, sizeof (servaddr)); 144 | if (rc < 0) { 145 | perror("bind() failed"); 146 | close(fd); 147 | exit(-1); 148 | } 149 | 150 | /* Listen on socket */ 151 | listen(fd, 1); 152 | if (rc < 0) { 153 | perror("listen() failed"); 154 | close(fd); 155 | exit(-1); 156 | } 157 | 158 | return fd; 159 | } 160 | 161 | static int waitServer(int fd) { 162 | fd_set fds; 163 | struct timeval timeout; 164 | int rc; 165 | int max_fd; 166 | 167 | FD_ZERO(&fds); 168 | max_fd = fd; 169 | FD_SET(fd, &fds); 170 | 171 | timeout.tv_sec = 5; 172 | timeout.tv_usec = 0; 173 | 174 | rc = select(max_fd + 1, &fds, NULL, NULL, &timeout); 175 | 176 | return rc; 177 | } 178 | 179 | /* 180 | * 181 | */ 182 | int main(int argc, char** argv) { 183 | (void) argc; 184 | (void) argv; 185 | int rc; 186 | 187 | int listenfd; 188 | char smbuffer[10]; 189 | 190 | /* user_context will be pointer to socket */ 191 | scpi_context.user_context = NULL; 192 | 193 | SCPI_Init(&scpi_context, 194 | scpi_commands, 195 | &scpi_interface, 196 | scpi_units_def, 197 | SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4, 198 | scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, 199 | scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); 200 | 201 | listenfd = createServer(5025); 202 | 203 | while (1) { 204 | int clifd, flag = 1; 205 | struct sockaddr_in cliaddr; 206 | socklen_t clilen; 207 | 208 | clilen = sizeof (cliaddr); 209 | clifd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen); 210 | 211 | if (clifd < 0) continue; 212 | 213 | setsockopt(clifd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)); 214 | 215 | printf("Connection established %s\r\n", inet_ntoa(cliaddr.sin_addr)); 216 | 217 | scpi_context.user_context = &clifd; 218 | 219 | while (1) { 220 | rc = waitServer(clifd); 221 | if (rc < 0) { /* failed */ 222 | perror(" recv() failed"); 223 | break; 224 | } 225 | if (rc == 0) { /* timeout */ 226 | SCPI_Input(&scpi_context, NULL, 0); 227 | } 228 | if (rc > 0) { /* something to read */ 229 | rc = recv(clifd, smbuffer, sizeof (smbuffer), 0); 230 | if (rc < 0) { 231 | if (errno != EWOULDBLOCK) { 232 | perror(" recv() failed"); 233 | break; 234 | } 235 | } else if (rc == 0) { 236 | printf("Connection closed\r\n"); 237 | break; 238 | } else { 239 | SCPI_Input(&scpi_context, smbuffer, rc); 240 | } 241 | } 242 | } 243 | 244 | close(clifd); 245 | } 246 | 247 | return (EXIT_SUCCESS); 248 | } 249 | 250 | -------------------------------------------------------------------------------- /examples/test-vxi11/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROG = test 3 | 4 | SRCS = main.c vxi11_xdr.c ../common/scpi-def.c 5 | CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -I ../../libscpi/inc/ -I /usr/include/tirpc 6 | LDFLAGS += -lm -ltirpc ../../libscpi/dist/libscpi.a -Wl,--as-needed 7 | 8 | .PHONY: clean all 9 | 10 | all: $(PROG) 11 | 12 | OBJS = $(SRCS:.c=.o) 13 | 14 | .c.o: 15 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 16 | 17 | $(PROG): $(OBJS) 18 | $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) 19 | 20 | clean: 21 | $(RM) $(PROG) $(OBJS) 22 | -------------------------------------------------------------------------------- /examples/test-vxi11/vxi11_xdr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file. 3 | * It was generated using rpcgen. 4 | */ 5 | 6 | #include "vxi11.h" 7 | 8 | bool_t 9 | xdr_Device_Link (XDR *xdrs, Device_Link *objp) 10 | { 11 | register int32_t *buf; 12 | 13 | if (!xdr_long (xdrs, objp)) 14 | return FALSE; 15 | return TRUE; 16 | } 17 | 18 | bool_t 19 | xdr_Device_AddrFamily (XDR *xdrs, Device_AddrFamily *objp) 20 | { 21 | register int32_t *buf; 22 | 23 | if (!xdr_enum (xdrs, (enum_t *) objp)) 24 | return FALSE; 25 | return TRUE; 26 | } 27 | 28 | bool_t 29 | xdr_Device_Flags (XDR *xdrs, Device_Flags *objp) 30 | { 31 | register int32_t *buf; 32 | 33 | if (!xdr_long (xdrs, objp)) 34 | return FALSE; 35 | return TRUE; 36 | } 37 | 38 | bool_t 39 | xdr_Device_ErrorCode (XDR *xdrs, Device_ErrorCode *objp) 40 | { 41 | register int32_t *buf; 42 | 43 | if (!xdr_long (xdrs, objp)) 44 | return FALSE; 45 | return TRUE; 46 | } 47 | 48 | bool_t 49 | xdr_Device_Error (XDR *xdrs, Device_Error *objp) 50 | { 51 | register int32_t *buf; 52 | 53 | if (!xdr_Device_ErrorCode (xdrs, &objp->error)) 54 | return FALSE; 55 | return TRUE; 56 | } 57 | 58 | bool_t 59 | xdr_Create_LinkParms (XDR *xdrs, Create_LinkParms *objp) 60 | { 61 | register int32_t *buf; 62 | 63 | 64 | if (xdrs->x_op == XDR_ENCODE) { 65 | buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); 66 | if (buf == NULL) { 67 | if (!xdr_long (xdrs, &objp->clientId)) 68 | return FALSE; 69 | if (!xdr_bool (xdrs, &objp->lockDevice)) 70 | return FALSE; 71 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 72 | return FALSE; 73 | 74 | } else { 75 | IXDR_PUT_LONG(buf, objp->clientId); 76 | IXDR_PUT_BOOL(buf, objp->lockDevice); 77 | IXDR_PUT_U_LONG(buf, objp->lock_timeout); 78 | } 79 | if (!xdr_string (xdrs, &objp->device, ~0)) 80 | return FALSE; 81 | return TRUE; 82 | } else if (xdrs->x_op == XDR_DECODE) { 83 | buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); 84 | if (buf == NULL) { 85 | if (!xdr_long (xdrs, &objp->clientId)) 86 | return FALSE; 87 | if (!xdr_bool (xdrs, &objp->lockDevice)) 88 | return FALSE; 89 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 90 | return FALSE; 91 | 92 | } else { 93 | objp->clientId = IXDR_GET_LONG(buf); 94 | objp->lockDevice = IXDR_GET_BOOL(buf); 95 | objp->lock_timeout = IXDR_GET_U_LONG(buf); 96 | } 97 | if (!xdr_string (xdrs, &objp->device, ~0)) 98 | return FALSE; 99 | return TRUE; 100 | } 101 | 102 | if (!xdr_long (xdrs, &objp->clientId)) 103 | return FALSE; 104 | if (!xdr_bool (xdrs, &objp->lockDevice)) 105 | return FALSE; 106 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 107 | return FALSE; 108 | if (!xdr_string (xdrs, &objp->device, ~0)) 109 | return FALSE; 110 | return TRUE; 111 | } 112 | 113 | bool_t 114 | xdr_Create_LinkResp (XDR *xdrs, Create_LinkResp *objp) 115 | { 116 | register int32_t *buf; 117 | 118 | if (!xdr_Device_ErrorCode (xdrs, &objp->error)) 119 | return FALSE; 120 | if (!xdr_Device_Link (xdrs, &objp->lid)) 121 | return FALSE; 122 | if (!xdr_u_short (xdrs, &objp->abortPort)) 123 | return FALSE; 124 | if (!xdr_u_long (xdrs, &objp->maxRecvSize)) 125 | return FALSE; 126 | return TRUE; 127 | } 128 | 129 | bool_t 130 | xdr_Device_WriteParms (XDR *xdrs, Device_WriteParms *objp) 131 | { 132 | register int32_t *buf; 133 | 134 | if (!xdr_Device_Link (xdrs, &objp->lid)) 135 | return FALSE; 136 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 137 | return FALSE; 138 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 139 | return FALSE; 140 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 141 | return FALSE; 142 | if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) 143 | return FALSE; 144 | return TRUE; 145 | } 146 | 147 | bool_t 148 | xdr_Device_WriteResp (XDR *xdrs, Device_WriteResp *objp) 149 | { 150 | register int32_t *buf; 151 | 152 | if (!xdr_Device_ErrorCode (xdrs, &objp->error)) 153 | return FALSE; 154 | if (!xdr_u_long (xdrs, &objp->size)) 155 | return FALSE; 156 | return TRUE; 157 | } 158 | 159 | bool_t 160 | xdr_Device_ReadParms (XDR *xdrs, Device_ReadParms *objp) 161 | { 162 | register int32_t *buf; 163 | 164 | 165 | if (xdrs->x_op == XDR_ENCODE) { 166 | if (!xdr_Device_Link (xdrs, &objp->lid)) 167 | return FALSE; 168 | buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); 169 | if (buf == NULL) { 170 | if (!xdr_u_long (xdrs, &objp->requestSize)) 171 | return FALSE; 172 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 173 | return FALSE; 174 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 175 | return FALSE; 176 | 177 | } else { 178 | IXDR_PUT_U_LONG(buf, objp->requestSize); 179 | IXDR_PUT_U_LONG(buf, objp->io_timeout); 180 | IXDR_PUT_U_LONG(buf, objp->lock_timeout); 181 | } 182 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 183 | return FALSE; 184 | if (!xdr_char (xdrs, &objp->termChar)) 185 | return FALSE; 186 | return TRUE; 187 | } else if (xdrs->x_op == XDR_DECODE) { 188 | if (!xdr_Device_Link (xdrs, &objp->lid)) 189 | return FALSE; 190 | buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); 191 | if (buf == NULL) { 192 | if (!xdr_u_long (xdrs, &objp->requestSize)) 193 | return FALSE; 194 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 195 | return FALSE; 196 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 197 | return FALSE; 198 | 199 | } else { 200 | objp->requestSize = IXDR_GET_U_LONG(buf); 201 | objp->io_timeout = IXDR_GET_U_LONG(buf); 202 | objp->lock_timeout = IXDR_GET_U_LONG(buf); 203 | } 204 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 205 | return FALSE; 206 | if (!xdr_char (xdrs, &objp->termChar)) 207 | return FALSE; 208 | return TRUE; 209 | } 210 | 211 | if (!xdr_Device_Link (xdrs, &objp->lid)) 212 | return FALSE; 213 | if (!xdr_u_long (xdrs, &objp->requestSize)) 214 | return FALSE; 215 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 216 | return FALSE; 217 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 218 | return FALSE; 219 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 220 | return FALSE; 221 | if (!xdr_char (xdrs, &objp->termChar)) 222 | return FALSE; 223 | return TRUE; 224 | } 225 | 226 | bool_t 227 | xdr_Device_ReadResp (XDR *xdrs, Device_ReadResp *objp) 228 | { 229 | register int32_t *buf; 230 | 231 | if (!xdr_Device_ErrorCode (xdrs, &objp->error)) 232 | return FALSE; 233 | if (!xdr_long (xdrs, &objp->reason)) 234 | return FALSE; 235 | if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) 236 | return FALSE; 237 | return TRUE; 238 | } 239 | 240 | bool_t 241 | xdr_Device_ReadStbResp (XDR *xdrs, Device_ReadStbResp *objp) 242 | { 243 | register int32_t *buf; 244 | 245 | if (!xdr_Device_ErrorCode (xdrs, &objp->error)) 246 | return FALSE; 247 | if (!xdr_u_char (xdrs, &objp->stb)) 248 | return FALSE; 249 | return TRUE; 250 | } 251 | 252 | bool_t 253 | xdr_Device_GenericParms (XDR *xdrs, Device_GenericParms *objp) 254 | { 255 | register int32_t *buf; 256 | 257 | if (!xdr_Device_Link (xdrs, &objp->lid)) 258 | return FALSE; 259 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 260 | return FALSE; 261 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 262 | return FALSE; 263 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 264 | return FALSE; 265 | return TRUE; 266 | } 267 | 268 | bool_t 269 | xdr_Device_RemoteFunc (XDR *xdrs, Device_RemoteFunc *objp) 270 | { 271 | register int32_t *buf; 272 | 273 | 274 | if (xdrs->x_op == XDR_ENCODE) { 275 | buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); 276 | if (buf == NULL) { 277 | if (!xdr_u_long (xdrs, &objp->hostAddr)) 278 | return FALSE; 279 | if (!xdr_u_long (xdrs, &objp->hostPort)) 280 | return FALSE; 281 | if (!xdr_u_long (xdrs, &objp->progNum)) 282 | return FALSE; 283 | if (!xdr_u_long (xdrs, &objp->progVers)) 284 | return FALSE; 285 | 286 | } else { 287 | IXDR_PUT_U_LONG(buf, objp->hostAddr); 288 | IXDR_PUT_U_LONG(buf, objp->hostPort); 289 | IXDR_PUT_U_LONG(buf, objp->progNum); 290 | IXDR_PUT_U_LONG(buf, objp->progVers); 291 | } 292 | if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) 293 | return FALSE; 294 | return TRUE; 295 | } else if (xdrs->x_op == XDR_DECODE) { 296 | buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); 297 | if (buf == NULL) { 298 | if (!xdr_u_long (xdrs, &objp->hostAddr)) 299 | return FALSE; 300 | if (!xdr_u_long (xdrs, &objp->hostPort)) 301 | return FALSE; 302 | if (!xdr_u_long (xdrs, &objp->progNum)) 303 | return FALSE; 304 | if (!xdr_u_long (xdrs, &objp->progVers)) 305 | return FALSE; 306 | 307 | } else { 308 | objp->hostAddr = IXDR_GET_U_LONG(buf); 309 | objp->hostPort = IXDR_GET_U_LONG(buf); 310 | objp->progNum = IXDR_GET_U_LONG(buf); 311 | objp->progVers = IXDR_GET_U_LONG(buf); 312 | } 313 | if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) 314 | return FALSE; 315 | return TRUE; 316 | } 317 | 318 | if (!xdr_u_long (xdrs, &objp->hostAddr)) 319 | return FALSE; 320 | if (!xdr_u_long (xdrs, &objp->hostPort)) 321 | return FALSE; 322 | if (!xdr_u_long (xdrs, &objp->progNum)) 323 | return FALSE; 324 | if (!xdr_u_long (xdrs, &objp->progVers)) 325 | return FALSE; 326 | if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) 327 | return FALSE; 328 | return TRUE; 329 | } 330 | 331 | bool_t 332 | xdr_Device_EnableSrqParms (XDR *xdrs, Device_EnableSrqParms *objp) 333 | { 334 | register int32_t *buf; 335 | 336 | if (!xdr_Device_Link (xdrs, &objp->lid)) 337 | return FALSE; 338 | if (!xdr_bool (xdrs, &objp->enable)) 339 | return FALSE; 340 | if (!xdr_bytes (xdrs, (char **)&objp->handle.handle_val, (u_int *) &objp->handle.handle_len, 40)) 341 | return FALSE; 342 | return TRUE; 343 | } 344 | 345 | bool_t 346 | xdr_Device_LockParms (XDR *xdrs, Device_LockParms *objp) 347 | { 348 | register int32_t *buf; 349 | 350 | if (!xdr_Device_Link (xdrs, &objp->lid)) 351 | return FALSE; 352 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 353 | return FALSE; 354 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 355 | return FALSE; 356 | return TRUE; 357 | } 358 | 359 | bool_t 360 | xdr_Device_DocmdParms (XDR *xdrs, Device_DocmdParms *objp) 361 | { 362 | register int32_t *buf; 363 | 364 | 365 | if (xdrs->x_op == XDR_ENCODE) { 366 | if (!xdr_Device_Link (xdrs, &objp->lid)) 367 | return FALSE; 368 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 369 | return FALSE; 370 | buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); 371 | if (buf == NULL) { 372 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 373 | return FALSE; 374 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 375 | return FALSE; 376 | if (!xdr_long (xdrs, &objp->cmd)) 377 | return FALSE; 378 | if (!xdr_bool (xdrs, &objp->network_order)) 379 | return FALSE; 380 | if (!xdr_long (xdrs, &objp->datasize)) 381 | return FALSE; 382 | 383 | } else { 384 | IXDR_PUT_U_LONG(buf, objp->io_timeout); 385 | IXDR_PUT_U_LONG(buf, objp->lock_timeout); 386 | IXDR_PUT_LONG(buf, objp->cmd); 387 | IXDR_PUT_BOOL(buf, objp->network_order); 388 | IXDR_PUT_LONG(buf, objp->datasize); 389 | } 390 | if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) 391 | return FALSE; 392 | return TRUE; 393 | } else if (xdrs->x_op == XDR_DECODE) { 394 | if (!xdr_Device_Link (xdrs, &objp->lid)) 395 | return FALSE; 396 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 397 | return FALSE; 398 | buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); 399 | if (buf == NULL) { 400 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 401 | return FALSE; 402 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 403 | return FALSE; 404 | if (!xdr_long (xdrs, &objp->cmd)) 405 | return FALSE; 406 | if (!xdr_bool (xdrs, &objp->network_order)) 407 | return FALSE; 408 | if (!xdr_long (xdrs, &objp->datasize)) 409 | return FALSE; 410 | 411 | } else { 412 | objp->io_timeout = IXDR_GET_U_LONG(buf); 413 | objp->lock_timeout = IXDR_GET_U_LONG(buf); 414 | objp->cmd = IXDR_GET_LONG(buf); 415 | objp->network_order = IXDR_GET_BOOL(buf); 416 | objp->datasize = IXDR_GET_LONG(buf); 417 | } 418 | if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) 419 | return FALSE; 420 | return TRUE; 421 | } 422 | 423 | if (!xdr_Device_Link (xdrs, &objp->lid)) 424 | return FALSE; 425 | if (!xdr_Device_Flags (xdrs, &objp->flags)) 426 | return FALSE; 427 | if (!xdr_u_long (xdrs, &objp->io_timeout)) 428 | return FALSE; 429 | if (!xdr_u_long (xdrs, &objp->lock_timeout)) 430 | return FALSE; 431 | if (!xdr_long (xdrs, &objp->cmd)) 432 | return FALSE; 433 | if (!xdr_bool (xdrs, &objp->network_order)) 434 | return FALSE; 435 | if (!xdr_long (xdrs, &objp->datasize)) 436 | return FALSE; 437 | if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) 438 | return FALSE; 439 | return TRUE; 440 | } 441 | 442 | bool_t 443 | xdr_Device_DocmdResp (XDR *xdrs, Device_DocmdResp *objp) 444 | { 445 | register int32_t *buf; 446 | 447 | if (!xdr_Device_ErrorCode (xdrs, &objp->error)) 448 | return FALSE; 449 | if (!xdr_bytes (xdrs, (char **)&objp->data_out.data_out_val, (u_int *) &objp->data_out.data_out_len, ~0)) 450 | return FALSE; 451 | return TRUE; 452 | } 453 | 454 | bool_t 455 | xdr_Device_SrqParms (XDR *xdrs, Device_SrqParms *objp) 456 | { 457 | register int32_t *buf; 458 | 459 | if (!xdr_bytes (xdrs, (char **)&objp->handle.handle_val, (u_int *) &objp->handle.handle_len, ~0)) 460 | return FALSE; 461 | return TRUE; 462 | } 463 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scpi-parser", 3 | "keywords": "scpi", 4 | "version": "2.4-pre", 5 | "description": "Open Source SCPI device library", 6 | "license": "BSD-2-Clause", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/j123b567/scpi-parser.git" 10 | }, 11 | "authors": { 12 | "name": "Jan Breuer", 13 | "email": "jan.breuer@jaybee.cz" 14 | }, 15 | "build": { 16 | "includeDir": "libscpi/inc", 17 | "srcDir": "libscpi/src" 18 | }, 19 | "examples": [ 20 | "examples/test-interactive/main.c" 21 | ], 22 | "frameworks": "*", 23 | "platforms": "*" 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libscpi/Makefile: -------------------------------------------------------------------------------- 1 | VERSION = 2.1.0 2 | LIBNAME = scpi 3 | 4 | CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -Iinc 5 | CFLAGS_SHARED += $(CFLAGS) -fPIC 6 | LDFLAGS += -lm -Wl,--as-needed 7 | #TESTCFLAGS += $(CFLAGS) `pkg-config --cflags cunit` 8 | #TESTLDFLAGS += $(LDFLAGS) `pkg-config --libs cunit` 9 | TESTCFLAGS += $(CFLAGS) 10 | TESTLDFLAGS += $(LDFLAGS) -lcunit 11 | 12 | OBJDIR=obj 13 | OBJDIR_STATIC=$(OBJDIR)/static 14 | OBJDIR_SHARED=$(OBJDIR)/shared 15 | DISTDIR=dist 16 | TESTDIR=test 17 | 18 | PREFIX := $(DESTDIR)/usr/local 19 | LIBDIR := $(PREFIX)/lib 20 | INCDIR := $(PREFIX)/include 21 | 22 | STATICLIBFLAGS = rcs 23 | SHAREDLIBFLAGS = $(LDFLAGS) -shared -Wl,-soname,$(SHAREDLIB) 24 | 25 | STATICLIB = lib$(LIBNAME).a 26 | SHAREDLIB = lib$(LIBNAME).so 27 | SHAREDLIBVER = $(SHAREDLIB).$(VERSION) 28 | 29 | SRCS = $(addprefix src/, \ 30 | error.c fifo.c ieee488.c \ 31 | minimal.c parser.c units.c utils.c \ 32 | lexer.c expression.c \ 33 | ) 34 | 35 | OBJS_STATIC = $(addprefix $(OBJDIR_STATIC)/, $(notdir $(SRCS:.c=.o))) 36 | OBJS_SHARED = $(addprefix $(OBJDIR_SHARED)/, $(notdir $(SRCS:.c=.o))) 37 | 38 | HDRS = $(addprefix inc/scpi/, \ 39 | scpi.h constants.h error.h \ 40 | ieee488.h minimal.h parser.h types.h units.h \ 41 | expression.h \ 42 | ) \ 43 | $(addprefix src/, \ 44 | lexer_private.h utils_private.h fifo_private.h \ 45 | parser_private.h \ 46 | ) \ 47 | 48 | 49 | TESTS = $(addprefix $(TESTDIR)/, \ 50 | test_fifo.c test_scpi_utils.c test_lexer_parser.c test_parser.c\ 51 | ) 52 | 53 | TESTS_OBJS = $(TESTS:.c=.o) 54 | TESTS_BINS = $(TESTS_OBJS:.o=.test) 55 | 56 | .PHONY: all clean static shared test install 57 | 58 | all: static shared 59 | 60 | static: $(DISTDIR)/$(STATICLIB) 61 | 62 | shared: $(DISTDIR)/$(SHAREDLIBVER) 63 | 64 | clean: 65 | $(RM) -r $(OBJDIR) $(DISTDIR) $(TESTS_BINS) $(TESTS_OBJS) 66 | 67 | test: $(TESTS_BINS) 68 | $(TESTS_BINS:.test=.test &&) true 69 | 70 | install: $(DISTDIR)/$(STATICLIB) $(DISTDIR)/$(SHAREDLIBVER) 71 | test -d $(PREFIX) || mkdir $(PREFIX) 72 | test -d $(LIBDIR) || mkdir $(LIBDIR) 73 | test -d $(INCDIR) || mkdir $(INCDIR) 74 | test -d $(INCDIR)/scpi || mkdir $(INCDIR)/scpi 75 | install -m 0644 $(DISTDIR)/$(STATICLIB) $(LIBDIR) 76 | install -m 0644 $(DISTDIR)/$(SHAREDLIBVER) $(LIBDIR) 77 | install -m 0644 inc/scpi/*.h $(INCDIR)/scpi 78 | 79 | $(OBJDIR_STATIC): 80 | mkdir -p $@ 81 | 82 | $(OBJDIR_SHARED): 83 | mkdir -p $@ 84 | 85 | $(DISTDIR): 86 | mkdir -p $@ 87 | 88 | $(OBJDIR_STATIC)/%.o: src/%.c $(HDRS) | $(OBJDIR_STATIC) 89 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 90 | 91 | $(OBJDIR_SHARED)/%.o: src/%.c $(HDRS) | $(OBJDIR_SHARED) 92 | $(CC) -c $(CFLAGS_SHARED) $(CPPFLAGS) -o $@ $< 93 | 94 | $(DISTDIR)/$(STATICLIB): $(OBJS_STATIC) | $(DISTDIR) 95 | $(AR) $(STATICLIBFLAGS) $(DISTDIR)/$(STATICLIB) $(OBJS_STATIC) 96 | 97 | $(DISTDIR)/$(SHAREDLIBVER): $(OBJS_SHARED) | $(DISTDIR) 98 | $(CC) $(SHAREDLIBFLAGS) -o $(DISTDIR)/$(SHAREDLIBVER) $(OBJS_SHARED) 99 | 100 | $(TESTDIR)/%.o: $(TESTDIR)/%.c 101 | $(CC) -c $(TESTCFLAGS) $(CPPFLAGS) -o $@ $< 102 | 103 | $(TESTDIR)/%.test: $(TESTDIR)/%.o $(DISTDIR)/$(STATICLIB) 104 | $(CC) $< -o $@ $(DISTDIR)/$(STATICLIB) $(TESTLDFLAGS) 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/cc.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file cc.h 31 | * 32 | * @brief compiler detection 33 | * 34 | * 35 | */ 36 | 37 | #ifndef __SCPI_CC_H_ 38 | #define __SCPI_CC_H_ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | #if defined(__STDC__) 45 | # define C89 1 46 | # if defined(__STDC_VERSION__) 47 | # define C90 1 48 | # if (__STDC_VERSION__ >= 199409L) 49 | # define C94 1 50 | # endif 51 | # if (__STDC_VERSION__ >= 199901L) 52 | # define C99 1 53 | # endif 54 | # endif 55 | #endif 56 | 57 | #if defined(__cplusplus) 58 | # if (__cplusplus >= 199711) 59 | # define CXX98 1 60 | # endif 61 | #endif 62 | 63 | #if (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200809L) || \ 64 | (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 700) 65 | #define HAVE_STRNDUP 1 66 | #define HAVE_STRNLEN 1 67 | #endif 68 | 69 | #if (defined _BSD_SOURCE && _BSD_SOURCE) || \ 70 | (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 500) || \ 71 | (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ 72 | (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \ 73 | C99 74 | #define HAVE_SNPRINTF 1 75 | #endif 76 | 77 | #if (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) 78 | #define HAVE_STRNCASECMP 1 79 | #endif 80 | 81 | #if (defined _BSD_SOURCE && _BSD_SOURCE) || \ 82 | (defined _SVID_SOURCE && _SVID_SOURCE) || \ 83 | (defined _XOPEN_SOURCE && _XOPEN_SOURCE) || \ 84 | (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ 85 | (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) ||\ 86 | C99 87 | #define HAVE_ISNAN 1 88 | #endif 89 | 90 | #if (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 600)|| \ 91 | (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ 92 | (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \ 93 | C99 94 | #define HAVE_ISFINITE 1 95 | #define HAVE_SIGNBIT 1 96 | #endif 97 | 98 | #if (defined _XOPEN_SOURCE && XOPEN_SOURCE >= 600) || \ 99 | (defined _BSD_SOURCE && _BSD_SOURCE) || \ 100 | (defined _SVID_SOURCE && _SVID_SOURCE) || \ 101 | (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ 102 | (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) 103 | #define HAVE_STRTOLL 1 104 | #endif 105 | 106 | #if (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 600) || \ 107 | (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ 108 | (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \ 109 | C99 110 | #define HAVE_STRTOF 1 111 | #endif 112 | 113 | #if (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || C99 || CXX98 114 | #define HAVE_STDBOOL 1 115 | #endif 116 | 117 | /* Compiler specific */ 118 | /* RealView/Keil ARM Compiler, e.g. Cortex-M CPUs */ 119 | #if defined(__CC_ARM) 120 | #define HAVE_STRNCASECMP 1 121 | #endif 122 | 123 | /* National Instruments (R) CVI x86/x64 PC platform */ 124 | #if defined(_CVI_) 125 | #define HAVE_STRNICMP 1 126 | #endif 127 | 128 | /* 8bit PIC - PIC16, etc */ 129 | #if defined(_MPC_) 130 | #define HAVE_STRNICMP 1 131 | #endif 132 | 133 | /* PIC24 */ 134 | #if defined(__C30__) 135 | #endif 136 | 137 | /* PIC32mx */ 138 | #if defined(__C32__) 139 | #define HAVE_FINITE 1 140 | #endif 141 | 142 | /* AVR libc */ 143 | #if defined(__AVR__) 144 | #include 145 | #define HAVE_DTOSTRE 1 146 | #undef HAVE_STRTOF 147 | #define HAVE_STRTOF 0 148 | #endif 149 | 150 | /* default values */ 151 | #ifndef HAVE_STRNLEN 152 | #define HAVE_STRNLEN 0 153 | #endif 154 | 155 | #ifndef HAVE_STRDUP 156 | #define HAVE_STRDUP 0 157 | #endif 158 | 159 | #ifndef HAVE_STRNDUP 160 | #define HAVE_STRNDUP 0 161 | #endif 162 | 163 | #ifndef HAVE_STRNICMP 164 | #define HAVE_STRNICMP 0 165 | #endif 166 | 167 | #ifndef HAVE_STDBOOL 168 | #define HAVE_STDBOOL 0 169 | #endif 170 | 171 | #ifndef HAVE_SNPRINTF 172 | #define HAVE_SNPRINTF 0 173 | #endif 174 | 175 | #ifndef HAVE_STRNCASECMP 176 | #define HAVE_STRNCASECMP 0 177 | #endif 178 | 179 | #ifndef HAVE_ISNAN 180 | #define HAVE_ISNAN 0 181 | #endif 182 | 183 | #ifndef HAVE_ISFINITE 184 | #define HAVE_ISFINITE 0 185 | #endif 186 | 187 | #ifndef HAVE_FINITE 188 | #define HAVE_FINITE 0 189 | #endif 190 | 191 | #ifndef HAVE_SIGNBIT 192 | #define HAVE_SIGNBIT 0 193 | #endif 194 | 195 | #ifndef HAVE_STRTOLL 196 | #define HAVE_STRTOLL 0 197 | #endif 198 | 199 | #ifndef HAVE_STRTOF 200 | #define HAVE_STRTOF 0 201 | #endif 202 | 203 | #ifndef HAVE_DTOSTRE 204 | #define HAVE_DTOSTRE 0 205 | #endif 206 | 207 | #ifdef __cplusplus 208 | } 209 | #endif 210 | 211 | #endif /* __SCPI_CC_H_ */ 212 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/config.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file config.h 31 | * @date Wed Mar 20 12:21:26 UTC 2013 32 | * 33 | * @brief SCPI Configuration 34 | * 35 | * 36 | */ 37 | 38 | #ifndef __SCPI_CONFIG_H_ 39 | #define __SCPI_CONFIG_H_ 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | #include "cc.h" 46 | 47 | #ifdef SCPI_USER_CONFIG 48 | #include "scpi_user_config.h" 49 | #endif 50 | 51 | /* set the termination character(s) */ 52 | #define LINE_ENDING_CR "\r" /* use a carriage return as termination charcter */ 53 | #define LINE_ENDING_LF "\n" /* use a line feed as termination charcter */ 54 | #define LINE_ENDING_CRLF "\r\n" /* use carriage return + line feed as termination charcters */ 55 | 56 | #ifndef SCPI_LINE_ENDING 57 | #define SCPI_LINE_ENDING LINE_ENDING_CRLF 58 | #endif 59 | 60 | #ifndef USE_CUSTOM_REGISTERS 61 | #define USE_CUSTOM_REGISTERS 0 62 | #endif 63 | 64 | /** 65 | * Detect, if it has limited resources or it is running on a full blown operating system. 66 | * All values can be overiden by scpi_user_config.h 67 | */ 68 | #define SYSTEM_BARE_METAL 0 69 | #define SYSTEM_FULL_BLOWN 1 70 | 71 | /* This should cover all windows compilers (msvc, mingw, cvi) and all Linux/OSX/BSD and other UNIX compatible systems (gcc, clang) */ 72 | #if defined(_WIN32) || defined(_WIN64) || defined(__unix) || defined(__unix__) || defined(__APPLE__) 73 | #define SYSTEM_TYPE SYSTEM_FULL_BLOWN 74 | #else 75 | #define SYSTEM_TYPE SYSTEM_BARE_METAL 76 | #endif 77 | 78 | /** 79 | * Enable full error list 80 | * 0 = Minimal set of errors 81 | * 1 = Full set of errors 82 | * 83 | * For small systems, full set of errors will occupy large ammount of data 84 | * It is enabled by default on full blown systems and disabled on limited bare metal systems 85 | */ 86 | #ifndef USE_FULL_ERROR_LIST 87 | #define USE_FULL_ERROR_LIST SYSTEM_TYPE 88 | #endif 89 | 90 | /** 91 | * Enable also LIST_OF_USER_ERRORS to be included 92 | * 0 = Use only library defined errors 93 | * 1 = Use also LIST_OF_USER_ERRORS 94 | */ 95 | #ifndef USE_USER_ERROR_LIST 96 | #define USE_USER_ERROR_LIST 0 97 | #endif 98 | 99 | #ifndef USE_DEVICE_DEPENDENT_ERROR_INFORMATION 100 | #define USE_DEVICE_DEPENDENT_ERROR_INFORMATION SYSTEM_TYPE 101 | #endif 102 | 103 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 104 | #ifndef USE_MEMORY_ALLOCATION_FREE 105 | #define USE_MEMORY_ALLOCATION_FREE 1 106 | #endif 107 | #else 108 | #ifndef USE_MEMORY_ALLOCATION_FREE 109 | #define USE_MEMORY_ALLOCATION_FREE 0 110 | #endif 111 | #endif 112 | 113 | #ifndef USE_COMMAND_TAGS 114 | #define USE_COMMAND_TAGS 1 115 | #endif 116 | 117 | #ifndef USE_DEPRECATED_FUNCTIONS 118 | #define USE_DEPRECATED_FUNCTIONS 1 119 | #endif 120 | 121 | #ifndef USE_CUSTOM_DTOSTRE 122 | #define USE_CUSTOM_DTOSTRE 0 123 | #endif 124 | 125 | #ifndef USE_UNITS_IMPERIAL 126 | #define USE_UNITS_IMPERIAL 0 127 | #endif 128 | 129 | #ifndef USE_UNITS_ANGLE 130 | #define USE_UNITS_ANGLE SYSTEM_TYPE 131 | #endif 132 | 133 | #ifndef USE_UNITS_PARTICLES 134 | #define USE_UNITS_PARTICLES SYSTEM_TYPE 135 | #endif 136 | 137 | #ifndef USE_UNITS_DISTANCE 138 | #define USE_UNITS_DISTANCE SYSTEM_TYPE 139 | #endif 140 | 141 | #ifndef USE_UNITS_MAGNETIC 142 | #define USE_UNITS_MAGNETIC SYSTEM_TYPE 143 | #endif 144 | 145 | #ifndef USE_UNITS_LIGHT 146 | #define USE_UNITS_LIGHT SYSTEM_TYPE 147 | #endif 148 | 149 | #ifndef USE_UNITS_ENERGY_FORCE_MASS 150 | #define USE_UNITS_ENERGY_FORCE_MASS SYSTEM_TYPE 151 | #endif 152 | 153 | #ifndef USE_UNITS_TIME 154 | #define USE_UNITS_TIME SYSTEM_TYPE 155 | #endif 156 | 157 | #ifndef USE_UNITS_TEMPERATURE 158 | #define USE_UNITS_TEMPERATURE SYSTEM_TYPE 159 | #endif 160 | 161 | #ifndef USE_UNITS_RATIO 162 | #define USE_UNITS_RATIO SYSTEM_TYPE 163 | #endif 164 | 165 | #ifndef USE_UNITS_POWER 166 | #define USE_UNITS_POWER 1 167 | #endif 168 | 169 | #ifndef USE_UNITS_FREQUENCY 170 | #define USE_UNITS_FREQUENCY 1 171 | #endif 172 | 173 | #ifndef USE_UNITS_ELECTRIC 174 | #define USE_UNITS_ELECTRIC 1 175 | #endif 176 | 177 | #ifndef USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE 178 | #define USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE SYSTEM_TYPE 179 | #endif 180 | 181 | /* define local macros depending on existance of strnlen */ 182 | #if HAVE_STRNLEN 183 | #define SCPIDEFINE_strnlen(s, l) strnlen((s), (l)) 184 | #else 185 | #define SCPIDEFINE_strnlen(s, l) BSD_strnlen((s), (l)) 186 | #endif 187 | 188 | /* define local macros depending on existance of strncasecmp and strnicmp */ 189 | #if HAVE_STRNCASECMP 190 | #define SCPIDEFINE_strncasecmp(s1, s2, l) strncasecmp((s1), (s2), (l)) 191 | #elif HAVE_STRNICMP 192 | #define SCPIDEFINE_strncasecmp(s1, s2, l) strnicmp((s1), (s2), (l)) 193 | #else 194 | #define SCPIDEFINE_strncasecmp(s1, s2, l) OUR_strncasecmp((s1), (s2), (l)) 195 | #endif 196 | 197 | #if HAVE_DTOSTRE 198 | #define SCPIDEFINE_floatToStr(v, s, l) dtostre((double)(v), (s), 6, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE) 199 | #elif USE_CUSTOM_DTOSTRE 200 | #define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0) 201 | #elif HAVE_SNPRINTF 202 | #define SCPIDEFINE_floatToStr(v, s, l) snprintf((s), (l), "%g", (v)) 203 | #else 204 | #define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0) 205 | #endif 206 | 207 | #if HAVE_DTOSTRE 208 | #define SCPIDEFINE_doubleToStr(v, s, l) dtostre((v), (s), 15, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE) 209 | #elif USE_CUSTOM_DTOSTRE 210 | #define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0) 211 | #elif HAVE_SNPRINTF 212 | #define SCPIDEFINE_doubleToStr(v, s, l) snprintf((s), (l), "%.15lg", (v)) 213 | #else 214 | #define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0) 215 | #endif 216 | 217 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 218 | 219 | #if USE_MEMORY_ALLOCATION_FREE 220 | #include 221 | #include 222 | #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 2 223 | #if HAVE_STRNDUP 224 | #define SCPIDEFINE_strndup(h, s, l) strndup((s), (l)) 225 | #else 226 | #define SCPIDEFINE_strndup(h, s, l) OUR_strndup((s), (l)) 227 | #endif 228 | #define SCPIDEFINE_free(h, s, r) free((s)) 229 | #else 230 | #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 3 231 | #define SCPIDEFINE_strndup(h, s, l) scpiheap_strndup((h), (s), (l)) 232 | #define SCPIDEFINE_free(h, s, r) scpiheap_free((h), (s), (r)) 233 | #define SCPIDEFINE_get_parts(h, s, l1, s2, l2) scpiheap_get_parts((h), (s), (l1), (s2), (l2)) 234 | #endif 235 | #else 236 | #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 1 237 | #define SCPIDEFINE_strndup(h, s, l) NULL 238 | #define SCPIDEFINE_free(h, s, r) 239 | #endif 240 | 241 | #if HAVE_SIGNBIT 242 | #define SCPIDEFINE_signbit(n) signbit(n) 243 | #else 244 | #define SCPIDEFINE_signbit(n) ((n)<0) 245 | #endif 246 | 247 | #if HAVE_FINITE 248 | #define SCPIDEFINE_isfinite(n) finite(n) 249 | #elif HAVE_ISFINITE 250 | #define SCPIDEFINE_isfinite(n) isfinite(n) 251 | #else 252 | #define SCPIDEFINE_isfinite(n) (!SCPIDEFINE_isnan((n)) && ((n) < INFINITY) && ((n) > -INFINITY)) 253 | #endif 254 | 255 | #if HAVE_STRTOF 256 | #define SCPIDEFINE_strtof(n, p) strtof((n), (p)) 257 | #else 258 | #define SCPIDEFINE_strtof(n, p) strtod((n), (p)) 259 | #endif 260 | 261 | #if HAVE_STRTOLL 262 | #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b)) 263 | #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b)) 264 | #else 265 | #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b)) 266 | #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b)) 267 | extern long long int strtoll(const char *nptr, char **endptr, int base); 268 | extern unsigned long long int strtoull(const char *nptr, char **endptr, int base); 269 | /* TODO: implement OUR_strtoll and OUR_strtoull */ 270 | /* #warning "64bit string to int conversion not implemented" */ 271 | #endif 272 | 273 | #if HAVE_ISNAN 274 | #define SCPIDEFINE_isnan(n) isnan((n)) 275 | #else 276 | #define SCPIDEFINE_isnan(n) ((n) != (n)) 277 | #endif 278 | 279 | #ifndef NAN 280 | #define NAN (0.0 / 0.0) 281 | #endif 282 | 283 | #ifndef INFINITY 284 | #define INFINITY (1.0 / 0.0) 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif 292 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/constants.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_constants.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI Device constants 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_CONSTANTS_H 39 | #define SCPI_CONSTANTS_H 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | /* 21.21 :VERSion? 46 | * YYYY.V 47 | * YYYY = SCPI year 48 | * V = SCPI revision 49 | */ 50 | #define SCPI_STD_VERSION_REVISION "1999.0" 51 | 52 | /* 21.8 :ERRor Subsystem 53 | * The maximum string length of plus is 255 characters. 54 | */ 55 | #define SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH 255 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* SCPI_CONSTANTS_H */ 62 | 63 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/expression.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file expression.h 31 | * 32 | * @brief Expressions handling 33 | * 34 | * 35 | */ 36 | #ifndef SCPI_EXPRESSION_H 37 | #define SCPI_EXPRESSION_H 38 | 39 | #include "scpi/config.h" 40 | #include "scpi/types.h" 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | enum _scpi_expr_result_t { 47 | SCPI_EXPR_OK = 0, 48 | SCPI_EXPR_ERROR, 49 | SCPI_EXPR_NO_MORE, 50 | }; 51 | typedef enum _scpi_expr_result_t scpi_expr_result_t; 52 | 53 | 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); 54 | 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); 55 | scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo); 56 | 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); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif /* SCPI_EXPRESSION_H */ 63 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/ieee488.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_ieee488.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief Implementation of IEEE488.2 commands and state model 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_IEEE488_H 39 | #define SCPI_IEEE488_H 40 | 41 | #include "scpi/types.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | scpi_result_t SCPI_CoreCls(scpi_t * context); 48 | scpi_result_t SCPI_CoreEse(scpi_t * context); 49 | scpi_result_t SCPI_CoreEseQ(scpi_t * context); 50 | scpi_result_t SCPI_CoreEsrQ(scpi_t * context); 51 | scpi_result_t SCPI_CoreIdnQ(scpi_t * context); 52 | scpi_result_t SCPI_CoreOpc(scpi_t * context); 53 | scpi_result_t SCPI_CoreOpcQ(scpi_t * context); 54 | scpi_result_t SCPI_CoreRst(scpi_t * context); 55 | scpi_result_t SCPI_CoreSre(scpi_t * context); 56 | scpi_result_t SCPI_CoreSreQ(scpi_t * context); 57 | scpi_result_t SCPI_CoreStbQ(scpi_t * context); 58 | scpi_result_t SCPI_CoreTstQ(scpi_t * context); 59 | scpi_result_t SCPI_CoreWai(scpi_t * context); 60 | 61 | 62 | #define STB_R01 0x01 /* Not used */ 63 | #define STB_PRO 0x02 /* Protection Event Flag */ 64 | #define STB_QMA 0x04 /* Error/Event queue message available */ 65 | #define STB_QES 0x08 /* Questionable status */ 66 | #define STB_MAV 0x10 /* Message Available */ 67 | #define STB_ESR 0x20 /* Standard Event Status Register */ 68 | #define STB_SRQ 0x40 /* Service Request */ 69 | #define STB_OPS 0x80 /* Operation Status Flag */ 70 | 71 | 72 | #define ESR_OPC 0x01 /* Operation complete */ 73 | #define ESR_REQ 0x02 /* Request Control */ 74 | #define ESR_QER 0x04 /* Query Error */ 75 | #define ESR_DER 0x08 /* Device Dependent Error */ 76 | #define ESR_EER 0x10 /* Execution Error (e.g. range error) */ 77 | #define ESR_CER 0x20 /* Command error (e.g. syntax error) */ 78 | #define ESR_URQ 0x40 /* User Request */ 79 | #define ESR_PON 0x80 /* Power On */ 80 | 81 | 82 | scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name); 83 | void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val); 84 | void SCPI_RegSetBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits); 85 | void SCPI_RegClearBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits); 86 | 87 | void SCPI_EventClear(scpi_t * context); 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif 92 | 93 | #endif /* SCPI_IEEE488_H */ 94 | 95 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/minimal.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_minimal.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI minimal implementation 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_MINIMAL_H 39 | #define SCPI_MINIMAL_H 40 | 41 | #include "scpi/types.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | scpi_result_t SCPI_Stub(scpi_t * context); 48 | scpi_result_t SCPI_StubQ(scpi_t * context); 49 | 50 | scpi_result_t SCPI_SystemVersionQ(scpi_t * context); 51 | scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context); 52 | scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context); 53 | scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context); 54 | scpi_result_t SCPI_StatusQuestionableConditionQ(scpi_t * context); 55 | scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context); 56 | scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context); 57 | scpi_result_t SCPI_StatusOperationConditionQ(scpi_t * context); 58 | scpi_result_t SCPI_StatusOperationEventQ(scpi_t * context); 59 | scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context); 60 | scpi_result_t SCPI_StatusOperationEnable(scpi_t * context); 61 | scpi_result_t SCPI_StatusPreset(scpi_t * context); 62 | 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif /* SCPI_MINIMAL_H */ 69 | 70 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/parser.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_parser.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI parser implementation 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_PARSER_H 39 | #define SCPI_PARSER_H 40 | 41 | #include 42 | #include "scpi/types.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | void SCPI_Init(scpi_t * context, 48 | const scpi_command_t * commands, 49 | scpi_interface_t * interface, 50 | const scpi_unit_def_t * units, 51 | const char * idn1, const char * idn2, const char * idn3, const char * idn4, 52 | char * input_buffer, size_t input_buffer_length, 53 | scpi_error_t * error_queue_data, int16_t error_queue_size); 54 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE 55 | void SCPI_InitHeap(scpi_t * context, char * error_info_heap, size_t error_info_heap_length); 56 | #endif 57 | 58 | scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len); 59 | scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len); 60 | 61 | size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len); 62 | #define SCPI_ResultMnemonic(context, data) SCPI_ResultCharacters((context), (data), strlen(data)) 63 | #define SCPI_ResultUInt8Base(c, v, b) SCPI_ResultUInt32Base((c), (v), (uint8_t)(b)) 64 | #define SCPI_ResultUInt8(c, v) SCPI_ResultUInt32Base((c), (uint8_t)(v), 10) 65 | #define SCPI_ResultInt8(c, v) SCPI_ResultInt32((c), (int8_t)(v)) 66 | #define SCPI_ResultUInt16Base(c, v, b) SCPI_ResultUInt32Base((c), (uint16_t)(v), (b)) 67 | #define SCPI_ResultUInt16(c, v) SCPI_ResultUInt32Base((c), (uint16_t)(v), 10) 68 | #define SCPI_ResultInt16(c, v) SCPI_ResultInt32((c), (int16_t)(v)) 69 | size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base); 70 | #define SCPI_ResultUInt32(c, v) SCPI_ResultUInt32Base((c), (v), 10) 71 | size_t SCPI_ResultInt32(scpi_t * context, int32_t val); 72 | size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base); 73 | #define SCPI_ResultUInt64(c, v) SCPI_ResultUInt64Base((c), (v), 10) 74 | size_t SCPI_ResultInt64(scpi_t * context, int64_t val); 75 | size_t SCPI_ResultFloat(scpi_t * context, float val); 76 | size_t SCPI_ResultDouble(scpi_t * context, double val); 77 | size_t SCPI_ResultText(scpi_t * context, const char * data); 78 | size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error); 79 | size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len); 80 | size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len); 81 | size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len); 82 | size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val); 83 | 84 | size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format); 85 | size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format); 86 | size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format); 87 | size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format); 88 | size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format); 89 | size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format); 90 | size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format); 91 | size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format); 92 | size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format); 93 | size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format); 94 | 95 | scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory); 96 | scpi_bool_t SCPI_ParamIsValid(scpi_parameter_t * parameter); 97 | scpi_bool_t SCPI_ParamErrorOccurred(scpi_t * context); 98 | scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed); 99 | scpi_bool_t SCPI_ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value); 100 | scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value); 101 | scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value); 102 | scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value); 103 | scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value); 104 | scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value); 105 | scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value); 106 | scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text); 107 | 108 | scpi_bool_t SCPI_ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory); 109 | scpi_bool_t SCPI_ParamUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory); 110 | scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory); 111 | scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory); 112 | scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory); 113 | scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory); 114 | scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); 115 | scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); 116 | scpi_bool_t SCPI_ParamCopyText(scpi_t * context, char * buffer, size_t buffer_len, size_t * copy_len, scpi_bool_t mandatory); 117 | 118 | extern const scpi_choice_def_t scpi_bool_def[]; 119 | scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory); 120 | scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory); 121 | 122 | 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); 123 | 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); 124 | 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); 125 | 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); 126 | 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); 127 | 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); 128 | 129 | scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd); 130 | #if USE_COMMAND_TAGS 131 | int32_t SCPI_CmdTag(scpi_t * context); 132 | #endif /* USE_COMMAND_TAGS */ 133 | scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len); 134 | scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value); 135 | 136 | #if USE_DEPRECATED_FUNCTIONS 137 | /* deprecated finction, should be removed later */ 138 | #define SCPI_ResultIntBase(context, val, base) SCPI_ResultInt32Base ((context), (val), (base), TRUE) 139 | #define SCPI_ResultInt(context, val) SCPI_ResultInt32 ((context), (val)) 140 | #define SCPI_ParamToInt(context, parameter, value) SCPI_ParamToInt32((context), (parameter), (value)) 141 | #define SCPI_ParamToUnsignedInt(context, parameter, value) SCPI_ParamToUInt32((context), (parameter), (value)) 142 | #define SCPI_ParamInt(context, value, mandatory) SCPI_ParamInt32((context), (value), (mandatory)) 143 | #define SCPI_ParamUnsignedInt(context, value, mandatory) SCPI_ParamUInt32((context), (value), (mandatory)) 144 | #endif /* USE_DEPRECATED_FUNCTIONS */ 145 | 146 | #ifdef __cplusplus 147 | } 148 | #endif 149 | 150 | #endif /* SCPI_PARSER_H */ 151 | 152 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/scpi.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI library include file 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_H 39 | #define SCPI_H 40 | 41 | #include "scpi/parser.h" 42 | #include "scpi/ieee488.h" 43 | #include "scpi/error.h" 44 | #include "scpi/constants.h" 45 | #include "scpi/minimal.h" 46 | #include "scpi/units.h" 47 | #include "scpi/utils.h" 48 | #include "scpi/expression.h" 49 | 50 | #endif /* SCPI_H */ 51 | 52 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/types.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer, Richard.hmm 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_types.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI data types 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_TYPES_H 39 | #define SCPI_TYPES_H 40 | 41 | #include 42 | #include 43 | #include "scpi/config.h" 44 | 45 | #if HAVE_STDBOOL 46 | #include 47 | #endif 48 | 49 | #ifdef __cplusplus 50 | extern "C" { 51 | #endif 52 | 53 | #if !HAVE_STDBOOL 54 | typedef unsigned char bool; 55 | #endif 56 | 57 | #ifndef FALSE 58 | #define FALSE 0 59 | #endif 60 | #ifndef TRUE 61 | #define TRUE (!FALSE) 62 | #endif 63 | 64 | /* basic data types */ 65 | typedef bool scpi_bool_t; 66 | /* typedef enum { FALSE = 0, TRUE } scpi_bool_t; */ 67 | 68 | /* IEEE 488.2 registers */ 69 | enum _scpi_reg_name_t { 70 | SCPI_REG_STB = 0, /* Status Byte */ 71 | SCPI_REG_SRE, /* Service Request Enable Register */ 72 | SCPI_REG_ESR, /* Standard Event Status Register (ESR, SESR) */ 73 | SCPI_REG_ESE, /* Event Status Enable Register */ 74 | SCPI_REG_OPER, /* OPERation Status Register */ 75 | SCPI_REG_OPERE, /* OPERation Status Enable Register */ 76 | SCPI_REG_OPERC, /* OPERation Status Condition Register */ 77 | SCPI_REG_QUES, /* QUEStionable status register */ 78 | SCPI_REG_QUESE, /* QUEStionable status Enable Register */ 79 | SCPI_REG_QUESC, /* QUEStionable status Condition Register */ 80 | 81 | #if USE_CUSTOM_REGISTERS 82 | #ifndef USER_REGISTERS 83 | #error "No user registers defined" 84 | #else 85 | USER_REGISTERS 86 | #endif 87 | #endif 88 | 89 | /* number of registers */ 90 | SCPI_REG_COUNT, 91 | /* last definition - a value for no register */ 92 | SCPI_REG_NONE 93 | }; 94 | typedef enum _scpi_reg_name_t scpi_reg_name_t; 95 | 96 | enum _scpi_ctrl_name_t { 97 | SCPI_CTRL_SRQ = 1, /* service request */ 98 | SCPI_CTRL_GTL, /* Go to local */ 99 | SCPI_CTRL_SDC, /* Selected device clear */ 100 | SCPI_CTRL_PPC, /* Parallel poll configure */ 101 | SCPI_CTRL_GET, /* Group execute trigger */ 102 | SCPI_CTRL_TCT, /* Take control */ 103 | SCPI_CTRL_LLO, /* Device clear */ 104 | SCPI_CTRL_DCL, /* Local lockout */ 105 | SCPI_CTRL_PPU, /* Parallel poll unconfigure */ 106 | SCPI_CTRL_SPE, /* Serial poll enable */ 107 | SCPI_CTRL_SPD, /* Serial poll disable */ 108 | SCPI_CTRL_MLA, /* My local address */ 109 | SCPI_CTRL_UNL, /* Unlisten */ 110 | SCPI_CTRL_MTA, /* My talk address */ 111 | SCPI_CTRL_UNT, /* Untalk */ 112 | SCPI_CTRL_MSA /* My secondary address */ 113 | }; 114 | typedef enum _scpi_ctrl_name_t scpi_ctrl_name_t; 115 | 116 | typedef uint16_t scpi_reg_val_t; 117 | 118 | enum _scpi_reg_class_t { 119 | SCPI_REG_CLASS_STB = 0, 120 | SCPI_REG_CLASS_SRE, 121 | SCPI_REG_CLASS_EVEN, 122 | SCPI_REG_CLASS_ENAB, 123 | SCPI_REG_CLASS_COND, 124 | SCPI_REG_CLASS_NTR, 125 | SCPI_REG_CLASS_PTR, 126 | }; 127 | typedef enum _scpi_reg_class_t scpi_reg_class_t; 128 | 129 | enum _scpi_reg_group_t { 130 | SCPI_REG_GROUP_STB = 0, 131 | SCPI_REG_GROUP_ESR, 132 | SCPI_REG_GROUP_OPER, 133 | SCPI_REG_GROUP_QUES, 134 | 135 | #if USE_CUSTOM_REGISTERS 136 | #ifndef USER_REGISTER_GROUPS 137 | #error "No user register groups defined" 138 | #else 139 | USER_REGISTER_GROUPS 140 | #endif 141 | #endif 142 | 143 | /* last definition - number of register groups */ 144 | SCPI_REG_GROUP_COUNT 145 | }; 146 | typedef enum _scpi_reg_group_t scpi_reg_group_t; 147 | 148 | struct _scpi_reg_info_t { 149 | scpi_reg_class_t type; 150 | scpi_reg_group_t group; 151 | }; 152 | typedef struct _scpi_reg_info_t scpi_reg_info_t; 153 | 154 | struct _scpi_reg_group_info_t { 155 | scpi_reg_name_t event; 156 | scpi_reg_name_t enable; 157 | scpi_reg_name_t condition; 158 | scpi_reg_name_t ptfilt; 159 | scpi_reg_name_t ntfilt; 160 | scpi_reg_name_t parent_reg; 161 | scpi_reg_val_t parent_bit; 162 | }; 163 | typedef struct _scpi_reg_group_info_t scpi_reg_group_info_t; 164 | 165 | /* scpi commands */ 166 | enum _scpi_result_t { 167 | SCPI_RES_OK = 1, 168 | SCPI_RES_ERR = -1 169 | }; 170 | typedef enum _scpi_result_t scpi_result_t; 171 | 172 | typedef struct _scpi_command_t scpi_command_t; 173 | 174 | #if USE_COMMAND_TAGS 175 | #define SCPI_CMD_LIST_END {NULL, NULL, 0} 176 | #else 177 | #define SCPI_CMD_LIST_END {NULL, NULL} 178 | #endif 179 | 180 | 181 | /* scpi interface */ 182 | typedef struct _scpi_t scpi_t; 183 | typedef struct _scpi_interface_t scpi_interface_t; 184 | 185 | struct _scpi_buffer_t { 186 | size_t length; 187 | size_t position; 188 | char * data; 189 | }; 190 | typedef struct _scpi_buffer_t scpi_buffer_t; 191 | 192 | struct _scpi_const_buffer_t { 193 | size_t length; 194 | size_t position; 195 | const char * data; 196 | }; 197 | typedef struct _scpi_const_buffer_t scpi_const_buffer_t; 198 | 199 | typedef size_t(*scpi_write_t)(scpi_t * context, const char * data, size_t len); 200 | typedef scpi_result_t(*scpi_write_control_t)(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val); 201 | typedef int (*scpi_error_callback_t)(scpi_t * context, int_fast16_t error); 202 | 203 | /* scpi lexer */ 204 | enum _scpi_token_type_t { 205 | SCPI_TOKEN_COMMA, 206 | SCPI_TOKEN_SEMICOLON, 207 | SCPI_TOKEN_COLON, 208 | SCPI_TOKEN_SPECIFIC_CHARACTER, 209 | SCPI_TOKEN_QUESTION, 210 | SCPI_TOKEN_NL, 211 | SCPI_TOKEN_HEXNUM, 212 | SCPI_TOKEN_OCTNUM, 213 | SCPI_TOKEN_BINNUM, 214 | SCPI_TOKEN_PROGRAM_MNEMONIC, 215 | SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA, 216 | SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX, 217 | SCPI_TOKEN_SUFFIX_PROGRAM_DATA, 218 | SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA, 219 | SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA, 220 | SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA, 221 | SCPI_TOKEN_PROGRAM_EXPRESSION, 222 | SCPI_TOKEN_COMPOUND_PROGRAM_HEADER, 223 | SCPI_TOKEN_INCOMPLETE_COMPOUND_PROGRAM_HEADER, 224 | SCPI_TOKEN_COMMON_PROGRAM_HEADER, 225 | SCPI_TOKEN_INCOMPLETE_COMMON_PROGRAM_HEADER, 226 | SCPI_TOKEN_COMPOUND_QUERY_PROGRAM_HEADER, 227 | SCPI_TOKEN_COMMON_QUERY_PROGRAM_HEADER, 228 | SCPI_TOKEN_WS, 229 | SCPI_TOKEN_ALL_PROGRAM_DATA, 230 | SCPI_TOKEN_INVALID, 231 | SCPI_TOKEN_UNKNOWN, 232 | }; 233 | typedef enum _scpi_token_type_t scpi_token_type_t; 234 | 235 | struct _scpi_token_t { 236 | scpi_token_type_t type; 237 | char * ptr; 238 | int len; 239 | }; 240 | typedef struct _scpi_token_t scpi_token_t; 241 | 242 | struct _lex_state_t { 243 | char * buffer; 244 | char * pos; 245 | int len; 246 | }; 247 | typedef struct _lex_state_t lex_state_t; 248 | 249 | /* scpi parser */ 250 | enum _message_termination_t { 251 | SCPI_MESSAGE_TERMINATION_NONE, 252 | SCPI_MESSAGE_TERMINATION_NL, 253 | SCPI_MESSAGE_TERMINATION_SEMICOLON, 254 | }; 255 | typedef enum _message_termination_t message_termination_t; 256 | 257 | struct _scpi_parser_state_t { 258 | scpi_token_t programHeader; 259 | scpi_token_t programData; 260 | int numberOfParameters; 261 | message_termination_t termination; 262 | }; 263 | typedef struct _scpi_parser_state_t scpi_parser_state_t; 264 | 265 | typedef scpi_result_t(*scpi_command_callback_t)(scpi_t *); 266 | 267 | struct _scpi_error_info_heap_t { 268 | size_t wr; 269 | /* size_t rd; */ 270 | size_t count; 271 | size_t size; 272 | char * data; 273 | }; 274 | typedef struct _scpi_error_info_heap_t scpi_error_info_heap_t; 275 | 276 | struct _scpi_error_t { 277 | int16_t error_code; 278 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 279 | char * device_dependent_info; 280 | #endif 281 | }; 282 | typedef struct _scpi_error_t scpi_error_t; 283 | 284 | struct _scpi_fifo_t { 285 | int16_t wr; 286 | int16_t rd; 287 | int16_t count; 288 | int16_t size; 289 | scpi_error_t * data; 290 | }; 291 | typedef struct _scpi_fifo_t scpi_fifo_t; 292 | 293 | /* scpi units */ 294 | enum _scpi_unit_t { 295 | SCPI_UNIT_NONE, 296 | SCPI_UNIT_VOLT, 297 | SCPI_UNIT_AMPER, 298 | SCPI_UNIT_OHM, 299 | SCPI_UNIT_HERTZ, 300 | SCPI_UNIT_CELSIUS, 301 | SCPI_UNIT_SECOND, 302 | SCPI_UNIT_METER, 303 | SCPI_UNIT_GRAY, 304 | SCPI_UNIT_BECQUEREL, 305 | SCPI_UNIT_MOLE, 306 | SCPI_UNIT_DEGREE, 307 | SCPI_UNIT_GRADE, 308 | SCPI_UNIT_RADIAN, 309 | SCPI_UNIT_REVOLUTION, 310 | SCPI_UNIT_STERADIAN, 311 | SCPI_UNIT_SIEVERT, 312 | SCPI_UNIT_FARAD, 313 | SCPI_UNIT_COULOMB, 314 | SCPI_UNIT_SIEMENS, 315 | SCPI_UNIT_ELECTRONVOLT, 316 | SCPI_UNIT_JOULE, 317 | SCPI_UNIT_NEWTON, 318 | SCPI_UNIT_LUX, 319 | SCPI_UNIT_HENRY, 320 | SCPI_UNIT_ASTRONOMIC_UNIT, 321 | SCPI_UNIT_INCH, 322 | SCPI_UNIT_FOOT, 323 | SCPI_UNIT_PARSEC, 324 | SCPI_UNIT_MILE, 325 | SCPI_UNIT_NAUTICAL_MILE, 326 | SCPI_UNIT_LUMEN, 327 | SCPI_UNIT_CANDELA, 328 | SCPI_UNIT_WEBER, 329 | SCPI_UNIT_TESLA, 330 | SCPI_UNIT_ATOMIC_MASS, 331 | SCPI_UNIT_KILOGRAM, 332 | SCPI_UNIT_WATT, 333 | SCPI_UNIT_DBM, 334 | SCPI_UNIT_ATMOSPHERE, 335 | SCPI_UNIT_INCH_OF_MERCURY, 336 | SCPI_UNIT_MM_OF_MERCURY, 337 | SCPI_UNIT_PASCAL, 338 | SCPI_UNIT_TORT, 339 | SCPI_UNIT_BAR, 340 | SCPI_UNIT_DECIBEL, 341 | SCPI_UNIT_UNITLESS, 342 | SCPI_UNIT_FAHRENHEIT, 343 | SCPI_UNIT_KELVIN, 344 | SCPI_UNIT_DAY, 345 | SCPI_UNIT_YEAR, 346 | SCPI_UNIT_STROKES, 347 | SCPI_UNIT_POISE, 348 | SCPI_UNIT_LITER 349 | }; 350 | typedef enum _scpi_unit_t scpi_unit_t; 351 | 352 | struct _scpi_unit_def_t { 353 | const char * name; 354 | scpi_unit_t unit; 355 | double mult; 356 | }; 357 | #define SCPI_UNITS_LIST_END {NULL, SCPI_UNIT_NONE, 0} 358 | typedef struct _scpi_unit_def_t scpi_unit_def_t; 359 | 360 | enum _scpi_special_number_t { 361 | SCPI_NUM_NUMBER, 362 | SCPI_NUM_MIN, 363 | SCPI_NUM_MAX, 364 | SCPI_NUM_DEF, 365 | SCPI_NUM_UP, 366 | SCPI_NUM_DOWN, 367 | SCPI_NUM_NAN, 368 | SCPI_NUM_INF, 369 | SCPI_NUM_NINF, 370 | SCPI_NUM_AUTO 371 | }; 372 | typedef enum _scpi_special_number_t scpi_special_number_t; 373 | 374 | struct _scpi_choice_def_t { 375 | const char * name; 376 | int32_t tag; 377 | }; 378 | #define SCPI_CHOICE_LIST_END {NULL, -1} 379 | typedef struct _scpi_choice_def_t scpi_choice_def_t; 380 | 381 | struct _scpi_param_list_t { 382 | const scpi_command_t * cmd; 383 | lex_state_t lex_state; 384 | scpi_const_buffer_t cmd_raw; 385 | }; 386 | typedef struct _scpi_param_list_t scpi_param_list_t; 387 | 388 | struct _scpi_number_parameter_t { 389 | scpi_bool_t special; 390 | 391 | union { 392 | double value; 393 | int32_t tag; 394 | } content; 395 | scpi_unit_t unit; 396 | int8_t base; 397 | }; 398 | typedef struct _scpi_number_parameter_t scpi_number_t; 399 | 400 | struct _scpi_data_parameter_t { 401 | const char * ptr; 402 | int32_t len; 403 | }; 404 | typedef struct _scpi_data_parameter_t scpi_data_parameter_t; 405 | 406 | typedef scpi_token_t scpi_parameter_t; 407 | 408 | struct _scpi_command_t { 409 | const char * pattern; 410 | scpi_command_callback_t callback; 411 | #if USE_COMMAND_TAGS 412 | int32_t tag; 413 | #endif /* USE_COMMAND_TAGS */ 414 | }; 415 | 416 | struct _scpi_interface_t { 417 | scpi_error_callback_t error; 418 | scpi_write_t write; 419 | scpi_write_control_t control; 420 | scpi_command_callback_t flush; 421 | scpi_command_callback_t reset; 422 | }; 423 | 424 | struct _scpi_t { 425 | const scpi_command_t * cmdlist; 426 | scpi_buffer_t buffer; 427 | scpi_param_list_t param_list; 428 | scpi_interface_t * interface; 429 | int_fast16_t output_count; 430 | int_fast16_t input_count; 431 | scpi_bool_t first_output; 432 | scpi_bool_t cmd_error; 433 | scpi_fifo_t error_queue; 434 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE 435 | scpi_error_info_heap_t error_info_heap; 436 | #endif 437 | scpi_reg_val_t registers[SCPI_REG_COUNT]; 438 | const scpi_unit_def_t * units; 439 | void * user_context; 440 | scpi_parser_state_t parser_state; 441 | const char * idn[4]; 442 | size_t arbitrary_remaining; 443 | }; 444 | 445 | enum _scpi_array_format_t { 446 | SCPI_FORMAT_ASCII = 0, 447 | SCPI_FORMAT_NORMAL = 1, 448 | SCPI_FORMAT_SWAPPED = 2, 449 | SCPI_FORMAT_BIGENDIAN = SCPI_FORMAT_NORMAL, 450 | SCPI_FORMAT_LITTLEENDIAN = SCPI_FORMAT_SWAPPED, 451 | }; 452 | typedef enum _scpi_array_format_t scpi_array_format_t; 453 | 454 | #ifdef __cplusplus 455 | } 456 | #endif 457 | 458 | #endif /* SCPI_TYPES_H */ 459 | 460 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/units.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_units.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI Units 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_UNITS_H 39 | #define SCPI_UNITS_H 40 | 41 | #include "scpi/types.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | extern const scpi_unit_def_t scpi_units_def[]; 48 | extern const scpi_choice_def_t scpi_special_numbers_def[]; 49 | 50 | scpi_bool_t SCPI_ParamNumber(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, scpi_bool_t mandatory); 51 | 52 | scpi_bool_t SCPI_ParamTranslateNumberVal(scpi_t * context, scpi_parameter_t * parameter); 53 | size_t SCPI_NumberToStr(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, char * str, size_t len); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif /* SCPI_UNITS_H */ 60 | 61 | -------------------------------------------------------------------------------- /libscpi/inc/scpi/utils.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file utils.h 31 | * 32 | * @brief Conversion routines and string manipulation routines 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_UTILS_H 38 | #define SCPI_UTILS_H 39 | 40 | #include 41 | #include "scpi/types.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | size_t SCPI_UInt32ToStrBase(uint32_t val, char * str, size_t len, int8_t base); 48 | size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len); 49 | size_t SCPI_UInt64ToStrBase(uint64_t val, char * str, size_t len, int8_t base); 50 | size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len); 51 | size_t SCPI_FloatToStr(float val, char * str, size_t len); 52 | size_t SCPI_DoubleToStr(double val, char * str, size_t len); 53 | 54 | /* deprecated finction, should be removed later */ 55 | #define SCPI_LongToStr(val, str, len, base) SCPI_Int32ToStr((val), (str), (len), (base), TRUE) 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* SCPI_UTILS_H */ 62 | 63 | -------------------------------------------------------------------------------- /libscpi/src/error.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | /** 29 | * @file scpi_error.c 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief Error handling and storing routines 33 | * 34 | * 35 | */ 36 | 37 | #include 38 | 39 | #include "scpi/parser.h" 40 | #include "scpi/ieee488.h" 41 | #include "scpi/error.h" 42 | #include "fifo_private.h" 43 | #include "scpi/constants.h" 44 | 45 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 46 | #define SCPI_ERROR_SETVAL(e, c, i) do { (e)->error_code = (c); (e)->device_dependent_info = (i); } while(0) 47 | #else 48 | #define SCPI_ERROR_SETVAL(e, c, i) do { (e)->error_code = (c); (void)(i);} while(0) 49 | #endif 50 | 51 | /** 52 | * Initialize error queue 53 | * @param context - scpi context 54 | */ 55 | void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size) { 56 | fifo_init(&context->error_queue, data, size); 57 | } 58 | 59 | /** 60 | * Emit no error 61 | * @param context scpi context 62 | */ 63 | static void SCPI_ErrorEmitEmpty(scpi_t * context) { 64 | if ((SCPI_ErrorCount(context) == 0) && (SCPI_RegGet(context, SCPI_REG_STB) & STB_QMA)) { 65 | SCPI_RegClearBits(context, SCPI_REG_STB, STB_QMA); 66 | 67 | if (context->interface && context->interface->error) { 68 | context->interface->error(context, 0); 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * Emit error 75 | * @param context scpi context 76 | * @param err Error to emit 77 | */ 78 | static void SCPI_ErrorEmit(scpi_t * context, int16_t err) { 79 | SCPI_RegSetBits(context, SCPI_REG_STB, STB_QMA); 80 | 81 | if (context->interface && context->interface->error) { 82 | context->interface->error(context, err); 83 | } 84 | } 85 | 86 | /** 87 | * Clear error queue 88 | * @param context - scpi context 89 | */ 90 | void SCPI_ErrorClear(scpi_t * context) { 91 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 92 | scpi_error_t error; 93 | while (fifo_remove(&context->error_queue, &error)) { 94 | SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); 95 | } 96 | #endif 97 | fifo_clear(&context->error_queue); 98 | 99 | SCPI_ErrorEmitEmpty(context); 100 | } 101 | 102 | /** 103 | * Pop error from queue 104 | * @param context - scpi context 105 | * @param error 106 | * @return 107 | */ 108 | scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error) { 109 | if (!error || !context) return FALSE; 110 | SCPI_ERROR_SETVAL(error, 0, NULL); 111 | fifo_remove(&context->error_queue, error); 112 | 113 | SCPI_ErrorEmitEmpty(context); 114 | 115 | return TRUE; 116 | } 117 | 118 | /** 119 | * Return number of errors/events in the queue 120 | * @param context 121 | * @return 122 | */ 123 | int32_t SCPI_ErrorCount(scpi_t * context) { 124 | int16_t result = 0; 125 | 126 | fifo_count(&context->error_queue, &result); 127 | 128 | return result; 129 | } 130 | 131 | static scpi_bool_t SCPI_ErrorAddInternal(scpi_t * context, int16_t err, char * info, size_t info_len) { 132 | scpi_error_t error_value; 133 | /* SCPIDEFINE_strndup is sometimes a dumy that does not reference it's arguments. 134 | Since info_len is not referenced elsewhere caoing to void prevents unusd argument warnings */ 135 | (void) info_len; 136 | char * info_ptr = NULL; 137 | if (info) { 138 | info_ptr = SCPIDEFINE_strndup(&context->error_info_heap, info, info_len); 139 | } 140 | SCPI_ERROR_SETVAL(&error_value, err, info_ptr); 141 | if (!fifo_add(&context->error_queue, &error_value)) { 142 | SCPIDEFINE_free(&context->error_info_heap, error_value.device_dependent_info, true); 143 | fifo_remove_last(&context->error_queue, &error_value); 144 | SCPIDEFINE_free(&context->error_info_heap, error_value.device_dependent_info, true); 145 | SCPI_ERROR_SETVAL(&error_value, SCPI_ERROR_QUEUE_OVERFLOW, NULL); 146 | fifo_add(&context->error_queue, &error_value); 147 | return FALSE; 148 | } 149 | return TRUE; 150 | } 151 | 152 | struct error_reg { 153 | int16_t from; 154 | int16_t to; 155 | scpi_reg_val_t esrBit; 156 | }; 157 | 158 | #define ERROR_DEFS_N 9 159 | 160 | static const struct error_reg errs[ERROR_DEFS_N] = { 161 | {-100, -199, ESR_CER}, /* Command error (e.g. syntax error) ch 21.8.9 */ 162 | {-200, -299, ESR_EER}, /* Execution Error (e.g. range error) ch 21.8.10 */ 163 | {-300, -399, ESR_DER}, /* Device specific error -300, -399 ch 21.8.11 */ 164 | { 1, 32767, ESR_DER}, /* Device designer provided specific error 1, 32767 ch 21.8.11 */ 165 | {-400, -499, ESR_QER}, /* Query error -400, -499 ch 21.8.12 */ 166 | {-500, -599, ESR_PON}, /* Power on event -500, -599 ch 21.8.13 */ 167 | {-600, -699, ESR_URQ}, /* User Request Event -600, -699 ch 21.8.14 */ 168 | {-700, -799, ESR_REQ}, /* Request Control Event -700, -799 ch 21.8.15 */ 169 | {-800, -899, ESR_OPC}, /* Operation Complete Event -800, -899 ch 21.8.16 */ 170 | }; 171 | 172 | /** 173 | * Push error to queue 174 | * @param context 175 | * @param err - error number 176 | * @param info - additional text information or NULL for no text 177 | * @param info_len - length of text or 0 for automatic length 178 | */ 179 | void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info, size_t info_len) { 180 | int i; 181 | /* automatic calculation of length */ 182 | if (info && info_len == 0) { 183 | info_len = SCPIDEFINE_strnlen(info, SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH); 184 | } 185 | scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, info, info_len); 186 | 187 | for (i = 0; i < ERROR_DEFS_N; i++) { 188 | if ((err <= errs[i].from) && (err >= errs[i].to)) { 189 | SCPI_RegSetBits(context, SCPI_REG_ESR, errs[i].esrBit); 190 | } 191 | } 192 | 193 | SCPI_ErrorEmit(context, err); 194 | if (queue_overflow) { 195 | SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW); 196 | } 197 | 198 | if (context) { 199 | context->cmd_error = TRUE; 200 | } 201 | } 202 | 203 | /** 204 | * Push error to queue 205 | * @param context - scpi context 206 | * @param err - error number 207 | */ 208 | void SCPI_ErrorPush(scpi_t * context, int16_t err) { 209 | SCPI_ErrorPushEx(context, err, NULL, 0); 210 | return; 211 | } 212 | 213 | /** 214 | * Translate error number to string 215 | * @param err - error number 216 | * @return Error string representation 217 | */ 218 | const char * SCPI_ErrorTranslate(int16_t err) { 219 | switch (err) { 220 | #define X(def, val, str) case def: return str; 221 | #if USE_FULL_ERROR_LIST 222 | #define XE X 223 | #else 224 | #define XE(def, val, str) 225 | #endif 226 | LIST_OF_ERRORS 227 | 228 | #if USE_USER_ERROR_LIST 229 | LIST_OF_USER_ERRORS 230 | #endif 231 | #undef X 232 | #undef XE 233 | default: return "Unknown error"; 234 | } 235 | } 236 | 237 | 238 | -------------------------------------------------------------------------------- /libscpi/src/expression.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file expression.c 31 | * 32 | * @brief Expressions handling 33 | * 34 | * 35 | */ 36 | 37 | #include "scpi/expression.h" 38 | #include "scpi/error.h" 39 | #include "scpi/parser.h" 40 | 41 | #include "lexer_private.h" 42 | 43 | /** 44 | * Parse one range or single value 45 | * @param state lexer state 46 | * @param isRange return true if parsed expression is range 47 | * @param valueFrom return parsed value from 48 | * @param valueTo return parsed value to 49 | * @return SCPI_EXPR_OK - parsing was succesful 50 | * SCPI_EXPR_ERROR - parser error 51 | * SCPI_EXPR_NO_MORE - no more data 52 | */ 53 | static scpi_expr_result_t numericRange(lex_state_t * state, scpi_bool_t * isRange, scpi_token_t * valueFrom, scpi_token_t * valueTo) { 54 | if (scpiLex_DecimalNumericProgramData(state, valueFrom)) { 55 | if (scpiLex_Colon(state, valueTo)) { 56 | *isRange = TRUE; 57 | if (scpiLex_DecimalNumericProgramData(state, valueTo)) { 58 | return SCPI_EXPR_OK; 59 | } else { 60 | return SCPI_EXPR_ERROR; 61 | } 62 | } else { 63 | *isRange = FALSE; 64 | return SCPI_EXPR_OK; 65 | } 66 | } 67 | 68 | return SCPI_EXPR_NO_MORE; 69 | } 70 | 71 | /** 72 | * Parse entry on specified position 73 | * @param context scpi context 74 | * @param param input parameter 75 | * @param index index of position (start from 0) 76 | * @param isRange return true if expression at index was range 77 | * @param valueFrom return value from 78 | * @param valueTo return value to 79 | * @return SCPI_EXPR_OK - parsing was succesful 80 | * SCPI_EXPR_ERROR - parser error 81 | * SCPI_EXPR_NO_MORE - no more data 82 | * @see SCPI_ExprNumericListEntryInt, SCPI_ExprNumericListEntryDouble 83 | */ 84 | 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) { 85 | lex_state_t lex; 86 | int i; 87 | scpi_expr_result_t res = SCPI_EXPR_OK; 88 | 89 | if (!isRange || !valueFrom || !valueTo || !param) { 90 | SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); 91 | return SCPI_EXPR_ERROR; 92 | } 93 | 94 | if (param->type != SCPI_TOKEN_PROGRAM_EXPRESSION) { 95 | SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); 96 | return SCPI_EXPR_ERROR; 97 | } 98 | 99 | lex.buffer = param->ptr + 1; 100 | lex.pos = lex.buffer; 101 | lex.len = param->len - 2; 102 | 103 | for (i = 0; i <= index; i++) { 104 | res = numericRange(&lex, isRange, valueFrom, valueTo); 105 | if (res != SCPI_EXPR_OK) { 106 | break; 107 | } 108 | if (i != index) { 109 | if (!scpiLex_Comma(&lex, valueFrom)) { 110 | res = scpiLex_IsEos(&lex) ? SCPI_EXPR_NO_MORE : SCPI_EXPR_ERROR; 111 | break; 112 | } 113 | } 114 | } 115 | 116 | if (res == SCPI_EXPR_ERROR) { 117 | SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); 118 | } 119 | return res; 120 | } 121 | 122 | /** 123 | * Parse entry on specified position and convert result to int32_t 124 | * @param context scpi context 125 | * @param param input parameter 126 | * @param index index of position (start from 0) 127 | * @param isRange return true if expression at index was range 128 | * @param valueFrom return value from 129 | * @param valueTo return value to 130 | * @return SCPI_EXPR_OK - parsing was succesful 131 | * SCPI_EXPR_ERROR - parser error 132 | * SCPI_EXPR_NO_MORE - no more data 133 | * @see SCPI_ExprNumericListEntry, SCPI_ExprNumericListEntryDouble 134 | */ 135 | 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) { 136 | scpi_expr_result_t res; 137 | scpi_bool_t range = FALSE; 138 | scpi_parameter_t paramFrom; 139 | scpi_parameter_t paramTo; 140 | 141 | res = SCPI_ExprNumericListEntry(context, param, index, &range, ¶mFrom, ¶mTo); 142 | if (res == SCPI_EXPR_OK) { 143 | *isRange = range; 144 | SCPI_ParamToInt32(context, ¶mFrom, valueFrom); 145 | if (range) { 146 | SCPI_ParamToInt32(context, ¶mTo, valueTo); 147 | } 148 | } 149 | 150 | return res; 151 | } 152 | 153 | /** 154 | * Parse entry on specified position and convert result to double 155 | * @param context scpi context 156 | * @param param input parameter 157 | * @param index index of position (start from 0) 158 | * @param isRange return true if expression at index was range 159 | * @param valueFrom return value from 160 | * @param valueTo return value to 161 | * @return SCPI_EXPR_OK - parsing was succesful 162 | * SCPI_EXPR_ERROR - parser error 163 | * SCPI_EXPR_NO_MORE - no more data 164 | * @see SCPI_ExprNumericListEntry, SCPI_ExprNumericListEntryInt 165 | */ 166 | scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo) { 167 | scpi_expr_result_t res; 168 | scpi_bool_t range = FALSE; 169 | scpi_parameter_t paramFrom; 170 | scpi_parameter_t paramTo; 171 | 172 | res = SCPI_ExprNumericListEntry(context, param, index, &range, ¶mFrom, ¶mTo); 173 | if (res == SCPI_EXPR_OK) { 174 | *isRange = range; 175 | SCPI_ParamToDouble(context, ¶mFrom, valueFrom); 176 | if (range) { 177 | SCPI_ParamToDouble(context, ¶mTo, valueTo); 178 | } 179 | } 180 | 181 | return res; 182 | } 183 | 184 | /** 185 | * Parse one channel_spec e.g. "1!5!8" 186 | * @param context 187 | * @param state lexer state 188 | * @param values range values 189 | * @param length length of values array 190 | * @param dimensions real number of dimensions 191 | */ 192 | static scpi_expr_result_t channelSpec(scpi_t * context, lex_state_t * state, int32_t * values, size_t length, size_t * dimensions) { 193 | scpi_parameter_t param; 194 | size_t i = 0; 195 | while (scpiLex_DecimalNumericProgramData(state, ¶m)) { 196 | if (i < length) { 197 | SCPI_ParamToInt32(context, ¶m, &values[i]); 198 | } 199 | 200 | if (scpiLex_SpecificCharacter(state, ¶m, '!')) { 201 | i++; 202 | } else { 203 | *dimensions = i + 1; 204 | return SCPI_EXPR_OK; 205 | } 206 | } 207 | 208 | if (i == 0) { 209 | return SCPI_EXPR_NO_MORE; 210 | } else { 211 | /* there was at least one number followed by !, but after ! was not another number */ 212 | return SCPI_EXPR_ERROR; 213 | } 214 | } 215 | 216 | /** 217 | * Parse channel_range e.g. "1!2:5!6" 218 | * @param context 219 | * @param state lexer state 220 | * @param isRange return true if it is range 221 | * @param valuesFrom return array of values from 222 | * @param valuesTo return array of values to 223 | * @param length length of values arrays 224 | * @param dimensions real number of dimensions 225 | */ 226 | static scpi_expr_result_t channelRange(scpi_t * context, lex_state_t * state, scpi_bool_t * isRange, int32_t * valuesFrom, int32_t * valuesTo, size_t length, size_t * dimensions) { 227 | scpi_token_t token; 228 | scpi_expr_result_t err; 229 | size_t fromDimensions; 230 | size_t toDimensions; 231 | 232 | err = channelSpec(context, state, valuesFrom, length, &fromDimensions); 233 | if (err == SCPI_EXPR_OK) { 234 | if (scpiLex_Colon(state, &token)) { 235 | *isRange = TRUE; 236 | err = channelSpec(context, state, valuesTo, length, &toDimensions); 237 | if (err != SCPI_EXPR_OK) { 238 | return SCPI_EXPR_ERROR; 239 | } 240 | if (fromDimensions != toDimensions) { 241 | return SCPI_EXPR_ERROR; 242 | } 243 | *dimensions = fromDimensions; 244 | } else { 245 | *isRange = FALSE; 246 | *dimensions = fromDimensions; 247 | return SCPI_EXPR_OK; 248 | } 249 | } else if (err == SCPI_EXPR_NO_MORE) { 250 | err = SCPI_EXPR_ERROR; 251 | } 252 | 253 | return err; 254 | } 255 | 256 | /** 257 | * Parse one list entry at specific position e.g. "1!2:5!6" 258 | * @param context 259 | * @param param 260 | * @param index 261 | * @param isRange return true if it is range 262 | * @param valuesFrom return array of values from 263 | * @param valuesTo return array of values to 264 | * @param length length of values arrays 265 | * @param dimensions real number of dimensions 266 | */ 267 | 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) { 268 | lex_state_t lex; 269 | int i; 270 | scpi_expr_result_t res = SCPI_EXPR_OK; 271 | scpi_token_t token; 272 | 273 | if (!isRange || !param || !dimensions || (length && (!valuesFrom || !valuesTo))) { 274 | SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); 275 | return SCPI_EXPR_ERROR; 276 | } 277 | 278 | if (param->type != SCPI_TOKEN_PROGRAM_EXPRESSION) { 279 | SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); 280 | return SCPI_EXPR_ERROR; 281 | } 282 | 283 | lex.buffer = param->ptr + 1; 284 | lex.pos = lex.buffer; 285 | lex.len = param->len - 2; 286 | 287 | /* detect channel list expression */ 288 | if (!scpiLex_SpecificCharacter(&lex, &token, '@')) { 289 | SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); 290 | return SCPI_EXPR_ERROR; 291 | } 292 | 293 | for (i = 0; i <= index; i++) { 294 | res = channelRange(context, &lex, isRange, valuesFrom, valuesTo, (i == index) ? length : 0, dimensions); 295 | if (res != SCPI_EXPR_OK) { 296 | break; 297 | } 298 | if (i != index) { 299 | if (!scpiLex_Comma(&lex, &token)) { 300 | res = scpiLex_IsEos(&lex) ? SCPI_EXPR_NO_MORE : SCPI_EXPR_ERROR; 301 | break; 302 | } 303 | } 304 | } 305 | 306 | if (res == SCPI_EXPR_ERROR) { 307 | SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); 308 | } 309 | if (res == SCPI_EXPR_NO_MORE) { 310 | if (!scpiLex_IsEos(&lex)) { 311 | res = SCPI_EXPR_ERROR; 312 | SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); 313 | } 314 | } 315 | return res; 316 | } 317 | -------------------------------------------------------------------------------- /libscpi/src/fifo.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "fifo_private.h" 30 | 31 | /** 32 | * Initialize fifo 33 | * @param fifo 34 | */ 35 | void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) { 36 | fifo->wr = 0; 37 | fifo->rd = 0; 38 | fifo->count = 0; 39 | fifo->data = data; 40 | fifo->size = size; 41 | } 42 | 43 | /** 44 | * Empty fifo 45 | * @param fifo 46 | */ 47 | void fifo_clear(scpi_fifo_t * fifo) { 48 | fifo->wr = 0; 49 | fifo->rd = 0; 50 | fifo->count = 0; 51 | } 52 | 53 | /** 54 | * Test if fifo is empty 55 | * @param fifo 56 | * @return 57 | */ 58 | scpi_bool_t fifo_is_empty(scpi_fifo_t * fifo) { 59 | return fifo->count == 0; 60 | } 61 | 62 | /** 63 | * Test if fifo is full 64 | * @param fifo 65 | * @return 66 | */ 67 | scpi_bool_t fifo_is_full(scpi_fifo_t * fifo) { 68 | return fifo->count == fifo->size; 69 | } 70 | 71 | /** 72 | * Add element to fifo. If fifo is full, return FALSE. 73 | * @param fifo 74 | * @param err 75 | * @param info 76 | * @return 77 | */ 78 | scpi_bool_t fifo_add(scpi_fifo_t * fifo, const scpi_error_t * value) { 79 | /* FIFO full? */ 80 | if (fifo_is_full(fifo)) { 81 | return FALSE; 82 | } 83 | if (!value) { 84 | return FALSE; 85 | } 86 | 87 | fifo->data[fifo->wr] = *value; 88 | fifo->wr = (fifo->wr + 1) % (fifo->size); 89 | fifo->count += 1; 90 | return TRUE; 91 | } 92 | 93 | /** 94 | * Remove element form fifo 95 | * @param fifo 96 | * @param value 97 | * @return FALSE - fifo is empty 98 | */ 99 | scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) { 100 | /* FIFO empty? */ 101 | if (fifo_is_empty(fifo)) { 102 | return FALSE; 103 | } 104 | 105 | if (value) { 106 | *value = fifo->data[fifo->rd]; 107 | } 108 | 109 | fifo->rd = (fifo->rd + 1) % (fifo->size); 110 | fifo->count -= 1; 111 | 112 | return TRUE; 113 | } 114 | 115 | /** 116 | * Remove last element from fifo 117 | * @param fifo 118 | * @param value 119 | * @return FALSE - fifo is empty 120 | */ 121 | scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) { 122 | /* FIFO empty? */ 123 | if (fifo_is_empty(fifo)) { 124 | return FALSE; 125 | } 126 | 127 | fifo->wr = (fifo->wr + fifo->size - 1) % (fifo->size); 128 | 129 | if (value) { 130 | *value = fifo->data[fifo->wr]; 131 | } 132 | fifo->count -= 1; 133 | 134 | return TRUE; 135 | } 136 | 137 | /** 138 | * Retrive number of elements in fifo 139 | * @param fifo 140 | * @param value 141 | * @return 142 | */ 143 | scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) { 144 | *value = fifo->count; 145 | return TRUE; 146 | } 147 | -------------------------------------------------------------------------------- /libscpi/src/fifo_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_fifo.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief basic FIFO implementation 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_FIFO_H 39 | #define SCPI_FIFO_H 40 | 41 | #include "scpi/types.h" 42 | #include "utils_private.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) LOCAL; 49 | void fifo_clear(scpi_fifo_t * fifo) LOCAL; 50 | scpi_bool_t fifo_is_empty(scpi_fifo_t * fifo) LOCAL; 51 | scpi_bool_t fifo_is_full(scpi_fifo_t * fifo) LOCAL; 52 | scpi_bool_t fifo_add(scpi_fifo_t * fifo, const scpi_error_t * value) LOCAL; 53 | scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL; 54 | scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL; 55 | scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) LOCAL; 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* SCPI_FIFO_H */ 62 | -------------------------------------------------------------------------------- /libscpi/src/ieee488.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_ieee488.c 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief Implementation of IEEE488.2 commands and state model 34 | * 35 | * 36 | */ 37 | 38 | #include "scpi/parser.h" 39 | #include "scpi/ieee488.h" 40 | #include "scpi/error.h" 41 | #include "scpi/constants.h" 42 | 43 | #include 44 | 45 | static const scpi_reg_info_t scpi_reg_details[SCPI_REG_COUNT] = { 46 | { SCPI_REG_CLASS_STB, SCPI_REG_GROUP_STB }, 47 | { SCPI_REG_CLASS_SRE, SCPI_REG_GROUP_STB }, 48 | { SCPI_REG_CLASS_EVEN, SCPI_REG_GROUP_ESR }, 49 | { SCPI_REG_CLASS_ENAB, SCPI_REG_GROUP_ESR }, 50 | { SCPI_REG_CLASS_EVEN, SCPI_REG_GROUP_OPER }, 51 | { SCPI_REG_CLASS_ENAB, SCPI_REG_GROUP_OPER }, 52 | { SCPI_REG_CLASS_COND, SCPI_REG_GROUP_OPER }, 53 | { SCPI_REG_CLASS_EVEN, SCPI_REG_GROUP_QUES }, 54 | { SCPI_REG_CLASS_ENAB, SCPI_REG_GROUP_QUES }, 55 | { SCPI_REG_CLASS_COND, SCPI_REG_GROUP_QUES }, 56 | 57 | #if USE_CUSTOM_REGISTERS 58 | #ifndef USER_REGISTER_DETAILS 59 | #error "No user register details defined" 60 | #else 61 | USER_REGISTER_DETAILS 62 | #endif 63 | #endif 64 | 65 | }; 66 | 67 | static const scpi_reg_group_info_t scpi_reg_group_details[SCPI_REG_GROUP_COUNT] = { 68 | { 69 | SCPI_REG_STB, 70 | SCPI_REG_SRE, 71 | SCPI_REG_NONE, 72 | SCPI_REG_NONE, 73 | SCPI_REG_NONE, 74 | SCPI_REG_NONE, 75 | 0 76 | }, /* SCPI_REG_GROUP_STB */ 77 | { 78 | SCPI_REG_ESR, 79 | SCPI_REG_ESE, 80 | SCPI_REG_NONE, 81 | SCPI_REG_NONE, 82 | SCPI_REG_NONE, 83 | SCPI_REG_STB, 84 | STB_ESR 85 | }, /* SCPI_REG_GROUP_ESR */ 86 | { 87 | SCPI_REG_OPER, 88 | SCPI_REG_OPERE, 89 | SCPI_REG_OPERC, 90 | SCPI_REG_NONE, 91 | SCPI_REG_NONE, 92 | SCPI_REG_STB, 93 | STB_OPS 94 | }, /* SCPI_REG_GROUP_OPER */ 95 | { 96 | SCPI_REG_QUES, 97 | SCPI_REG_QUESE, 98 | SCPI_REG_QUESC, 99 | SCPI_REG_NONE, 100 | SCPI_REG_NONE, 101 | SCPI_REG_STB, 102 | STB_QES 103 | }, /* SCPI_REG_GROUP_QUES */ 104 | 105 | #if USE_CUSTOM_REGISTERS 106 | #ifndef USER_REGISTER_GROUP_DETAILS 107 | #error "No user register group details defined" 108 | #else 109 | USER_REGISTER_GROUP_DETAILS 110 | #endif 111 | #endif 112 | 113 | }; 114 | 115 | /** 116 | * Get register value 117 | * @param name - register name 118 | * @return register value 119 | */ 120 | scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name) { 121 | if ((name < SCPI_REG_COUNT) && context) { 122 | return context->registers[name]; 123 | } else { 124 | return 0; 125 | } 126 | } 127 | 128 | /** 129 | * Wrapper function to control interface from context 130 | * @param context 131 | * @param ctrl number of controll message 132 | * @param value value of related register 133 | */ 134 | static size_t writeControl(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 135 | if (context && context->interface && context->interface->control) { 136 | return context->interface->control(context, ctrl, val); 137 | } else { 138 | return 0; 139 | } 140 | } 141 | 142 | /** 143 | * Set register value 144 | * @param name - register name 145 | * @param val - new value 146 | */ 147 | void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val) { 148 | if ((name >= SCPI_REG_COUNT) || (context == NULL)) { 149 | return; 150 | } 151 | 152 | scpi_reg_group_info_t register_group; 153 | 154 | do { 155 | scpi_reg_class_t register_type = scpi_reg_details[name].type; 156 | register_group = scpi_reg_group_details[scpi_reg_details[name].group]; 157 | 158 | scpi_reg_val_t ptrans; 159 | 160 | /* store old register value */ 161 | scpi_reg_val_t old_val = context->registers[name]; 162 | 163 | if (old_val == val) { 164 | return; 165 | } else { 166 | context->registers[name] = val; 167 | } 168 | 169 | switch (register_type) { 170 | case SCPI_REG_CLASS_STB: 171 | case SCPI_REG_CLASS_SRE: 172 | { 173 | scpi_reg_val_t stb = context->registers[SCPI_REG_STB] & ~STB_SRQ; 174 | scpi_reg_val_t sre = context->registers[SCPI_REG_SRE] & ~STB_SRQ; 175 | 176 | if (stb & sre) { 177 | ptrans = ((old_val ^ val) & val); 178 | context->registers[SCPI_REG_STB] |= STB_SRQ; 179 | if (ptrans & val) { 180 | writeControl(context, SCPI_CTRL_SRQ, context->registers[SCPI_REG_STB]); 181 | } 182 | } else { 183 | context->registers[SCPI_REG_STB] &= ~STB_SRQ; 184 | } 185 | break; 186 | } 187 | case SCPI_REG_CLASS_EVEN: 188 | { 189 | scpi_reg_val_t enable; 190 | if(register_group.enable != SCPI_REG_NONE) { 191 | enable = SCPI_RegGet(context, register_group.enable); 192 | } else { 193 | enable = 0xFFFF; 194 | } 195 | 196 | scpi_bool_t summary = val & enable; 197 | 198 | name = register_group.parent_reg; 199 | val = SCPI_RegGet(context, register_group.parent_reg); 200 | if (summary) { 201 | val |= register_group.parent_bit; 202 | } else { 203 | val &= ~(register_group.parent_bit); 204 | } 205 | break; 206 | } 207 | case SCPI_REG_CLASS_COND: 208 | { 209 | name = register_group.event; 210 | 211 | if(register_group.ptfilt == SCPI_REG_NONE && register_group.ntfilt == SCPI_REG_NONE) { 212 | val = ((old_val ^ val) & val) | SCPI_RegGet(context, register_group.event); 213 | } else { 214 | scpi_reg_val_t ptfilt = 0, ntfilt = 0; 215 | scpi_reg_val_t transitions; 216 | scpi_reg_val_t ntrans; 217 | 218 | if(register_group.ptfilt != SCPI_REG_NONE) { 219 | ptfilt = SCPI_RegGet(context, register_group.ptfilt); 220 | } 221 | 222 | if(register_group.ntfilt != SCPI_REG_NONE) { 223 | ntfilt = SCPI_RegGet(context, register_group.ntfilt); 224 | } 225 | 226 | transitions = old_val ^ val; 227 | ptrans = transitions & val; 228 | ntrans = transitions & ~ptrans; 229 | 230 | val = ((ptrans & ptfilt) | (ntrans & ntfilt)) | SCPI_RegGet(context, register_group.event); 231 | } 232 | break; 233 | } 234 | case SCPI_REG_CLASS_ENAB: 235 | case SCPI_REG_CLASS_NTR: 236 | case SCPI_REG_CLASS_PTR: 237 | return; 238 | } 239 | } while(register_group.parent_reg != SCPI_REG_NONE); 240 | } 241 | 242 | /** 243 | * Set register bits 244 | * @param name - register name 245 | * @param bits bit mask 246 | */ 247 | void SCPI_RegSetBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits) { 248 | SCPI_RegSet(context, name, SCPI_RegGet(context, name) | bits); 249 | } 250 | 251 | /** 252 | * Clear register bits 253 | * @param name - register name 254 | * @param bits bit mask 255 | */ 256 | void SCPI_RegClearBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits) { 257 | SCPI_RegSet(context, name, SCPI_RegGet(context, name) & ~bits); 258 | } 259 | 260 | /** 261 | * *CLS - This command clears all status data structures in a device. 262 | * For a device which minimally complies with SCPI. (SCPI std 4.1.3.2) 263 | * @param context 264 | * @return 265 | */ 266 | scpi_result_t SCPI_CoreCls(scpi_t * context) { 267 | SCPI_ErrorClear(context); 268 | int i; 269 | for (i = 0; i < SCPI_REG_GROUP_COUNT; ++i) { 270 | scpi_reg_name_t event_reg = scpi_reg_group_details[i].event; 271 | if (event_reg != SCPI_REG_STB) { 272 | SCPI_RegSet(context, event_reg, 0); 273 | } 274 | } 275 | return SCPI_RES_OK; 276 | } 277 | 278 | /** 279 | * *ESE 280 | * @param context 281 | * @return 282 | */ 283 | scpi_result_t SCPI_CoreEse(scpi_t * context) { 284 | int32_t new_ESE; 285 | if (SCPI_ParamInt32(context, &new_ESE, TRUE)) { 286 | SCPI_RegSet(context, SCPI_REG_ESE, (scpi_reg_val_t) new_ESE); 287 | return SCPI_RES_OK; 288 | } 289 | return SCPI_RES_ERR; 290 | } 291 | 292 | /** 293 | * *ESE? 294 | * @param context 295 | * @return 296 | */ 297 | scpi_result_t SCPI_CoreEseQ(scpi_t * context) { 298 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_ESE)); 299 | return SCPI_RES_OK; 300 | } 301 | 302 | /** 303 | * *ESR? 304 | * @param context 305 | * @return 306 | */ 307 | scpi_result_t SCPI_CoreEsrQ(scpi_t * context) { 308 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_ESR)); 309 | SCPI_RegSet(context, SCPI_REG_ESR, 0); 310 | return SCPI_RES_OK; 311 | } 312 | 313 | /** 314 | * *IDN? 315 | * 316 | * field1: MANUFACTURE 317 | * field2: MODEL 318 | * field4: SUBSYSTEMS REVISIONS 319 | * 320 | * example: MANUFACTURE,MODEL,0,01-02-01 321 | * @param context 322 | * @return 323 | */ 324 | scpi_result_t SCPI_CoreIdnQ(scpi_t * context) { 325 | int i; 326 | for (i = 0; i < 4; i++) { 327 | if (context->idn[i]) { 328 | SCPI_ResultMnemonic(context, context->idn[i]); 329 | } else { 330 | SCPI_ResultMnemonic(context, "0"); 331 | } 332 | } 333 | return SCPI_RES_OK; 334 | } 335 | 336 | /** 337 | * *OPC 338 | * @param context 339 | * @return 340 | */ 341 | scpi_result_t SCPI_CoreOpc(scpi_t * context) { 342 | SCPI_RegSetBits(context, SCPI_REG_ESR, ESR_OPC); 343 | return SCPI_RES_OK; 344 | } 345 | 346 | /** 347 | * *OPC? 348 | * @param context 349 | * @return 350 | */ 351 | scpi_result_t SCPI_CoreOpcQ(scpi_t * context) { 352 | /* Operation is always completed */ 353 | SCPI_ResultInt32(context, 1); 354 | return SCPI_RES_OK; 355 | } 356 | 357 | /** 358 | * *RST 359 | * @param context 360 | * @return 361 | */ 362 | scpi_result_t SCPI_CoreRst(scpi_t * context) { 363 | if (context && context->interface && context->interface->reset) { 364 | return context->interface->reset(context); 365 | } 366 | return SCPI_RES_OK; 367 | } 368 | 369 | /** 370 | * *SRE 371 | * @param context 372 | * @return 373 | */ 374 | scpi_result_t SCPI_CoreSre(scpi_t * context) { 375 | int32_t new_SRE; 376 | if (SCPI_ParamInt32(context, &new_SRE, TRUE)) { 377 | SCPI_RegSet(context, SCPI_REG_SRE, (scpi_reg_val_t) new_SRE); 378 | return SCPI_RES_OK; 379 | } 380 | return SCPI_RES_ERR; 381 | } 382 | 383 | /** 384 | * *SRE? 385 | * @param context 386 | * @return 387 | */ 388 | scpi_result_t SCPI_CoreSreQ(scpi_t * context) { 389 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_SRE)); 390 | return SCPI_RES_OK; 391 | } 392 | 393 | /** 394 | * *STB? 395 | * @param context 396 | * @return 397 | */ 398 | scpi_result_t SCPI_CoreStbQ(scpi_t * context) { 399 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_STB)); 400 | return SCPI_RES_OK; 401 | } 402 | 403 | /** 404 | * *TST? 405 | * @param context 406 | * @return 407 | */ 408 | scpi_result_t SCPI_CoreTstQ(scpi_t * context) { 409 | (void) context; 410 | SCPI_ResultInt32(context, 0); 411 | return SCPI_RES_OK; 412 | } 413 | 414 | /** 415 | * *WAI 416 | * @param context 417 | * @return 418 | */ 419 | scpi_result_t SCPI_CoreWai(scpi_t * context) { 420 | (void) context; 421 | /* NOP */ 422 | return SCPI_RES_OK; 423 | } 424 | 425 | -------------------------------------------------------------------------------- /libscpi/src/lexer_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file lexer.h 31 | * @date Thu Mar 21 15:00:58 UTC 2013 32 | * 33 | * @brief SCPI Lexer 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_LEXER_H 39 | #define SCPI_LEXER_H 40 | 41 | #include "scpi/types.h" 42 | #include "utils_private.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | int scpiLex_IsEos(lex_state_t * state) LOCAL; 49 | int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) LOCAL; 50 | int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) LOCAL; 51 | int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 52 | int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 53 | int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 54 | int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) LOCAL; 55 | int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 56 | int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 57 | int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) LOCAL; 58 | int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) LOCAL; 59 | int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) LOCAL; 60 | int scpiLex_Colon(lex_state_t * state, scpi_token_t * token) LOCAL; 61 | int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) LOCAL; 62 | int scpiLex_SpecificCharacter(lex_state_t * state, scpi_token_t * token, char chr) LOCAL; 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif /* SCPI_LEXER_H */ 69 | 70 | -------------------------------------------------------------------------------- /libscpi/src/minimal.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_minimal.c 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief SCPI minimal implementation 34 | * 35 | * 36 | */ 37 | 38 | 39 | #include "scpi/parser.h" 40 | #include "scpi/minimal.h" 41 | #include "scpi/constants.h" 42 | #include "scpi/error.h" 43 | #include "scpi/ieee488.h" 44 | #include "utils_private.h" 45 | 46 | /** 47 | * Command stub function 48 | * @param context 49 | * @return 50 | */ 51 | scpi_result_t SCPI_Stub(scpi_t * context) { 52 | (void) context; 53 | return SCPI_RES_OK; 54 | } 55 | 56 | /** 57 | * Query command stub function 58 | * @param context 59 | * @return 60 | */ 61 | scpi_result_t SCPI_StubQ(scpi_t * context) { 62 | SCPI_ResultInt32(context, 0); 63 | return SCPI_RES_OK; 64 | } 65 | 66 | /** 67 | * SYSTem:VERSion? 68 | * @param context 69 | * @return 70 | */ 71 | scpi_result_t SCPI_SystemVersionQ(scpi_t * context) { 72 | SCPI_ResultMnemonic(context, SCPI_STD_VERSION_REVISION); 73 | return SCPI_RES_OK; 74 | } 75 | 76 | /** 77 | * SYSTem:ERRor[:NEXT]? 78 | * @param context 79 | * @return 80 | */ 81 | scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context) { 82 | scpi_error_t error; 83 | SCPI_ErrorPop(context, &error); 84 | SCPI_ResultError(context, &error); 85 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 86 | SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); 87 | #endif 88 | return SCPI_RES_OK; 89 | } 90 | 91 | /** 92 | * SYSTem:ERRor:COUNt? 93 | * @param context 94 | * @return 95 | */ 96 | scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context) { 97 | SCPI_ResultInt32(context, SCPI_ErrorCount(context)); 98 | 99 | return SCPI_RES_OK; 100 | } 101 | 102 | /** 103 | * STATus:QUEStionable:CONDition? 104 | * @param context 105 | * @return 106 | */ 107 | scpi_result_t SCPI_StatusQuestionableConditionQ(scpi_t * context) { 108 | /* return value */ 109 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUESC)); 110 | 111 | return SCPI_RES_OK; 112 | } 113 | 114 | /** 115 | * STATus:QUEStionable[:EVENt]? 116 | * @param context 117 | * @return 118 | */ 119 | scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context) { 120 | /* return value */ 121 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUES)); 122 | 123 | /* clear register */ 124 | SCPI_RegSet(context, SCPI_REG_QUES, 0); 125 | 126 | return SCPI_RES_OK; 127 | } 128 | 129 | /** 130 | * STATus:QUEStionable:ENABle? 131 | * @param context 132 | * @return 133 | */ 134 | scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context) { 135 | /* return value */ 136 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUESE)); 137 | 138 | return SCPI_RES_OK; 139 | } 140 | 141 | /** 142 | * STATus:QUEStionable:ENABle 143 | * @param context 144 | * @return 145 | */ 146 | scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context) { 147 | int32_t new_QUESE; 148 | if (SCPI_ParamInt32(context, &new_QUESE, TRUE)) { 149 | SCPI_RegSet(context, SCPI_REG_QUESE, (scpi_reg_val_t) new_QUESE); 150 | } 151 | return SCPI_RES_OK; 152 | } 153 | 154 | /** 155 | * STATus:OPERation:CONDition? 156 | * @param context 157 | * @return 158 | */ 159 | scpi_result_t SCPI_StatusOperationConditionQ(scpi_t * context) { 160 | /* return value */ 161 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPERC)); 162 | 163 | return SCPI_RES_OK; 164 | } 165 | 166 | /** 167 | * STATus:OPERation[:EVENt]? 168 | * @param context 169 | * @return 170 | */ 171 | scpi_result_t SCPI_StatusOperationEventQ(scpi_t * context) { 172 | /* return value */ 173 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPER)); 174 | 175 | /* clear register */ 176 | SCPI_RegSet(context, SCPI_REG_OPER, 0); 177 | 178 | return SCPI_RES_OK; 179 | } 180 | 181 | /** 182 | * STATus:OPERation:ENABle? 183 | * @param context 184 | * @return 185 | */ 186 | scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context) { 187 | /* return value */ 188 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPERE)); 189 | 190 | return SCPI_RES_OK; 191 | } 192 | 193 | /** 194 | * STATus:OPERation:ENABle 195 | * @param context 196 | * @return 197 | */ 198 | scpi_result_t SCPI_StatusOperationEnable(scpi_t * context) { 199 | int32_t new_OPERE; 200 | if (SCPI_ParamInt32(context, &new_OPERE, TRUE)) { 201 | SCPI_RegSet(context, SCPI_REG_OPERE, (scpi_reg_val_t) new_OPERE); 202 | } 203 | return SCPI_RES_OK; 204 | } 205 | 206 | /** 207 | * STATus:PRESet 208 | * @param context 209 | * @return 210 | */ 211 | scpi_result_t SCPI_StatusPreset(scpi_t * context) { 212 | /* clear STATUS:... */ 213 | SCPI_RegSet(context, SCPI_REG_QUES, 0); 214 | return SCPI_RES_OK; 215 | } 216 | -------------------------------------------------------------------------------- /libscpi/src/parser_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file parser_private.h 31 | * 32 | * @brief SCPI Parser private definitions 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_PARSER_PRIVATE_H 38 | #define SCPI_PARSER_PRIVATE_H 39 | 40 | #include "scpi/types.h" 41 | #include "utils_private.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 48 | int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) LOCAL; 49 | int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, char * buffer, int len) LOCAL; 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif /* SCPI_PARSER_PRIVATE_H */ 56 | 57 | -------------------------------------------------------------------------------- /libscpi/src/scpi.g: -------------------------------------------------------------------------------- 1 | grammar scpi; 2 | 3 | terminatedProgramMessage 4 | : programMessage NL? EOF 5 | ; 6 | 7 | programMessage 8 | : programMessageUnit (SEMICOLON programMessageUnit)* 9 | ; 10 | 11 | 12 | programMessageUnit 13 | : WS* programHeader (WS programData (COMMA programData)*)? 14 | ; 15 | 16 | programHeader 17 | : compoundProgramHeader 18 | | commonProgramHeader 19 | ; 20 | 21 | compoundProgramHeader 22 | : COLON? PROGRAM_MNEMONIC (COLON PROGRAM_MNEMONIC)* QUESTION? 23 | ; 24 | 25 | commonProgramHeader 26 | : STAR PROGRAM_MNEMONIC QUESTION? 27 | ; 28 | 29 | programDataSeparator 30 | : WS* 31 | ; 32 | 33 | programData 34 | : WS* programDataType WS* 35 | ; 36 | 37 | programDataType 38 | : nondecimalNumericProgramData 39 | | characterProgramData 40 | | decimalNumericProgramData 41 | | stringProgramData 42 | | arbitraryBlockProgramData 43 | | expressionProgramData 44 | // | suffixProgramData 45 | ; 46 | 47 | nondecimalNumericProgramData 48 | : HEXNUM 49 | | OCTNUM 50 | | BINNUM 51 | ; 52 | 53 | characterProgramData 54 | : PROGRAM_MNEMONIC 55 | ; 56 | 57 | decimalNumericProgramData 58 | : DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX 59 | ; 60 | 61 | //suffixProgramData 62 | // : PROGRAM_MNEMONIC//SUFFIX_PROGRAM_DATA 63 | // ; 64 | 65 | stringProgramData 66 | : SINGLE_QUOTE_PROGRAM_DATA 67 | | DOUBLE_QUOTE_PROGRAM_DATA 68 | ; 69 | 70 | expressionProgramData 71 | : PROGRAM_EXPRESSION 72 | ; 73 | 74 | // support only nonzero prefix 75 | arbitraryBlockProgramData 76 | : SHARP NONZERO_DIGIT NUMBER .* 77 | ; 78 | 79 | PROGRAM_MNEMONIC : ALPHA (ALPHA | DIGIT | UNDERSCORE)*; 80 | HEXNUM : SHARP H HEXDIGIT*; 81 | BINNUM : SHARP Q OCTDIGIT*; 82 | OCTNUM : SHARP B BINDIGIT*; 83 | UNDERSCORE : '_'; 84 | SEMICOLON : ';'; 85 | QUESTION : '?'; 86 | COLON : ':'; 87 | COMMA : ','; 88 | STAR : '*'; 89 | NL : '\r'? '\n' ; 90 | WS : (SPACE | TAB); 91 | 92 | DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX : DECIMAL_NUMERIC_PROGRAM_DATA WS* (SUFFIX_PROGRAM_DATA)?; 93 | fragment DECIMAL_NUMERIC_PROGRAM_DATA : MANTISA WS* (EXPONENT)?; 94 | SINGLE_QUOTE_PROGRAM_DATA : SINGLE_QUOTE ( (NON_SINGLE_QUOTE) | (SINGLE_QUOTE SINGLE_QUOTE))* SINGLE_QUOTE; 95 | DOUBLE_QUOTE_PROGRAM_DATA : DOUBLE_QUOTE ( (NON_DOUBLE_QUOTE) | (DOUBLE_QUOTE DOUBLE_QUOTE))* DOUBLE_QUOTE; 96 | //SUFFIX_PROGRAM_DATA : SLASH? (ALPHA+ (MINUS? DIGIT)?) ((SLASH | DOT) (ALPHA+ (MINUS? DIGIT)?))*; 97 | fragment SUFFIX_PROGRAM_DATA : SLASH? ALPHA+ ((SLASH | DOT) ALPHA+)*; 98 | //fragment SUFFIX_PROGRAM_DATA : ALPHA+; 99 | 100 | fragment PROGRAM_EXPRESSION_CHARACTER : (SPACE | '!' | '$'..'&' | '*'..':' | '<' ..'~'); 101 | PROGRAM_EXPRESSION : LBRACKET PROGRAM_EXPRESSION_CHARACTER RBRACKET; 102 | 103 | fragment PLUSMN : (PLUS | MINUS); 104 | fragment MANTISA : PLUSMN? ( (NUMBER) | (NUMBER DOT NUMBER?) | (DOT NUMBER)); 105 | 106 | //fragment EXPONENT : WS* E WS* PLUSMN? NUMBER; 107 | fragment EXPONENT : E WS* PLUSMN? NUMBER; 108 | 109 | fragment NUMBER : DIGIT+; 110 | 111 | fragment LBRACKET : '('; 112 | fragment RBRACKET : ')'; 113 | 114 | fragment ALPHA : ('a'..'z'|'A'..'Z'); 115 | fragment DIGIT : ('0'..'9'); 116 | fragment NONZERO_DIGIT : ('1'..'9'); 117 | 118 | fragment HEXDIGIT : (DIGIT | 'a'..'f' | 'A'..'F'); 119 | fragment OCTDIGIT : ('0'..'7'); 120 | fragment BINDIGIT : ('0' | '1'); 121 | 122 | fragment SHARP : '#'; 123 | 124 | fragment E : ('E'|'e'); 125 | fragment H : ('H'|'h'); 126 | fragment Q : ('Q'|'q'); 127 | fragment B : ('B'|'b'); 128 | 129 | fragment SPACE : ' '; 130 | fragment TAB : '\t'; 131 | 132 | fragment PLUS : '+'; 133 | fragment MINUS : '-'; 134 | fragment DOT : '.'; 135 | fragment SLASH : '/'; 136 | fragment SINGLE_QUOTE : '\''; 137 | fragment DOUBLE_QUOTE : '"'; 138 | fragment NON_SINGLE_QUOTE : ~SINGLE_QUOTE; 139 | fragment NON_DOUBLE_QUOTE : ~DOUBLE_QUOTE; 140 | 141 | 142 | -------------------------------------------------------------------------------- /libscpi/src/utils_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * @file scpi_utils.h 31 | * @date Thu Nov 15 10:58:45 UTC 2012 32 | * 33 | * @brief Conversion routines and string manipulation routines 34 | * 35 | * 36 | */ 37 | 38 | #ifndef SCPI_UTILS_PRIVATE_H 39 | #define SCPI_UTILS_PRIVATE_H 40 | 41 | #include 42 | #include "scpi/config.h" 43 | #include "scpi/types.h" 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | #if defined(__GNUC__) && (__GNUC__ >= 4) 50 | #define LOCAL __attribute__((visibility ("hidden"))) 51 | #else 52 | #define LOCAL 53 | #endif 54 | 55 | char * strnpbrk(const char *str, size_t size, const char *set) LOCAL; 56 | scpi_bool_t compareStr(const char * str1, size_t len1, const char * str2, size_t len2) LOCAL; 57 | scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) LOCAL; 58 | size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; 59 | size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; 60 | size_t strBaseToInt32(const char * str, int32_t * val, int8_t base) LOCAL; 61 | size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) LOCAL; 62 | size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) LOCAL; 63 | size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) LOCAL; 64 | size_t strToFloat(const char * str, float * val) LOCAL; 65 | size_t strToDouble(const char * str, double * val) LOCAL; 66 | scpi_bool_t locateText(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; 67 | scpi_bool_t locateStr(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; 68 | size_t skipWhitespace(const char * cmd, size_t len) LOCAL; 69 | scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len, int32_t * num) LOCAL; 70 | scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value) LOCAL; 71 | scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) LOCAL; 72 | 73 | #define SCPI_DTOSTRE_UPPERCASE 1 74 | #define SCPI_DTOSTRE_ALWAYS_SIGN 2 75 | #define SCPI_DTOSTRE_PLUS_SIGN 4 76 | char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags); 77 | 78 | scpi_array_format_t SCPI_GetNativeFormat(void); 79 | uint16_t SCPI_Swap16(uint16_t val); 80 | uint32_t SCPI_Swap32(uint32_t val); 81 | uint64_t SCPI_Swap64(uint64_t val); 82 | 83 | #if !HAVE_STRNLEN 84 | size_t BSD_strnlen(const char *s, size_t maxlen) LOCAL; 85 | #endif 86 | 87 | #if !HAVE_STRNCASECMP && !HAVE_STRNICMP 88 | int OUR_strncasecmp(const char *s1, const char *s2, size_t n) LOCAL; 89 | #endif 90 | 91 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE 92 | void scpiheap_init(scpi_error_info_heap_t * heap, char * error_info_heap, size_t error_info_heap_length); 93 | char * scpiheap_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) LOCAL; 94 | void scpiheap_free(scpi_error_info_heap_t * heap, char *s, scpi_bool_t rollback) LOCAL; 95 | scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap, const char *s1, size_t * len1, const char ** s2, size_t * len2) LOCAL; 96 | #endif 97 | 98 | #if !HAVE_STRNDUP 99 | char *OUR_strndup(const char *s, size_t n); 100 | #endif 101 | 102 | #ifndef min 103 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 104 | #endif 105 | 106 | #ifndef max 107 | #define max(a, b) (((a) > (b)) ? (a) : (b)) 108 | #endif 109 | 110 | #if 0 111 | #define max(a,b) \ 112 | ({ __typeof__ (a) _a = (a); \ 113 | __typeof__ (b) _b = (b); \ 114 | _a > _b ? _a : _b; }) 115 | 116 | #define min(a,b) \ 117 | ({ __typeof__ (a) _a = (a); \ 118 | __typeof__ (b) _b = (b); \ 119 | _a < _b ? _a : _b; }) 120 | 121 | #endif 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif /* SCPI_UTILS_PRIVATE_H */ 128 | 129 | -------------------------------------------------------------------------------- /libscpi/test/test_fifo.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * BSD 2-Clause License 3 | * 4 | * Copyright (c) 2012-2018, Jan Breuer 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include "CUnit/Basic.h" 32 | 33 | #include "../src/fifo_private.h" 34 | 35 | /* 36 | * CUnit Test Suite 37 | */ 38 | 39 | static int init_suite(void) { 40 | return 0; 41 | } 42 | 43 | static int clean_suite(void) { 44 | return 0; 45 | } 46 | 47 | static void testFifo() { 48 | scpi_fifo_t fifo; 49 | scpi_error_t fifo_data[4]; 50 | fifo_init(&fifo, fifo_data, 4); 51 | scpi_error_t value; 52 | int16_t count_value; 53 | 54 | #define TEST_FIFO_COUNT(n) \ 55 | do { \ 56 | fifo_count(&fifo, &count_value); \ 57 | CU_ASSERT_EQUAL(count_value, n); \ 58 | } while(0) \ 59 | 60 | 61 | TEST_FIFO_COUNT(0); 62 | CU_ASSERT_TRUE(fifo_is_empty(&fifo)); 63 | CU_ASSERT_FALSE(fifo_is_full(&fifo)); 64 | 65 | value.error_code = 1; 66 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 67 | TEST_FIFO_COUNT(1); 68 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 69 | CU_ASSERT_FALSE(fifo_is_full(&fifo)); 70 | 71 | value.error_code = 2; 72 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 73 | TEST_FIFO_COUNT(2); 74 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 75 | CU_ASSERT_FALSE(fifo_is_full(&fifo)); 76 | 77 | value.error_code = 3; 78 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 79 | TEST_FIFO_COUNT(3); 80 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 81 | CU_ASSERT_FALSE(fifo_is_full(&fifo)); 82 | 83 | value.error_code = 4; 84 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 85 | TEST_FIFO_COUNT(4); 86 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 87 | CU_ASSERT_TRUE(fifo_is_full(&fifo)); 88 | 89 | CU_ASSERT_EQUAL(fifo.data[0].error_code, 1); 90 | CU_ASSERT_EQUAL(fifo.data[1].error_code, 2); 91 | CU_ASSERT_EQUAL(fifo.data[2].error_code, 3); 92 | CU_ASSERT_EQUAL(fifo.data[3].error_code, 4); 93 | 94 | value.error_code = 5; 95 | CU_ASSERT_FALSE(fifo_add(&fifo, &value)); 96 | TEST_FIFO_COUNT(4); 97 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 98 | CU_ASSERT_TRUE(fifo_is_full(&fifo)); 99 | 100 | CU_ASSERT_EQUAL(fifo.data[0].error_code, 1); 101 | CU_ASSERT_EQUAL(fifo.data[1].error_code, 2); 102 | CU_ASSERT_EQUAL(fifo.data[2].error_code, 3); 103 | CU_ASSERT_EQUAL(fifo.data[3].error_code, 4); 104 | 105 | CU_ASSERT_TRUE(fifo_remove_last(&fifo, &value)); 106 | CU_ASSERT_EQUAL(value.error_code, 4); 107 | TEST_FIFO_COUNT(3); 108 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 109 | CU_ASSERT_FALSE(fifo_is_full(&fifo)); 110 | 111 | value.error_code = 6; 112 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 113 | TEST_FIFO_COUNT(4); 114 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 115 | CU_ASSERT_TRUE(fifo_is_full(&fifo)); 116 | 117 | CU_ASSERT_EQUAL(fifo.data[0].error_code, 1); 118 | CU_ASSERT_EQUAL(fifo.data[1].error_code, 2); 119 | CU_ASSERT_EQUAL(fifo.data[2].error_code, 3); 120 | CU_ASSERT_EQUAL(fifo.data[3].error_code, 6); 121 | 122 | CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); 123 | CU_ASSERT_EQUAL(value.error_code, 1); 124 | TEST_FIFO_COUNT(3); 125 | CU_ASSERT_FALSE(fifo_is_empty(&fifo)); 126 | CU_ASSERT_FALSE(fifo_is_full(&fifo)); 127 | 128 | value.error_code = 7; 129 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 130 | TEST_FIFO_COUNT(4); 131 | 132 | CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); 133 | CU_ASSERT_EQUAL(value.error_code, 2); 134 | TEST_FIFO_COUNT(3); 135 | 136 | CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); 137 | CU_ASSERT_EQUAL(value.error_code, 3); 138 | TEST_FIFO_COUNT(2); 139 | 140 | value.error_code = 10; 141 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 142 | TEST_FIFO_COUNT(3); 143 | 144 | value.error_code = 11; 145 | CU_ASSERT_TRUE(fifo_add(&fifo, &value)); 146 | TEST_FIFO_COUNT(4); 147 | 148 | CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); 149 | CU_ASSERT_EQUAL(value.error_code, 6); 150 | TEST_FIFO_COUNT(3); 151 | 152 | CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); 153 | CU_ASSERT_EQUAL(value.error_code, 7); 154 | TEST_FIFO_COUNT(2); 155 | 156 | CU_ASSERT_TRUE(fifo_remove_last(&fifo, &value)); 157 | CU_ASSERT_EQUAL(value.error_code, 11); 158 | TEST_FIFO_COUNT(1); 159 | 160 | CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); 161 | CU_ASSERT_EQUAL(value.error_code, 10); 162 | TEST_FIFO_COUNT(0); 163 | 164 | CU_ASSERT_FALSE(fifo_remove(&fifo, &value)); 165 | TEST_FIFO_COUNT(0); 166 | 167 | CU_ASSERT_FALSE(fifo_remove_last(&fifo, NULL)); 168 | } 169 | 170 | int main() { 171 | unsigned int result; 172 | CU_pSuite pSuite = NULL; 173 | 174 | /* Initialize the CUnit test registry */ 175 | if (CUE_SUCCESS != CU_initialize_registry()) 176 | return CU_get_error(); 177 | 178 | /* Add a suite to the registry */ 179 | pSuite = CU_add_suite("FIFO", init_suite, clean_suite); 180 | if (NULL == pSuite) { 181 | CU_cleanup_registry(); 182 | return CU_get_error(); 183 | } 184 | 185 | /* Add the tests to the suite */ 186 | if ((NULL == CU_add_test(pSuite, "test fifo", testFifo))) { 187 | CU_cleanup_registry(); 188 | return CU_get_error(); 189 | } 190 | 191 | /* Run all tests using the CUnit Basic interface */ 192 | CU_basic_set_mode(CU_BRM_VERBOSE); 193 | CU_basic_run_tests(); 194 | result = CU_get_number_of_tests_failed(); 195 | CU_cleanup_registry(); 196 | return result ? result : CU_get_error(); 197 | } 198 | --------------------------------------------------------------------------------