AMU Library 3.0
C/C++ library for communicating with AMU (Aerospace Measurement Unit) devices
Loading...
Searching...
No Matches
parser.c
Go to the documentation of this file.
1/*-
2 * Copyright (c) 2012-2013 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
36
37#include <ctype.h>
38#include <string.h>
39
40#include "config.h"
41#include "parser.h"
42#include "parser_private.h"
43#include "lexer_private.h"
44#include "expression.h"
45#include "error.h"
46#include "constants.h"
47#include "utils.h"
48
49#ifdef __AMU_SCPI_USE_PROGMEM__
50#include <avr/pgmspace.h>
51#endif
52
60static size_t writeData(scpi_t * context, const char * data, size_t len) {
61 if (len > 0) {
62 return context->interface->write(context, data, len);
63 } else {
64 return 0;
65 }
66}
67
73static int flushData(scpi_t * context) {
74 if (context && context->interface && context->interface->flush) {
75 return context->interface->flush(context);
76 } else {
77 return SCPI_RES_OK;
78 }
79}
80
86static size_t writeDelimiter(scpi_t * context) {
87 if (context->output_count > 0) {
88 return writeData(context, ",", 1);
89 } else {
90 return 0;
91 }
92}
93
99static size_t writeNewLine(scpi_t * context) {
100 if (context->output_count > 0) {
101 size_t len;
102#ifndef SCPI_LINE_ENDING
103#error no termination character defined
104#endif
105 len = writeData(context, SCPI_LINE_ENDING, strlen(SCPI_LINE_ENDING));
106 flushData(context);
107 return len;
108 } else {
109 return 0;
110 }
111}
112
118static size_t writeSemicolon(scpi_t * context) {
119 if (context->output_count > 0) {
120 return writeData(context, ";", 1);
121 } else {
122 return 0;
123 }
124}
125
130static scpi_bool_t processCommand(scpi_t * context) {
131 const scpi_command_t * cmd = context->param_list.cmd;
132 lex_state_t * state = &context->param_list.lex_state;
133 scpi_bool_t result = TRUE;
134
135 /* conditionaly write ; */
136 writeSemicolon(context);
137
138 context->cmd_error = FALSE;
139 context->output_count = 0;
140 context->input_count = 0;
141 context->arbitrary_reminding = 0;
142
143 /* if callback exists - call command callback */
144 if (cmd->callback != NULL) {
145 // original code wrap
146 if ((cmd->callback(context) != SCPI_RES_OK)) {
147 if (!context->cmd_error) {
149 }
150 result = FALSE;
151 }
152 else {
153 if (context->cmd_error) {
154 result = FALSE;
155 }
156 }
157
158 }
159 /* set error if command callback did not read all parameters */
160 if (state->pos < (state->buffer + state->len) && !context->cmd_error) {
162 result = FALSE;
163 }
164
165 return result;
166}
167
173
174static scpi_bool_t findCommandHeader(scpi_t* context, const char* header, int len) {
175 int32_t i;
176
177#ifdef __AMU_SCPI_USE_PROGMEM__
178 PGM_P pattern;
179
180 for (i = 0; (pattern = (PGM_P)pgm_read_word(&context->def_cmdlist[i].pattern)) != 0; i++) {
181 strncpy_P(context->param_list.cmd_pattern_s, pattern, SCPI_MAX_CMD_PATTERN_SIZE);
182 context->param_list.cmd_pattern_s[SCPI_MAX_CMD_PATTERN_SIZE] = '\0';
183
184 if (matchCommand(context->param_list.cmd_pattern_s, header, len, NULL, 0, 0, &context->query)) {
185 context->param_list.cmd_s.callback = (scpi_command_callback_t)pgm_read_word(&context->def_cmdlist[i].callback);
186 context->param_list.cmd_s.tag = (int32_t)pgm_read_dword(&context->def_cmdlist[i].tag);
187 return TRUE;
188 }
189 }
190
191 if (context->aux_cmdlist != NULL) {
192
193 for (i = 0; (pattern = (PGM_P)pgm_read_word(&context->aux_cmdlist[i].pattern)) != 0; i++) {
194 strncpy_P(context->param_list.cmd_pattern_s, pattern, SCPI_MAX_CMD_PATTERN_SIZE);
195 context->param_list.cmd_pattern_s[SCPI_MAX_CMD_PATTERN_SIZE] = '\0';
196
197 if (matchCommand(context->param_list.cmd_pattern_s, header, len, NULL, 0, 0, &context->query)) {
198 context->param_list.cmd_s.callback = (scpi_command_callback_t)pgm_read_word(&context->aux_cmdlist[i].callback);
199 context->param_list.cmd_s.tag = (int32_t)pgm_read_dword(&context->aux_cmdlist[i].tag);
200 return TRUE;
201 }
202 }
203 }
204#else
205 const scpi_command_t * cmd;
206
207 for (i = 0; context->def_cmdlist[i].pattern != NULL; i++) {
208 cmd = &context->def_cmdlist[i];
209 if (matchCommand(cmd->pattern, header, len, NULL, 0, 0, &context->query)) {
210 context->param_list.cmd = cmd;
211 return TRUE;
212 }
213 }
214
215 if (context->aux_cmdlist != NULL) {
216 for (i = 0; context->aux_cmdlist[i].pattern != NULL; i++) {
217 cmd = &context->aux_cmdlist[i];
218 if (matchCommand(cmd->pattern, header, len, NULL, 0, 0, &context->query)) {
219 context->param_list.cmd = cmd;
220 return TRUE;
221 }
222 }
223 }
224#endif
225
226 return FALSE;
227}
228
229//static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len) {
230 //int32_t i;
231 //
232 //
233 //uint_farptr_t p_cmd = context->cmdlist;
234 //uint_farptr_t p_pattern = context->cmdpatterns;
235 //uint16_t pattern_length;
236 //
237 //for (i = 0;
238 //(pattern_length = pgm_read_word_far(p_cmd + offsetof(scpi_command_t, pattern))) != 0;
239 //++i, p_cmd += sizeof(scpi_command_t), p_pattern += pattern_length)
240 //{
241 //strncpy_PF(context->param_list.cmd_pattern_s, p_pattern, pattern_length);
242 //context->param_list.cmd_pattern_s[pattern_length] = '\0';
243 //
244 //if (matchCommand(context->param_list.cmd_pattern_s, header, len, NULL, 0, 0)) {
245 //context->param_list.cmd_s.callback = (scpi_command_callback_t)pgm_read_word_far(p_cmd + offsetof(scpi_command_t, callback));
246 //
247 //return FALSE;
248//}
249
257scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len) {
258 scpi_bool_t result = TRUE;
259 scpi_parser_state_t * state;
260 int r;
261 scpi_token_t cmd_prev = {SCPI_TOKEN_UNKNOWN, NULL, 0};
262
263 if (context == NULL) {
264 return FALSE;
265 }
266
267 state = &context->parser_state;
268 context->output_count = 0;
269 context->query = false;
270 context->has_param = false;
271
272 while (1) {
273 r = scpiParser_detectProgramMessageUnit(state, data, len);
274
275 if (state->programHeader.type == SCPI_TOKEN_INVALID) {
277 result = FALSE;
278 } else if (state->programHeader.len > 0) {
279
280 composeCompoundCommand(&cmd_prev, &state->programHeader);
281
282 if (findCommandHeader(context, state->programHeader.ptr, state->programHeader.len)) {
283
284 context->param_list.lex_state.buffer = state->programData.ptr;
285 context->param_list.lex_state.pos = context->param_list.lex_state.buffer;
286 context->param_list.lex_state.len = state->programData.len;
287 context->param_list.cmd_raw.data = state->programHeader.ptr;
288 context->param_list.cmd_raw.position = 0;
289 context->param_list.cmd_raw.length = state->programHeader.len;
290
291 result &= processCommand(context);
292
293 cmd_prev = state->programHeader;
294 } else {
295 /* place undefined header with error */
296 /* calculate length of errornouse header and trim \r\n */
297 size_t r2 = r;
298 while (r2 > 0 && (data[r2 - 1] == '\r' || data[r2 - 1] == '\n')) r2--;
299 // Debug: Command not found
300
302 result = FALSE;
303 }
304 }
305
306 if (r < len) {
307 data += r;
308 len -= r;
309 } else {
310 break;
311 }
312
313 }
314
315 /* conditionaly write new line */
316 writeNewLine(context);
317
318 return result;
319}
320
321
337void SCPI_Init(scpi_t * context,
338 const scpi_command_t * def_cmds,
339 scpi_interface_t * interface,
340 const scpi_unit_def_t * units,
341 const char * idn1, const char * idn2, const char * idn3, const char * idn4,
342 char * input_buffer, size_t input_buffer_length,
343 scpi_error_t * error_queue_data, int16_t error_queue_size) {
344 memset(context, 0, sizeof (*context));
345 context->def_cmdlist = def_cmds;
346 context->aux_cmdlist = NULL;
347 context->interface = interface;
348 context->units = units;
349 context->idn[0] = idn1;
350 context->idn[1] = idn2;
351 context->idn[2] = idn3;
352 context->idn[3] = idn4;
353 context->buffer.data = input_buffer;
354 context->buffer.length = input_buffer_length;
355 context->buffer.position = 0;
356
357#ifdef __AMU_SCPI_USE_PROGMEM__
358 //Initialize cmd_s for using PROGMEM SCPI commands
359 context->param_list.cmd_s.pattern = context->param_list.cmd_pattern_s;
360 context->param_list.cmd = &context->param_list.cmd_s;
361#endif
362
363 SCPI_ErrorInit(context, error_queue_data, error_queue_size);
364}
365
366#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE
367
375void SCPI_InitHeap(scpi_t * context,
376 char * error_info_heap, size_t error_info_heap_length) {
377 scpiheap_init(&context->error_info_heap, error_info_heap, error_info_heap_length);
378}
379#endif
380
391
392
393
394scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len) {
395 scpi_bool_t result = TRUE;
396 size_t totcmdlen = 0;
397 int cmdlen = 0;
398
399 if (len == 0) {
400 context->buffer.data[context->buffer.position] = 0;
401 result = SCPI_Parse(context, context->buffer.data, context->buffer.position);
402 context->buffer.position = 0;
403 } else {
404 int buffer_free;
405
406 buffer_free = context->buffer.length - context->buffer.position;
407 if (len > (buffer_free - 1)) {
408 /* Input buffer overrun - invalidate buffer */
409 context->buffer.position = 0;
410 context->buffer.data[context->buffer.position] = 0;
412 return FALSE;
413 }
414 memcpy(&context->buffer.data[context->buffer.position], data, len);
415 context->buffer.position += len;
416 context->buffer.data[context->buffer.position] = 0;
417
418
419 while (1) {
420 cmdlen = scpiParser_detectProgramMessageUnit(&context->parser_state, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen);
421 totcmdlen += cmdlen;
422
423 if (context->parser_state.termination == SCPI_MESSAGE_TERMINATION_NL) {
424 result = SCPI_Parse(context, context->buffer.data, totcmdlen);
425 memmove(context->buffer.data, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen);
426 context->buffer.position -= totcmdlen;
427 totcmdlen = 0;
428 } else {
429 if (context->parser_state.programHeader.type == SCPI_TOKEN_UNKNOWN) break;
430 if (totcmdlen >= context->buffer.position) break;
431 }
432 }
433
434 }
435
436 return result;
437}
438
439/* writing results */
440
447size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len) {
448 size_t result = 0;
449 result += writeDelimiter(context);
450 result += writeData(context, data, len);
451 context->output_count++;
452 return result;
453}
454
460static const char * getBasePrefix(int8_t base) {
461 switch (base) {
462 case 2: return "#B";
463 case 8: return "#Q";
464 case 16: return "#H";
465 default: return NULL;
466 }
467}
468
477static size_t resultUInt32BaseSign(scpi_t * context, uint32_t val, int8_t base, scpi_bool_t sign) {
478 char buffer[32 + 1];
479 const char * basePrefix;
480 size_t result = 0;
481 size_t len;
482
483 len = UInt32ToStrBaseSign(val, buffer, sizeof (buffer), base, sign);
484 basePrefix = getBasePrefix(base);
485
486 result += writeDelimiter(context);
487 if (basePrefix != NULL) {
488 result += writeData(context, basePrefix, 2);
489 }
490 result += writeData(context, buffer, len);
491 context->output_count++;
492 return result;
493}
494
503static size_t resultUInt64BaseSign(scpi_t * context, uint64_t val, int8_t base, scpi_bool_t sign) {
504 char buffer[64 + 1];
505 const char * basePrefix;
506 size_t result = 0;
507 size_t len;
508
509 len = UInt64ToStrBaseSign(val, buffer, sizeof (buffer), base, sign);
510 basePrefix = getBasePrefix(base);
511
512 result += writeDelimiter(context);
513 if (basePrefix != NULL) {
514 result += writeData(context, basePrefix, 2);
515 }
516 result += writeData(context, buffer, len);
517 context->output_count++;
518 return result;
519}
520
527size_t SCPI_ResultInt32(scpi_t * context, int32_t val) {
528 return resultUInt32BaseSign(context, val, 10, TRUE);
529}
530
538size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base) {
539 return resultUInt32BaseSign(context, val, base, FALSE);
540}
541
548size_t SCPI_ResultInt64(scpi_t * context, int64_t val) {
549 return resultUInt64BaseSign(context, val, 10, TRUE);
550}
551
558size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base) {
559 return resultUInt64BaseSign(context, val, base, FALSE);
560}
561
568size_t SCPI_ResultFloat(scpi_t * context, float val) {
569 char buffer[32];
570 size_t result = 0;
571 size_t len = SCPI_FloatToStr(val, buffer, sizeof (buffer));
572 result += writeDelimiter(context);
573 result += writeData(context, buffer, len);
574 context->output_count++;
575 return result;
576}
577
584size_t SCPI_ResultDouble(scpi_t * context, double val) {
585 char buffer[32];
586 size_t result = 0;
587 size_t len = SCPI_DoubleToStr(val, buffer, sizeof (buffer));
588 result += writeDelimiter(context);
589 result += writeData(context, buffer, len);
590 context->output_count++;
591 return result;
592}
593
600size_t SCPI_ResultText(scpi_t * context, const char * data) {
601 size_t result = 0;
602 size_t len = strlen(data);
603 const char * quote;
604 result += writeDelimiter(context);
605 result += writeData(context, "\"", 1);
606 while ((quote = strnpbrk(data, len, "\""))) {
607 result += writeData(context, data, quote - data + 1);
608 result += writeData(context, "\"", 1);
609 len -= quote - data + 1;
610 data = quote + 1;
611 }
612 result += writeData(context, data, len);
613 result += writeData(context, "\"", 1);
614 context->output_count++;
615 return result;
616}
617
629size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error) {
630 size_t result = 0;
631 size_t outputlimit = SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH;
632 size_t step = 0;
633 const char * quote;
634
635 const char * data[SCPIDEFINE_DESCRIPTION_MAX_PARTS];
637 size_t i;
638
639 data[0] = SCPI_ErrorTranslate(error->error_code);
640 len[0] = strlen(data[0]);
641
642#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION
643 data[1] = error->device_dependent_info;
644#if USE_MEMORY_ALLOCATION_FREE
645 len[1] = error->device_dependent_info ? strlen(data[1]) : 0;
646#else
647 SCPIDEFINE_get_parts(&context->error_info_heap, data[1], &len[1], &data[2], &len[2]);
648#endif
649#endif
650
651 result += SCPI_ResultInt32(context, error->error_code);
652 result += writeDelimiter(context);
653 result += writeData(context, "\"", 1);
654
655 for (i = 0; (i < SCPIDEFINE_DESCRIPTION_MAX_PARTS) && data[i] && outputlimit; i++) {
656 if (i == 1) {
657 result += writeSemicolon(context);
658 outputlimit -= 1;
659 }
660 if (len[i] > outputlimit) {
661 len[i] = outputlimit;
662 }
663
664 while ((quote = strnpbrk(data[i], len[i], "\""))) {
665 if ((step = quote - data[i] + 1) >= outputlimit) {
666 len[i] -= 1;
667 outputlimit -= 1;
668 break;
669 }
670 result += writeData(context, data[i], step);
671 result += writeData(context, "\"", 1);
672 len[i] -= step;
673 outputlimit -= step + 1;
674 data[i] = quote + 1;
675 if (len[i] > outputlimit) {
676 len[i] = outputlimit;
677 }
678 }
679
680 result += writeData(context, data[i], len[i]);
681 outputlimit -= len[i];
682 }
683 result += writeData(context, "\"", 1);
684
685 return result;
686}
687
694size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len) {
695 char block_header[12];
696 size_t header_len;
697 block_header[0] = '#';
698 SCPI_UInt32ToStrBase((uint32_t) len, block_header + 2, 10, 10);
699
700 header_len = strlen(block_header + 2);
701 block_header[1] = (char) (header_len + '0');
702
703 context->arbitrary_reminding = len;
704 return writeData(context, block_header, header_len + 2);
705}
706
714size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len) {
715
716 if (context->arbitrary_reminding < len) {
718 return 0;
719 }
720
721 context->arbitrary_reminding -= len;
722
723 if (context->arbitrary_reminding == 0) {
724 context->output_count++;
725 }
726
727 return writeData(context, (const char *) data, len);
728}
729
737size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len) {
738 size_t result = 0;
739 result += SCPI_ResultArbitraryBlockHeader(context, len);
740 result += SCPI_ResultArbitraryBlockData(context, data, len);
741 return result;
742}
743
750size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val) {
751 return resultUInt32BaseSign(context, val ? 1 : 0, 10, FALSE);
752}
753
754/* parsing parameters */
755
761static void invalidateToken(scpi_token_t * token, char * ptr) {
762 token->len = 0;
763 token->ptr = ptr;
764 token->type = SCPI_TOKEN_UNKNOWN;
765}
766
774scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory) {
775 lex_state_t * state;
776
777 if (!parameter) {
779 return FALSE;
780 }
781
782 invalidateToken(parameter, NULL);
783
784 state = &context->param_list.lex_state;
785
786 if (state->pos >= (state->buffer + state->len)) {
787 if (mandatory) {
789 } else {
790 parameter->type = SCPI_TOKEN_PROGRAM_MNEMONIC; /* TODO: select something different */
791 }
792 return FALSE;
793 }
794 if (context->input_count != 0) {
795 scpiLex_Comma(state, parameter);
796 if (parameter->type != SCPI_TOKEN_COMMA) {
797 invalidateToken(parameter, NULL);
799 return FALSE;
800 }
801 }
802
803 context->input_count++;
804
805 scpiParser_parseProgramData(&context->param_list.lex_state, parameter);
806
807 switch (parameter->type) {
818 context->has_param = true;
819 return TRUE;
820 default:
821 invalidateToken(parameter, NULL);
823 return FALSE;
824 }
825}
826
834 switch (parameter->type) {
839 return TRUE;
841 return suffixAllowed;
842 default:
843 return FALSE;
844 }
845}
846
855static scpi_bool_t ParamSignToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value, scpi_bool_t sign) {
856
857 if (!value) {
859 return FALSE;
860 }
861
862 switch (parameter->type) {
864 return strBaseToUInt32(parameter->ptr, value, 16) > 0 ? TRUE : FALSE;
866 return strBaseToUInt32(parameter->ptr, value, 8) > 0 ? TRUE : FALSE;
868 return strBaseToUInt32(parameter->ptr, value, 2) > 0 ? TRUE : FALSE;
871 if (sign) {
872 return strBaseToInt32(parameter->ptr, (int32_t *) value, 10) > 0 ? TRUE : FALSE;
873 } else {
874 return strBaseToUInt32(parameter->ptr, value, 10) > 0 ? TRUE : FALSE;
875 }
876 default:
877 return FALSE;
878 }
879}
880
889static scpi_bool_t ParamSignToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value, scpi_bool_t sign) {
890
891 if (!value) {
893 return FALSE;
894 }
895
896 switch (parameter->type) {
898 return strBaseToUInt64(parameter->ptr, value, 16) > 0 ? TRUE : FALSE;
900 return strBaseToUInt64(parameter->ptr, value, 8) > 0 ? TRUE : FALSE;
902 return strBaseToUInt64(parameter->ptr, value, 2) > 0 ? TRUE : FALSE;
905 if (sign) {
906 return strBaseToInt64(parameter->ptr, (int64_t *) value, 10) > 0 ? TRUE : FALSE;
907 } else {
908 return strBaseToUInt64(parameter->ptr, value, 10) > 0 ? TRUE : FALSE;
909 }
910 default:
911 return FALSE;
912 }
913}
914
922scpi_bool_t SCPI_ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value) {
923 return ParamSignToUInt32(context, parameter, (uint32_t *) value, TRUE);
924}
925
933scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value) {
934 return ParamSignToUInt32(context, parameter, value, FALSE);
935}
936
944scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value) {
945 return ParamSignToUInt64(context, parameter, (uint64_t *) value, TRUE);
946}
947
955scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value) {
956 return ParamSignToUInt64(context, parameter, value, FALSE);
957}
958
966scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value) {
967 scpi_bool_t result;
968 uint32_t valint;
969
970 if (!value) {
972 return FALSE;
973 }
974
975 switch (parameter->type) {
979 result = SCPI_ParamToUInt32(context, parameter, &valint);
980 *value = valint;
981 break;
984 result = strToFloat(parameter->ptr, value) > 0 ? TRUE : FALSE;
985 break;
986 default:
987 result = FALSE;
988 }
989 return result;
990}
991
999scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value) {
1000 scpi_bool_t result;
1001 uint64_t valint;
1002
1003 if (!value) {
1005 return FALSE;
1006 }
1007
1008 switch (parameter->type) {
1009 case SCPI_TOKEN_HEXNUM:
1010 case SCPI_TOKEN_OCTNUM:
1011 case SCPI_TOKEN_BINNUM:
1012 result = SCPI_ParamToUInt64(context, parameter, &valint);
1013 *value = valint;
1014 break;
1017 result = strToDouble(parameter->ptr, value) > 0 ? TRUE : FALSE;
1018 break;
1019 default:
1020 result = FALSE;
1021 }
1022 return result;
1023}
1024
1032scpi_bool_t SCPI_ParamFloat(scpi_t * context, void * value, scpi_bool_t mandatory) {
1033 scpi_bool_t result;
1034 scpi_parameter_t param;
1035
1036 if (!value) {
1038 return FALSE;
1039 }
1040
1041 result = SCPI_Parameter(context, &param, mandatory);
1042 if (result) {
1043 if (SCPI_ParamIsNumber(&param, FALSE)) {
1044 SCPI_ParamToFloat(context, &param, (float *)value);
1045 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
1047 result = FALSE;
1048 } else {
1050 result = FALSE;
1051 }
1052 }
1053 return result;
1054}
1055
1063scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory) {
1064 scpi_bool_t result;
1065 scpi_parameter_t param;
1066
1067 if (!value) {
1069 return FALSE;
1070 }
1071
1072 result = SCPI_Parameter(context, &param, mandatory);
1073 if (result) {
1074 if (SCPI_ParamIsNumber(&param, FALSE)) {
1075 SCPI_ParamToDouble(context, &param, value);
1076 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
1078 result = FALSE;
1079 } else {
1081 result = FALSE;
1082 }
1083 }
1084 return result;
1085}
1086
1095static scpi_bool_t ParamSignUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory, scpi_bool_t sign) {
1096 scpi_bool_t result;
1097 scpi_parameter_t param;
1098
1099 if (!value) {
1101 return FALSE;
1102 }
1103
1104 result = SCPI_Parameter(context, &param, mandatory);
1105 if (result) {
1106 if (SCPI_ParamIsNumber(&param, FALSE)) {
1107 result = ParamSignToUInt32(context, &param, value, sign);
1108 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
1110 result = FALSE;
1111 } else {
1113 result = FALSE;
1114 }
1115 }
1116 return result;
1117}
1118
1127static scpi_bool_t ParamSignUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory, scpi_bool_t sign) {
1128 scpi_bool_t result;
1129 scpi_parameter_t param;
1130
1131 if (!value) {
1133 return FALSE;
1134 }
1135
1136 result = SCPI_Parameter(context, &param, mandatory);
1137 if (result) {
1138 if (SCPI_ParamIsNumber(&param, FALSE)) {
1139 result = ParamSignToUInt64(context, &param, value, sign);
1140 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
1142 result = FALSE;
1143 } else {
1145 result = FALSE;
1146 }
1147 }
1148 return result;
1149}
1150
1158scpi_bool_t SCPI_ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory) {
1159 return ParamSignUInt32(context, (uint32_t *) value, mandatory, TRUE);
1160}
1161
1169scpi_bool_t SCPI_ParamUInt32(scpi_t * context, void * value, scpi_bool_t mandatory) {
1170 return ParamSignUInt32(context, (uint32_t *)value, mandatory, FALSE);
1171}
1172
1180scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory) {
1181 return ParamSignUInt64(context, (uint64_t *) value, mandatory, TRUE);
1182}
1183
1191scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory) {
1192 return ParamSignUInt64(context, value, mandatory, FALSE);
1193}
1194
1203scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory) {
1204 scpi_bool_t result;
1205 scpi_parameter_t param;
1206
1207 if (!value || !len) {
1209 return FALSE;
1210 }
1211
1212 result = SCPI_Parameter(context, &param, mandatory);
1213 if (result) {
1214 switch (param.type) {
1217 *value = param.ptr + 1;
1218 *len = param.len - 2;
1219 break;
1220 default:
1221 *value = param.ptr;
1222 *len = param.len;
1223 break;
1224 }
1225
1226 /* TODO: return also parameter type (ProgramMnemonic, ArbitraryBlockProgramData, SingleQuoteProgramData, DoubleQuoteProgramData */
1227 }
1228
1229 return result;
1230}
1231
1240scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory) {
1241 scpi_bool_t result;
1242 scpi_parameter_t param;
1243
1244 if (!value || !len) {
1246 return FALSE;
1247 }
1248
1249 result = SCPI_Parameter(context, &param, mandatory);
1250 if (result) {
1251 if (param.type == SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA) {
1252 *value = param.ptr;
1253 *len = param.len;
1254 } else {
1256 result = FALSE;
1257 }
1258 }
1259
1260 return result;
1261}
1262
1263scpi_bool_t SCPI_ParamCopyText(scpi_t * context, char * buffer, size_t buffer_len, size_t * copy_len, scpi_bool_t mandatory) {
1264 scpi_bool_t result;
1265 scpi_parameter_t param;
1266 size_t i_from;
1267 size_t i_to;
1268 char quote;
1269
1270 if (!buffer || !copy_len) {
1272 return FALSE;
1273 }
1274
1275 result = SCPI_Parameter(context, &param, mandatory);
1276 if (result) {
1277
1278 switch (param.type) {
1281 quote = param.type == SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA ? '\'' : '"';
1282 for (i_from = 1, i_to = 0; i_from < (size_t) (param.len - 1); i_from++) {
1283 if (i_from >= buffer_len) {
1284 break;
1285 }
1286 buffer[i_to] = param.ptr[i_from];
1287 i_to++;
1288 if (param.ptr[i_from] == quote) {
1289 i_from++;
1290 }
1291 }
1292 *copy_len = i_to;
1293 if (i_to < buffer_len) {
1294 buffer[i_to] = 0;
1295 }
1296 break;
1297 default:
1299 result = FALSE;
1300 }
1301 }
1302
1303 return result;
1304}
1305
1314scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value) {
1315 size_t res;
1316 scpi_bool_t result = FALSE;
1317
1318 if (!options || !value) {
1320 return FALSE;
1321 }
1322
1323 if (parameter->type == SCPI_TOKEN_PROGRAM_MNEMONIC) {
1324 for (res = 0; options[res].name; ++res) {
1325 if (matchPattern(options[res].name, strlen(options[res].name), parameter->ptr, parameter->len, NULL)) {
1326 *value = options[res].tag;
1327 result = TRUE;
1328 break;
1329 }
1330 }
1331
1332 if (!result) {
1334 }
1335 } else {
1337 }
1338
1339 return result;
1340}
1341
1349scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text) {
1350 int i;
1351
1352 for (i = 0; options[i].name != NULL; i++) {
1353 if (options[i].tag == tag) {
1354 *text = options[i].name;
1355 return TRUE;
1356 }
1357 }
1358
1359 return FALSE;
1360}
1361
1369scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory) {
1370 scpi_bool_t result;
1371 scpi_parameter_t param;
1372 int32_t intval;
1373
1374 scpi_choice_def_t bool_options[] = {
1375 {"OFF", 0},
1376 {"ON", 1},
1377 SCPI_CHOICE_LIST_END /* termination of option list */
1378 };
1379
1380 if (!value) {
1382 return FALSE;
1383 }
1384
1385 result = SCPI_Parameter(context, &param, mandatory);
1386
1387 if (result) {
1388 if (param.type == SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA) {
1389 SCPI_ParamToInt32(context, &param, &intval);
1390 *value = intval ? TRUE : FALSE;
1391 } else {
1392 result = SCPI_ParamToChoice(context, &param, bool_options, &intval);
1393 if (result) {
1394 *value = intval ? TRUE : FALSE;
1395 }
1396 }
1397 }
1398
1399 return result;
1400}
1401
1410scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory) {
1411 scpi_bool_t result;
1412 scpi_parameter_t param;
1413
1414 if (!options || !value) {
1416 return FALSE;
1417 }
1418
1419 result = SCPI_Parameter(context, &param, mandatory);
1420 if (result) {
1421 result = SCPI_ParamToChoice(context, &param, options, value);
1422 }
1423
1424 return result;
1425}
1426
1433int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) {
1434 scpi_token_t tmp;
1435 int result = 0;
1436 int wsLen;
1437 int suffixLen;
1438 int realLen = 0;
1439 realLen += scpiLex_WhiteSpace(state, &tmp);
1440
1441 if (result == 0) result = scpiLex_NondecimalNumericData(state, token);
1442 if (result == 0) result = scpiLex_CharacterProgramData(state, token);
1443 if (result == 0) {
1444 result = scpiLex_DecimalNumericProgramData(state, token);
1445 if (result != 0) {
1446 wsLen = scpiLex_WhiteSpace(state, &tmp);
1447 suffixLen = scpiLex_SuffixProgramData(state, &tmp);
1448 if (suffixLen > 0) {
1449 token->len += wsLen + suffixLen;
1451 result = token->len;
1452 }
1453 }
1454 }
1455
1456 if (result == 0) result = scpiLex_StringProgramData(state, token);
1457 if (result == 0) result = scpiLex_ArbitraryBlockProgramData(state, token);
1458 if (result == 0) result = scpiLex_ProgramExpression(state, token);
1459
1460 realLen += scpiLex_WhiteSpace(state, &tmp);
1461
1462 return result + realLen;
1463}
1464
1472int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) {
1473
1474 int result;
1475 scpi_token_t tmp;
1476 int paramCount = 0;
1477
1478 token->len = -1;
1479 token->type = SCPI_TOKEN_ALL_PROGRAM_DATA;
1480 token->ptr = state->pos;
1481
1482
1483 for (result = 1; result != 0; result = scpiLex_Comma(state, &tmp)) {
1484 token->len += result;
1485
1486 if (result == 0) {
1487 token->type = SCPI_TOKEN_UNKNOWN;
1488 token->len = 0;
1489 paramCount = -1;
1490 break;
1491 }
1492
1493 result = scpiParser_parseProgramData(state, &tmp);
1494 if (tmp.type != SCPI_TOKEN_UNKNOWN) {
1495 token->len += result;
1496 } else {
1497 token->type = SCPI_TOKEN_UNKNOWN;
1498 token->len = 0;
1499 paramCount = -1;
1500 break;
1501 }
1502 paramCount++;
1503 }
1504
1505 if (token->len == -1) {
1506 token->len = 0;
1507 }
1508
1509 if (numberOfParameters != NULL) {
1510 *numberOfParameters = paramCount;
1511 }
1512 return token->len;
1513}
1514
1522int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, char * buffer, int len) {
1523 lex_state_t lex_state;
1524 scpi_token_t tmp;
1525 int result = 0;
1526
1527 lex_state.buffer = lex_state.pos = buffer;
1528 lex_state.len = len;
1529 state->numberOfParameters = 0;
1530
1531 /* ignore whitespace at the begginig */
1532 scpiLex_WhiteSpace(&lex_state, &tmp);
1533
1534 if (scpiLex_ProgramHeader(&lex_state, &state->programHeader) >= 0) {
1535 if (scpiLex_WhiteSpace(&lex_state, &tmp) > 0) {
1536 scpiParser_parseAllProgramData(&lex_state, &state->programData, &state->numberOfParameters);
1537 } else {
1538 invalidateToken(&state->programData, lex_state.pos);
1539 }
1540 } else {
1541 invalidateToken(&state->programHeader, lex_state.buffer);
1542 invalidateToken(&state->programData, lex_state.buffer);
1543 }
1544
1545 if (result == 0) result = scpiLex_NewLine(&lex_state, &tmp);
1546 if (result == 0) result = scpiLex_Semicolon(&lex_state, &tmp);
1547
1548 if (!scpiLex_IsEos(&lex_state) && (result == 0)) {
1549 lex_state.pos++;
1550
1551 state->programHeader.len = 1;
1552 state->programHeader.type = SCPI_TOKEN_INVALID;
1553
1554 invalidateToken(&state->programData, lex_state.buffer);
1555 }
1556
1557 if (SCPI_TOKEN_SEMICOLON == tmp.type) {
1558 state->termination = SCPI_MESSAGE_TERMINATION_SEMICOLON;
1559 } else if (SCPI_TOKEN_NL == tmp.type) {
1560 state->termination = SCPI_MESSAGE_TERMINATION_NL;
1561 } else {
1562 state->termination = SCPI_MESSAGE_TERMINATION_NONE;
1563 }
1564
1565 return lex_state.pos - lex_state.buffer;
1566}
1567
1575scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd) {
1576 const char * pattern;
1577
1578 if (!context->param_list.cmd) {
1579 return FALSE;
1580 }
1581
1582 pattern = context->param_list.cmd->pattern;
1583 return matchCommand(pattern, cmd, strlen(cmd), NULL, 0, 0, &context->query);
1584}
1585
1586#if USE_COMMAND_TAGS
1587
1593uint16_t SCPI_CmdTag(scpi_t * context) {
1594 if (context->param_list.cmd) {
1595 return context->param_list.cmd->tag;
1596 } else {
1597 return 0;
1598 }
1599}
1600#endif /* USE_COMMAND_TAGS */
1601
1602scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len, bool *query) {
1603 return matchCommand(pattern, value, len, NULL, 0, 0, query);
1604}
1605
1606scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value) {
1607 return matchCommand(context->param_list.cmd->pattern, context->param_list.cmd_raw.data, context->param_list.cmd_raw.length, numbers, len, default_value, &context->query);
1608}
1609
1617 return parameter->type == SCPI_TOKEN_UNKNOWN ? FALSE : TRUE;
1618}
1619
1626 return context->cmd_error;
1627}
1628
1638static size_t produceResultArrayBinary(scpi_t * context, const void * array, size_t count, size_t item_size, scpi_array_format_t format) {
1639
1640 if (SCPI_GetNativeFormat() == format) {
1641 switch (item_size) {
1642 case 1:
1643 case 2:
1644 case 4:
1645 case 8:
1646 return SCPI_ResultArbitraryBlock(context, array, count * item_size);
1647 default:
1649 return 0;
1650 }
1651 } else {
1652 size_t result = 0;
1653 size_t i;
1654 switch (item_size) {
1655 case 1:
1656 case 2:
1657 case 4:
1658 case 8:
1659 result += SCPI_ResultArbitraryBlockHeader(context, count * item_size);
1660 break;
1661 default:
1663 return 0;
1664 }
1665
1666 switch (item_size) {
1667 case 1:
1668 result += SCPI_ResultArbitraryBlockData(context, array, count);
1669 break;
1670 case 2:
1671 for (i = 0; i < count; i++) {
1672 uint16_t val = SCPI_Swap16(((uint16_t*) array)[i]);
1673 result += SCPI_ResultArbitraryBlockData(context, &val, item_size);
1674 }
1675 break;
1676 case 4:
1677 for (i = 0; i < count; i++) {
1678 uint32_t val = SCPI_Swap32(((uint32_t*) array)[i]);
1679 result += SCPI_ResultArbitraryBlockData(context, &val, item_size);
1680 }
1681 break;
1682 case 8:
1683 for (i = 0; i < count; i++) {
1684 uint64_t val = SCPI_Swap64(((uint64_t*) array)[i]);
1685 result += SCPI_ResultArbitraryBlockData(context, &val, item_size);
1686 }
1687 break;
1688 }
1689
1690 return result;
1691 }
1692}
1693
1694
1695#define RESULT_ARRAY(func) do {\
1696 size_t result = 0;\
1697 if (format == SCPI_FORMAT_ASCII) {\
1698 size_t i;\
1699 for (i = 0; i < count; i++) {\
1700 result += func(context, array[i]);\
1701 }\
1702 } else {\
1703 result = produceResultArrayBinary(context, array, count, sizeof(*array), format);\
1704 }\
1705 return result;\
1706} while(0)
1707
1716size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format) {
1718}
1719
1728size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format) {
1730}
1731
1740size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format) {
1742}
1743
1752size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format) {
1754}
1755
1764size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format) {
1766}
1767
1776size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format) {
1778}
1779
1788size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format) {
1790}
1791
1800size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format) {
1802}
1803
1812size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format) {
1814}
1815
1824size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format) {
1826}
1827
1828/*
1829 * Template macro to generate all SCPI_ParamArrayXYZ function
1830 */
1831#define PARAM_ARRAY_TEMPLATE(func) do{\
1832 if (format != SCPI_FORMAT_ASCII) return FALSE;\
1833 for (*o_count = 0; *o_count < i_count; (*o_count)++) {\
1834 if (!func(context, &data[*o_count], mandatory)) {\
1835 break;\
1836 }\
1837 mandatory = FALSE;\
1838 }\
1839 return mandatory ? FALSE : TRUE;\
1840}while(0)
1841
1851scpi_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) {
1853}
1854
1864scpi_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) {
1866}
1867
1877scpi_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) {
1879}
1880
1890scpi_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) {
1892}
1893
1903scpi_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) {
1905}
1906
1916scpi_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) {
1918}
SCPI Configuration.
#define SCPI_MAX_CMD_PATTERN_SIZE
Definition config.h:46
#define SCPI_LINE_ENDING
Definition config.h:54
#define SCPIDEFINE_DESCRIPTION_MAX_PARTS
Definition config.h:225
#define SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH
Definition constants.h:54
void SCPI_ErrorPush(scpi_t *context, int16_t err)
Definition error.c:202
void SCPI_ErrorPushEx(scpi_t *context, int16_t err, char *info, size_t info_len)
Definition error.c:173
const char * SCPI_ErrorTranslate(int16_t err)
Definition error.c:212
void SCPI_ErrorInit(scpi_t *context, scpi_error_t *data, int16_t size)
Definition error.c:55
@ SCPI_ERROR_PARAMETER_NOT_ALLOWED
Definition error.h:193
@ SCPI_ERROR_EXECUTION_ERROR
Definition error.h:193
@ SCPI_ERROR_ILLEGAL_PARAMETER_VALUE
Definition error.h:193
@ SCPI_ERROR_UNDEFINED_HEADER
Definition error.h:193
@ SCPI_ERROR_MISSING_PARAMETER
Definition error.h:193
@ SCPI_ERROR_INVALID_SEPARATOR
Definition error.h:193
@ SCPI_ERROR_INPUT_BUFFER_OVERRUN
Definition error.h:193
@ SCPI_ERROR_SYSTEM_ERROR
Definition error.h:193
@ SCPI_ERROR_INVALID_CHARACTER
Definition error.h:193
@ SCPI_ERROR_DATA_TYPE_ERROR
Definition error.h:193
@ SCPI_ERROR_SUFFIX_NOT_ALLOWED
Definition error.h:193
@ SCPI_ERROR_INVALID_STRING_DATA
Definition error.h:193
Expressions handling.
int scpiLex_NewLine(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:917
int scpiLex_StringProgramData(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:665
int scpiLex_ProgramExpression(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:805
int scpiLex_ArbitraryBlockProgramData(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:717
int scpiLex_DecimalNumericProgramData(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:508
int scpiLex_ProgramHeader(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:405
int scpiLex_SuffixProgramData(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:533
int scpiLex_Semicolon(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:857
int scpiLex_IsEos(lex_state_t *state)
Definition lexer.c:98
int scpiLex_CharacterProgramData(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:451
int scpiLex_WhiteSpace(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:330
int scpiLex_Comma(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:837
int scpiLex_NondecimalNumericData(lex_state_t *state, scpi_token_t *token)
Definition lexer.c:596
scpi_bool_t SCPI_ParamToInt64(scpi_t *context, scpi_parameter_t *parameter, int64_t *value)
Definition parser.c:944
size_t SCPI_ResultArrayInt64(scpi_t *context, const int64_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1788
static scpi_bool_t ParamSignToUInt64(scpi_t *context, scpi_parameter_t *parameter, uint64_t *value, scpi_bool_t sign)
Definition parser.c:889
scpi_bool_t SCPI_ParamDouble(scpi_t *context, double *value, scpi_bool_t mandatory)
Definition parser.c:1063
static size_t writeData(scpi_t *context, const char *data, size_t len)
Definition parser.c:60
scpi_bool_t SCPI_ParamFloat(scpi_t *context, void *value, scpi_bool_t mandatory)
Definition parser.c:1032
scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t *options, int32_t tag, const char **text)
Definition parser.c:1349
scpi_bool_t SCPI_ParamInt32(scpi_t *context, int32_t *value, scpi_bool_t mandatory)
Definition parser.c:1158
scpi_bool_t SCPI_ParamToChoice(scpi_t *context, scpi_parameter_t *parameter, const scpi_choice_def_t *options, int32_t *value)
Definition parser.c:1314
uint16_t SCPI_CmdTag(scpi_t *context)
Definition parser.c:1593
size_t SCPI_ResultBool(scpi_t *context, scpi_bool_t val)
Definition parser.c:750
static scpi_bool_t ParamSignToUInt32(scpi_t *context, scpi_parameter_t *parameter, uint32_t *value, scpi_bool_t sign)
Definition parser.c:855
scpi_bool_t SCPI_Match(const char *pattern, const char *value, size_t len, bool *query)
Definition parser.c:1602
scpi_bool_t SCPI_CommandNumbers(scpi_t *context, int32_t *numbers, size_t len, int32_t default_value)
Definition parser.c:1606
scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t *context, const char **value, size_t *len, scpi_bool_t mandatory)
Definition parser.c:1240
static scpi_bool_t processCommand(scpi_t *context)
Definition parser.c:130
scpi_bool_t SCPI_ParamToDouble(scpi_t *context, scpi_parameter_t *parameter, double *value)
Definition parser.c:999
#define PARAM_ARRAY_TEMPLATE(func)
Definition parser.c:1831
size_t SCPI_ResultArbitraryBlock(scpi_t *context, const void *data, size_t len)
Definition parser.c:737
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)
Definition parser.c:1903
scpi_bool_t SCPI_ParamChoice(scpi_t *context, const scpi_choice_def_t *options, int32_t *value, scpi_bool_t mandatory)
Definition parser.c:1410
scpi_bool_t SCPI_IsCmd(scpi_t *context, const char *cmd)
Definition parser.c:1575
scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t *parameter, scpi_bool_t suffixAllowed)
Definition parser.c:833
static size_t writeNewLine(scpi_t *context)
Definition parser.c:99
int scpiParser_parseAllProgramData(lex_state_t *state, scpi_token_t *token, int *numberOfParameters)
Definition parser.c:1472
scpi_bool_t SCPI_ParamErrorOccurred(scpi_t *context)
Definition parser.c:1625
static size_t produceResultArrayBinary(scpi_t *context, const void *array, size_t count, size_t item_size, scpi_array_format_t format)
Definition parser.c:1638
scpi_bool_t SCPI_ParamUInt64(scpi_t *context, uint64_t *value, scpi_bool_t mandatory)
Definition parser.c:1191
size_t SCPI_ResultArrayInt8(scpi_t *context, const int8_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1716
scpi_bool_t SCPI_Parse(scpi_t *context, char *data, int len)
Definition parser.c:257
scpi_bool_t SCPI_Parameter(scpi_t *context, scpi_parameter_t *parameter, scpi_bool_t mandatory)
Definition parser.c:774
size_t SCPI_ResultInt64(scpi_t *context, int64_t val)
Definition parser.c:548
size_t SCPI_ResultError(scpi_t *context, scpi_error_t *error)
Definition parser.c:629
static const char * getBasePrefix(int8_t base)
Definition parser.c:460
static int flushData(scpi_t *context)
Definition parser.c:73
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)
Definition parser.c:1864
size_t SCPI_ResultArrayUInt16(scpi_t *context, const uint16_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1752
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)
Definition parser.c:1916
static scpi_bool_t findCommandHeader(scpi_t *context, const char *header, int len)
Definition parser.c:174
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)
Definition parser.c:1877
size_t SCPI_ResultText(scpi_t *context, const char *data)
Definition parser.c:600
size_t SCPI_ResultInt32(scpi_t *context, int32_t val)
Definition parser.c:527
size_t SCPI_ResultUInt32Base(scpi_t *context, uint32_t val, int8_t base)
Definition parser.c:538
static size_t writeDelimiter(scpi_t *context)
Definition parser.c:86
size_t SCPI_ResultArrayUInt8(scpi_t *context, const uint8_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1728
size_t SCPI_ResultArbitraryBlockData(scpi_t *context, const void *data, size_t len)
Definition parser.c:714
size_t SCPI_ResultArrayInt32(scpi_t *context, const int32_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1764
scpi_bool_t SCPI_Input(scpi_t *context, const char *data, int len)
Definition parser.c:394
scpi_bool_t SCPI_ParamCharacters(scpi_t *context, const char **value, size_t *len, scpi_bool_t mandatory)
Definition parser.c:1203
scpi_bool_t SCPI_ParamUInt32(scpi_t *context, void *value, scpi_bool_t mandatory)
Definition parser.c:1169
static scpi_bool_t ParamSignUInt32(scpi_t *context, uint32_t *value, scpi_bool_t mandatory, scpi_bool_t sign)
Definition parser.c:1095
scpi_bool_t SCPI_ParamToFloat(scpi_t *context, scpi_parameter_t *parameter, float *value)
Definition parser.c:966
scpi_bool_t SCPI_ParamToInt32(scpi_t *context, scpi_parameter_t *parameter, int32_t *value)
Definition parser.c:922
static scpi_bool_t ParamSignUInt64(scpi_t *context, uint64_t *value, scpi_bool_t mandatory, scpi_bool_t sign)
Definition parser.c:1127
scpi_bool_t SCPI_ParamBool(scpi_t *context, scpi_bool_t *value, scpi_bool_t mandatory)
Definition parser.c:1369
#define RESULT_ARRAY(func)
Definition parser.c:1695
size_t SCPI_ResultArrayDouble(scpi_t *context, const double *array, size_t count, scpi_array_format_t format)
Definition parser.c:1824
int scpiParser_detectProgramMessageUnit(scpi_parser_state_t *state, char *buffer, int len)
Definition parser.c:1522
size_t SCPI_ResultUInt64Base(scpi_t *context, uint64_t val, int8_t base)
Definition parser.c:558
size_t SCPI_ResultDouble(scpi_t *context, double val)
Definition parser.c:584
static size_t resultUInt32BaseSign(scpi_t *context, uint32_t val, int8_t base, scpi_bool_t sign)
Definition parser.c:477
static size_t resultUInt64BaseSign(scpi_t *context, uint64_t val, int8_t base, scpi_bool_t sign)
Definition parser.c:503
size_t SCPI_ResultArrayUInt32(scpi_t *context, const uint32_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1776
static size_t writeSemicolon(scpi_t *context)
Definition parser.c:118
size_t SCPI_ResultArrayFloat(scpi_t *context, const float *array, size_t count, scpi_array_format_t format)
Definition parser.c:1812
size_t SCPI_ResultFloat(scpi_t *context, float val)
Definition parser.c:568
scpi_bool_t SCPI_ParamCopyText(scpi_t *context, char *buffer, size_t buffer_len, size_t *copy_len, scpi_bool_t mandatory)
Definition parser.c:1263
scpi_bool_t SCPI_ParamIsValid(scpi_parameter_t *parameter)
Definition parser.c:1616
scpi_bool_t SCPI_ParamToUInt64(scpi_t *context, scpi_parameter_t *parameter, uint64_t *value)
Definition parser.c:955
size_t SCPI_ResultArbitraryBlockHeader(scpi_t *context, size_t len)
Definition parser.c:694
scpi_bool_t SCPI_ParamToUInt32(scpi_t *context, scpi_parameter_t *parameter, uint32_t *value)
Definition parser.c:933
int scpiParser_parseProgramData(lex_state_t *state, scpi_token_t *token)
Definition parser.c:1433
void SCPI_Init(scpi_t *context, const scpi_command_t *def_cmds, scpi_interface_t *interface, const scpi_unit_def_t *units, const char *idn1, const char *idn2, const char *idn3, const char *idn4, char *input_buffer, size_t input_buffer_length, scpi_error_t *error_queue_data, int16_t error_queue_size)
Definition parser.c:337
scpi_bool_t SCPI_ParamInt64(scpi_t *context, int64_t *value, scpi_bool_t mandatory)
Definition parser.c:1180
size_t SCPI_ResultCharacters(scpi_t *context, const char *data, size_t len)
Definition parser.c:447
static void invalidateToken(scpi_token_t *token, char *ptr)
Definition parser.c:761
size_t SCPI_ResultArrayInt16(scpi_t *context, const int16_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1740
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)
Definition parser.c:1851
size_t SCPI_ResultArrayUInt64(scpi_t *context, const uint64_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1800
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)
Definition parser.c:1890
#define SCPI_ResultUInt64(c, v)
Definition parser.h:76
#define SCPI_ResultUInt32(c, v)
Definition parser.h:72
#define SCPI_ResultUInt16(c, v)
Definition parser.h:66
#define SCPI_ResultInt16(c, v)
Definition parser.h:67
#define SCPI_ResultUInt8(c, v)
Definition parser.h:63
#define SCPI_ResultInt8(c, v)
Definition parser.h:64
SCPI Parser private definitions.
static size_t o_count
Definition scpi.c:26
@ SCPI_MESSAGE_TERMINATION_NONE
Definition types.h:193
@ SCPI_MESSAGE_TERMINATION_NL
Definition types.h:194
@ SCPI_MESSAGE_TERMINATION_SEMICOLON
Definition types.h:195
enum _scpi_array_format_t scpi_array_format_t
Definition types.h:407
bool scpi_bool_t
Definition types.h:67
@ SCPI_RES_OK
Definition types.h:110
#define SCPI_CHOICE_LIST_END
Definition types.h:320
scpi_result_t(* scpi_command_callback_t)(scpi_t *)
Definition types.h:207
#define TRUE
Definition types.h:63
#define FALSE
Definition types.h:60
@ SCPI_TOKEN_PROGRAM_MNEMONIC
Definition types.h:156
@ SCPI_TOKEN_BINNUM
Definition types.h:155
@ SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA
Definition types.h:162
@ SCPI_TOKEN_SEMICOLON
Definition types.h:148
@ SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX
Definition types.h:158
@ SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA
Definition types.h:161
@ SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA
Definition types.h:157
@ SCPI_TOKEN_COMMA
Definition types.h:147
@ SCPI_TOKEN_OCTNUM
Definition types.h:154
@ SCPI_TOKEN_NL
Definition types.h:152
@ SCPI_TOKEN_HEXNUM
Definition types.h:153
@ SCPI_TOKEN_ALL_PROGRAM_DATA
Definition types.h:171
@ SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA
Definition types.h:160
@ SCPI_TOKEN_INVALID
Definition types.h:172
@ SCPI_TOKEN_PROGRAM_EXPRESSION
Definition types.h:163
@ SCPI_TOKEN_UNKNOWN
Definition types.h:173
scpi_token_t scpi_parameter_t
Definition types.h:362
uint64_t SCPI_Swap64(uint64_t val)
Definition utils.c:1143
char * strnpbrk(const char *str, size_t size, const char *set)
Definition utils.c:59
size_t SCPI_FloatToStr(float val, char *str, size_t len)
Definition utils.c:251
size_t SCPI_UInt32ToStrBase(uint32_t val, char *str, size_t len, int8_t base)
Definition utils.c:154
scpi_bool_t matchPattern(const char *pattern, size_t pattern_len, const char *str, size_t str_len, int32_t *num)
Definition utils.c:479
size_t UInt64ToStrBaseSign(uint64_t val, char *str, size_t len, int8_t base, scpi_bool_t sign)
Definition utils.c:167
uint32_t SCPI_Swap32(uint32_t val)
Definition utils.c:1131
size_t strToDouble(const char *str, double *val)
Definition utils.c:334
size_t strBaseToUInt64(const char *str, uint64_t *val, int8_t base)
Definition utils.c:310
scpi_bool_t matchCommand(const char *pattern, const char *cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value, bool *query)
Definition utils.c:505
size_t strBaseToUInt32(const char *str, uint32_t *val, int8_t base)
Definition utils.c:286
scpi_bool_t composeCompoundCommand(const scpi_token_t *prev, scpi_token_t *current)
Definition utils.c:688
scpi_array_format_t SCPI_GetNativeFormat(void)
Definition utils.c:1106
size_t SCPI_DoubleToStr(double val, char *str, size_t len)
Definition utils.c:263
size_t strBaseToInt64(const char *str, int64_t *val, int8_t base)
Definition utils.c:298
size_t strBaseToInt32(const char *str, int32_t *val, int8_t base)
Definition utils.c:274
size_t strToFloat(const char *str, float *val)
Definition utils.c:322
uint16_t SCPI_Swap16(uint16_t val)
Definition utils.c:1121
size_t UInt32ToStrBaseSign(uint32_t val, char *str, size_t len, int8_t base, scpi_bool_t sign)
Definition utils.c:81
Conversion routines and string manipulation routines.