├── .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 |  [](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 | SCPI version | v1999.0 |
33 |
34 |
35 |
36 | **Supported command patterns**
37 |
38 | Feature | Pattern example |
39 | Short and long form | MEASure means MEAS or MEASURE command |
40 | Common command | *CLS |
41 |
Compound command | CONFigure:VOLTage |
42 |
Query command | MEASure:VOLTage? , *IDN? |
43 | Optional keywords | MEASure:VOLTage[:DC]? |
44 | Numeric keyword suffix Multiple identical capabilities | OUTput#:FREQuency |
45 |
46 |
47 | **Supported parameter types**
48 |
49 | Type | Example |
50 | Decimal | 10 , 10.5 |
51 | Decimal with suffix | -5.5 V , 1.5 KOHM |
52 | Hexadecimal | #HFF |
53 | Octal | #Q77 |
54 | Binary | #B11 |
55 | String | "text" , 'text' |
56 | Arbitrary block | #12AB |
57 | Program expression | (1) |
58 | Numeric list | (1,2:50,80) |
59 | Channel list | (@1!2:3!4,5!6) |
60 | Character data | MINimum , DEFault , INFinity |
61 |
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 |
--------------------------------------------------------------------------------