AMU Library 3.0
C/C++ library for communicating with AMU (Aerospace Measurement Unit) devices
Loading...
Searching...
No Matches
expression.c
Go to the documentation of this file.
1/*-
2 * Copyright (c) 2012-2015 Jan Breuer,
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
35
36#include "expression.h"
37#include "error.h"
38#include "parser.h"
39
40#include "lexer_private.h"
41
52static scpi_expr_result_t numericRange(lex_state_t * state, scpi_bool_t * isRange, scpi_token_t * valueFrom, scpi_token_t * valueTo) {
53 if (scpiLex_DecimalNumericProgramData(state, valueFrom)) {
54 if (scpiLex_Colon(state, valueTo)) {
55 *isRange = TRUE;
56 if (scpiLex_DecimalNumericProgramData(state, valueTo)) {
57 return SCPI_EXPR_OK;
58 } else {
59 return SCPI_EXPR_ERROR;
60 }
61 } else {
62 *isRange = FALSE;
63 return SCPI_EXPR_OK;
64 }
65 }
66
67 return SCPI_EXPR_NO_MORE;
68}
69
83scpi_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) {
84 lex_state_t lex;
85 int i;
87
88 if (!isRange || !valueFrom || !valueTo || !param) {
90 return SCPI_EXPR_ERROR;
91 }
92
93 if (param->type != SCPI_TOKEN_PROGRAM_EXPRESSION) {
95 return SCPI_EXPR_ERROR;
96 }
97
98 lex.buffer = param->ptr + 1;
99 lex.pos = lex.buffer;
100 lex.len = param->len - 2;
101
102 for (i = 0; i <= index; i++) {
103 res = numericRange(&lex, isRange, valueFrom, valueTo);
104 if (res != SCPI_EXPR_OK) {
105 break;
106 }
107 if (i != index) {
108 if (!scpiLex_Comma(&lex, valueFrom)) {
110 break;
111 }
112 }
113 }
114
115 if (res == SCPI_EXPR_ERROR) {
117 }
118 return res;
119}
120
134scpi_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_bool_t range = FALSE;
137 scpi_parameter_t paramFrom;
138 scpi_parameter_t paramTo;
139
140 res = SCPI_ExprNumericListEntry(context, param, index, &range, &paramFrom, &paramTo);
141 if (res == SCPI_EXPR_OK) {
142 *isRange = range;
143 SCPI_ParamToInt32(context, &paramFrom, valueFrom);
144 if (range) {
145 SCPI_ParamToInt32(context, &paramTo, valueTo);
146 }
147 }
148
149 return res;
150}
151
165scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo) {
167 scpi_bool_t range = FALSE;
168 scpi_parameter_t paramFrom;
169 scpi_parameter_t paramTo;
170
171 res = SCPI_ExprNumericListEntry(context, param, index, &range, &paramFrom, &paramTo);
172 if (res == SCPI_EXPR_OK) {
173 *isRange = range;
174 SCPI_ParamToDouble(context, &paramFrom, valueFrom);
175 if (range) {
176 SCPI_ParamToDouble(context, &paramTo, valueTo);
177 }
178 }
179
180 return res;
181}
182
191static scpi_expr_result_t channelSpec(scpi_t * context, lex_state_t * state, int32_t * values, size_t length, size_t * dimensions) {
192 scpi_parameter_t param;
193 size_t i = 0;
194 while (scpiLex_DecimalNumericProgramData(state, &param)) {
195 if (i < length) {
196 SCPI_ParamToInt32(context, &param, &values[i]);
197 }
198
199 if (scpiLex_SpecificCharacter(state, &param, '!')) {
200 i++;
201 } else {
202 *dimensions = i + 1;
203 return SCPI_EXPR_OK;
204 }
205 }
206
207 if (i == 0) {
208 return SCPI_EXPR_NO_MORE;
209 } else {
210 /* there was at least one number followed by !, but after ! was not another number */
211 return SCPI_EXPR_ERROR;
212 }
213}
214
225static 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) {
226 scpi_token_t token;
228 size_t fromDimensions;
229 size_t toDimensions;
230
231 err = channelSpec(context, state, valuesFrom, length, &fromDimensions);
232 if (err == SCPI_EXPR_OK) {
233 if (scpiLex_Colon(state, &token)) {
234 *isRange = TRUE;
235 err = channelSpec(context, state, valuesTo, length, &toDimensions);
236 if (err != SCPI_EXPR_OK) {
237 return SCPI_EXPR_ERROR;
238 }
239 if (fromDimensions != toDimensions) {
240 return SCPI_EXPR_ERROR;
241 }
242 *dimensions = fromDimensions;
243 } else {
244 *isRange = FALSE;
245 *dimensions = fromDimensions;
246 return SCPI_EXPR_OK;
247 }
248 } else if (err == SCPI_EXPR_NO_MORE) {
249 err = SCPI_EXPR_ERROR;
250 }
251
252 return err;
253}
254
266scpi_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) {
267 lex_state_t lex;
268 int i;
270 scpi_token_t token;
271
272 if (!isRange || !param || !dimensions || (length && (!valuesFrom || !valuesTo))) {
274 return SCPI_EXPR_ERROR;
275 }
276
277 if (param->type != SCPI_TOKEN_PROGRAM_EXPRESSION) {
279 return SCPI_EXPR_ERROR;
280 }
281
282 lex.buffer = param->ptr + 1;
283 lex.pos = lex.buffer;
284 lex.len = param->len - 2;
285
286 /* detect channel list expression */
287 if (!scpiLex_SpecificCharacter(&lex, &token, '@')) {
289 return SCPI_EXPR_ERROR;
290 }
291
292 for (i = 0; i <= index; i++) {
293 res = channelRange(context, &lex, isRange, valuesFrom, valuesTo, (i == index) ? length : 0, dimensions);
294 if (res != SCPI_EXPR_OK) {
295 break;
296 }
297 if (i != index) {
298 if (!scpiLex_Comma(&lex, &token)) {
300 break;
301 }
302 }
303 }
304
305 if (res == SCPI_EXPR_ERROR) {
307 }
308 if (res == SCPI_EXPR_NO_MORE) {
309 if (!scpiLex_IsEos(&lex)) {
310 res = SCPI_EXPR_ERROR;
312 }
313 }
314 return res;
315}
void SCPI_ErrorPush(scpi_t *context, int16_t err)
Definition error.c:202
@ SCPI_ERROR_SYSTEM_ERROR
Definition error.h:193
@ SCPI_ERROR_EXPRESSION_PARSING_ERROR
Definition error.h:193
@ SCPI_ERROR_DATA_TYPE_ERROR
Definition error.h:193
static scpi_expr_result_t numericRange(lex_state_t *state, scpi_bool_t *isRange, scpi_token_t *valueFrom, scpi_token_t *valueTo)
Definition expression.c:52
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)
Definition expression.c:266
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)
Definition expression.c:83
static scpi_expr_result_t channelSpec(scpi_t *context, lex_state_t *state, int32_t *values, size_t length, size_t *dimensions)
Definition expression.c:191
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)
Definition expression.c:225
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)
Definition expression.c:134
scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t *context, scpi_parameter_t *param, int index, scpi_bool_t *isRange, double *valueFrom, double *valueTo)
Definition expression.c:165
Expressions handling.
@ SCPI_EXPR_OK
Definition expression.h:46
@ SCPI_EXPR_ERROR
Definition expression.h:47
@ SCPI_EXPR_NO_MORE
Definition expression.h:48
enum _scpi_expr_result_t scpi_expr_result_t
Definition expression.h:50
int scpiLex_DecimalNumericProgramData(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:508
int scpiLex_SpecificCharacter(lex_state_t *state, scpi_token_t *token, char chr)
Definition lexer.c:897
int scpiLex_IsEos(lex_state_t *state)
Definition lexer.c:98
int scpiLex_Comma(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:837
int scpiLex_Colon(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:877
scpi_bool_t SCPI_ParamToDouble(scpi_t *context, scpi_parameter_t *parameter, double *value)
Definition parser.c:999
scpi_bool_t SCPI_ParamToInt32(scpi_t *context, scpi_parameter_t *parameter, int32_t *value)
Definition parser.c:922
bool scpi_bool_t
Definition types.h:67
#define TRUE
Definition types.h:63
#define FALSE
Definition types.h:60
@ SCPI_TOKEN_PROGRAM_EXPRESSION
Definition types.h:163
scpi_token_t scpi_parameter_t
Definition types.h:362