Liqun Wu / Mbed 2 deprecated 90418_mbed_controller

Dependencies:   mbed

Committer:
wuliqunyy
Date:
Mon Jan 17 13:20:09 2022 +0000
Revision:
0:be95bfb06686
a working non_flat + adc_didt for ehp regulation version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wuliqunyy 0:be95bfb06686 1 /*-
wuliqunyy 0:be95bfb06686 2 * BSD 2-Clause License
wuliqunyy 0:be95bfb06686 3 *
wuliqunyy 0:be95bfb06686 4 * Copyright (c) 2012-2018, Jan Breuer
wuliqunyy 0:be95bfb06686 5 * All rights reserved.
wuliqunyy 0:be95bfb06686 6 *
wuliqunyy 0:be95bfb06686 7 * Redistribution and use in source and binary forms, with or without
wuliqunyy 0:be95bfb06686 8 * modification, are permitted provided that the following conditions are met:
wuliqunyy 0:be95bfb06686 9 *
wuliqunyy 0:be95bfb06686 10 * * Redistributions of source code must retain the above copyright notice, this
wuliqunyy 0:be95bfb06686 11 * list of conditions and the following disclaimer.
wuliqunyy 0:be95bfb06686 12 *
wuliqunyy 0:be95bfb06686 13 * * Redistributions in binary form must reproduce the above copyright notice,
wuliqunyy 0:be95bfb06686 14 * this list of conditions and the following disclaimer in the documentation
wuliqunyy 0:be95bfb06686 15 * and/or other materials provided with the distribution.
wuliqunyy 0:be95bfb06686 16 *
wuliqunyy 0:be95bfb06686 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
wuliqunyy 0:be95bfb06686 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
wuliqunyy 0:be95bfb06686 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
wuliqunyy 0:be95bfb06686 20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
wuliqunyy 0:be95bfb06686 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
wuliqunyy 0:be95bfb06686 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
wuliqunyy 0:be95bfb06686 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
wuliqunyy 0:be95bfb06686 24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
wuliqunyy 0:be95bfb06686 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
wuliqunyy 0:be95bfb06686 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
wuliqunyy 0:be95bfb06686 27 */
wuliqunyy 0:be95bfb06686 28
wuliqunyy 0:be95bfb06686 29 /**
wuliqunyy 0:be95bfb06686 30 * @file scpi_parser.c
wuliqunyy 0:be95bfb06686 31 * @date Thu Nov 15 10:58:45 UTC 2012
wuliqunyy 0:be95bfb06686 32 *
wuliqunyy 0:be95bfb06686 33 * @brief SCPI parser implementation
wuliqunyy 0:be95bfb06686 34 *
wuliqunyy 0:be95bfb06686 35 *
wuliqunyy 0:be95bfb06686 36 */
wuliqunyy 0:be95bfb06686 37
wuliqunyy 0:be95bfb06686 38 #include <ctype.h>
wuliqunyy 0:be95bfb06686 39 #include <string.h>
wuliqunyy 0:be95bfb06686 40
wuliqunyy 0:be95bfb06686 41 #include "scpi/config.h"
wuliqunyy 0:be95bfb06686 42 #include "scpi/parser.h"
wuliqunyy 0:be95bfb06686 43 #include "parser_private.h"
wuliqunyy 0:be95bfb06686 44 #include "lexer_private.h"
wuliqunyy 0:be95bfb06686 45 #include "scpi/error.h"
wuliqunyy 0:be95bfb06686 46 #include "scpi/constants.h"
wuliqunyy 0:be95bfb06686 47 #include "scpi/utils.h"
wuliqunyy 0:be95bfb06686 48
wuliqunyy 0:be95bfb06686 49 /**
wuliqunyy 0:be95bfb06686 50 * Write data to SCPI output
wuliqunyy 0:be95bfb06686 51 * @param context
wuliqunyy 0:be95bfb06686 52 * @param data
wuliqunyy 0:be95bfb06686 53 * @param len - lenght of data to be written
wuliqunyy 0:be95bfb06686 54 * @return number of bytes written
wuliqunyy 0:be95bfb06686 55 */
wuliqunyy 0:be95bfb06686 56 static size_t writeData(scpi_t * context, const char * data, size_t len) {
wuliqunyy 0:be95bfb06686 57 if (len > 0) {
wuliqunyy 0:be95bfb06686 58 return context->interface->write(context, data, len);
wuliqunyy 0:be95bfb06686 59 } else {
wuliqunyy 0:be95bfb06686 60 return 0;
wuliqunyy 0:be95bfb06686 61 }
wuliqunyy 0:be95bfb06686 62 }
wuliqunyy 0:be95bfb06686 63
wuliqunyy 0:be95bfb06686 64 /**
wuliqunyy 0:be95bfb06686 65 * Flush data to SCPI output
wuliqunyy 0:be95bfb06686 66 * @param context
wuliqunyy 0:be95bfb06686 67 * @return
wuliqunyy 0:be95bfb06686 68 */
wuliqunyy 0:be95bfb06686 69 static int flushData(scpi_t * context) {
wuliqunyy 0:be95bfb06686 70 if (context && context->interface && context->interface->flush) {
wuliqunyy 0:be95bfb06686 71 return context->interface->flush(context);
wuliqunyy 0:be95bfb06686 72 } else {
wuliqunyy 0:be95bfb06686 73 return SCPI_RES_OK;
wuliqunyy 0:be95bfb06686 74 }
wuliqunyy 0:be95bfb06686 75 }
wuliqunyy 0:be95bfb06686 76
wuliqunyy 0:be95bfb06686 77 /**
wuliqunyy 0:be95bfb06686 78 * Write result delimiter to output
wuliqunyy 0:be95bfb06686 79 * @param context
wuliqunyy 0:be95bfb06686 80 * @return number of bytes written
wuliqunyy 0:be95bfb06686 81 */
wuliqunyy 0:be95bfb06686 82 static size_t writeDelimiter(scpi_t * context) {
wuliqunyy 0:be95bfb06686 83 if (context->output_count > 0) {
wuliqunyy 0:be95bfb06686 84 return writeData(context, ",", 1);
wuliqunyy 0:be95bfb06686 85 } else {
wuliqunyy 0:be95bfb06686 86 return 0;
wuliqunyy 0:be95bfb06686 87 }
wuliqunyy 0:be95bfb06686 88 }
wuliqunyy 0:be95bfb06686 89
wuliqunyy 0:be95bfb06686 90 /**
wuliqunyy 0:be95bfb06686 91 * Conditionaly write "New Line"
wuliqunyy 0:be95bfb06686 92 * @param context
wuliqunyy 0:be95bfb06686 93 * @return number of characters written
wuliqunyy 0:be95bfb06686 94 */
wuliqunyy 0:be95bfb06686 95 static size_t writeNewLine(scpi_t * context) {
wuliqunyy 0:be95bfb06686 96 if (context->output_count > 0) {
wuliqunyy 0:be95bfb06686 97 size_t len;
wuliqunyy 0:be95bfb06686 98 #ifndef SCPI_LINE_ENDING
wuliqunyy 0:be95bfb06686 99 #error no termination character defined
wuliqunyy 0:be95bfb06686 100 #endif
wuliqunyy 0:be95bfb06686 101 len = writeData(context, SCPI_LINE_ENDING, strlen(SCPI_LINE_ENDING));
wuliqunyy 0:be95bfb06686 102 flushData(context);
wuliqunyy 0:be95bfb06686 103 return len;
wuliqunyy 0:be95bfb06686 104 } else {
wuliqunyy 0:be95bfb06686 105 return 0;
wuliqunyy 0:be95bfb06686 106 }
wuliqunyy 0:be95bfb06686 107 }
wuliqunyy 0:be95bfb06686 108
wuliqunyy 0:be95bfb06686 109 /**
wuliqunyy 0:be95bfb06686 110 * Conditionaly write ";"
wuliqunyy 0:be95bfb06686 111 * @param context
wuliqunyy 0:be95bfb06686 112 * @return number of characters written
wuliqunyy 0:be95bfb06686 113 */
wuliqunyy 0:be95bfb06686 114 static size_t writeSemicolon(scpi_t * context) {
wuliqunyy 0:be95bfb06686 115 if (context->output_count > 0) {
wuliqunyy 0:be95bfb06686 116 return writeData(context, ";", 1);
wuliqunyy 0:be95bfb06686 117 } else {
wuliqunyy 0:be95bfb06686 118 return 0;
wuliqunyy 0:be95bfb06686 119 }
wuliqunyy 0:be95bfb06686 120 }
wuliqunyy 0:be95bfb06686 121
wuliqunyy 0:be95bfb06686 122 /**
wuliqunyy 0:be95bfb06686 123 * Process command
wuliqunyy 0:be95bfb06686 124 * @param context
wuliqunyy 0:be95bfb06686 125 */
wuliqunyy 0:be95bfb06686 126 static scpi_bool_t processCommand(scpi_t * context) {
wuliqunyy 0:be95bfb06686 127 const scpi_command_t * cmd = context->param_list.cmd;
wuliqunyy 0:be95bfb06686 128 lex_state_t * state = &context->param_list.lex_state;
wuliqunyy 0:be95bfb06686 129 scpi_bool_t result = TRUE;
wuliqunyy 0:be95bfb06686 130
wuliqunyy 0:be95bfb06686 131 /* conditionaly write ; */
wuliqunyy 0:be95bfb06686 132 writeSemicolon(context);
wuliqunyy 0:be95bfb06686 133
wuliqunyy 0:be95bfb06686 134 context->cmd_error = FALSE;
wuliqunyy 0:be95bfb06686 135 context->output_count = 0;
wuliqunyy 0:be95bfb06686 136 context->input_count = 0;
wuliqunyy 0:be95bfb06686 137 context->arbitrary_reminding = 0;
wuliqunyy 0:be95bfb06686 138
wuliqunyy 0:be95bfb06686 139 /* if callback exists - call command callback */
wuliqunyy 0:be95bfb06686 140 if (cmd->callback != NULL) {
wuliqunyy 0:be95bfb06686 141 if ((cmd->callback(context) != SCPI_RES_OK)) {
wuliqunyy 0:be95bfb06686 142 if (!context->cmd_error) {
wuliqunyy 0:be95bfb06686 143 SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR);
wuliqunyy 0:be95bfb06686 144 }
wuliqunyy 0:be95bfb06686 145 result = FALSE;
wuliqunyy 0:be95bfb06686 146 } else {
wuliqunyy 0:be95bfb06686 147 if (context->cmd_error) {
wuliqunyy 0:be95bfb06686 148 result = FALSE;
wuliqunyy 0:be95bfb06686 149 }
wuliqunyy 0:be95bfb06686 150 }
wuliqunyy 0:be95bfb06686 151 }
wuliqunyy 0:be95bfb06686 152
wuliqunyy 0:be95bfb06686 153 /* set error if command callback did not read all parameters */
wuliqunyy 0:be95bfb06686 154 if (state->pos < (state->buffer + state->len) && !context->cmd_error) {
wuliqunyy 0:be95bfb06686 155 SCPI_ErrorPush(context, SCPI_ERROR_PARAMETER_NOT_ALLOWED);
wuliqunyy 0:be95bfb06686 156 result = FALSE;
wuliqunyy 0:be95bfb06686 157 }
wuliqunyy 0:be95bfb06686 158
wuliqunyy 0:be95bfb06686 159 return result;
wuliqunyy 0:be95bfb06686 160 }
wuliqunyy 0:be95bfb06686 161
wuliqunyy 0:be95bfb06686 162 /**
wuliqunyy 0:be95bfb06686 163 * Cycle all patterns and search matching pattern. Execute command callback.
wuliqunyy 0:be95bfb06686 164 * @param context
wuliqunyy 0:be95bfb06686 165 * @result TRUE if context->paramlist is filled with correct values
wuliqunyy 0:be95bfb06686 166 */
wuliqunyy 0:be95bfb06686 167 static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len) {
wuliqunyy 0:be95bfb06686 168 int32_t i;
wuliqunyy 0:be95bfb06686 169 const scpi_command_t * cmd;
wuliqunyy 0:be95bfb06686 170
wuliqunyy 0:be95bfb06686 171 for (i = 0; context->cmdlist[i].pattern != NULL; i++) {
wuliqunyy 0:be95bfb06686 172 cmd = &context->cmdlist[i];
wuliqunyy 0:be95bfb06686 173 if (matchCommand(cmd->pattern, header, len, NULL, 0, 0)) {
wuliqunyy 0:be95bfb06686 174 context->param_list.cmd = cmd;
wuliqunyy 0:be95bfb06686 175 return TRUE;
wuliqunyy 0:be95bfb06686 176 }
wuliqunyy 0:be95bfb06686 177 }
wuliqunyy 0:be95bfb06686 178 return FALSE;
wuliqunyy 0:be95bfb06686 179 }
wuliqunyy 0:be95bfb06686 180
wuliqunyy 0:be95bfb06686 181 /**
wuliqunyy 0:be95bfb06686 182 * Parse one command line
wuliqunyy 0:be95bfb06686 183 * @param context
wuliqunyy 0:be95bfb06686 184 * @param data - complete command line
wuliqunyy 0:be95bfb06686 185 * @param len - command line length
wuliqunyy 0:be95bfb06686 186 * @return FALSE if there was some error during evaluation of commands
wuliqunyy 0:be95bfb06686 187 */
wuliqunyy 0:be95bfb06686 188 scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len) {
wuliqunyy 0:be95bfb06686 189 scpi_bool_t result = TRUE;
wuliqunyy 0:be95bfb06686 190 scpi_parser_state_t * state;
wuliqunyy 0:be95bfb06686 191 int r;
wuliqunyy 0:be95bfb06686 192 scpi_token_t cmd_prev = {SCPI_TOKEN_UNKNOWN, NULL, 0};
wuliqunyy 0:be95bfb06686 193
wuliqunyy 0:be95bfb06686 194 if (context == NULL) {
wuliqunyy 0:be95bfb06686 195 return FALSE;
wuliqunyy 0:be95bfb06686 196 }
wuliqunyy 0:be95bfb06686 197
wuliqunyy 0:be95bfb06686 198 state = &context->parser_state;
wuliqunyy 0:be95bfb06686 199 context->output_count = 0;
wuliqunyy 0:be95bfb06686 200
wuliqunyy 0:be95bfb06686 201 while (1) {
wuliqunyy 0:be95bfb06686 202 r = scpiParser_detectProgramMessageUnit(state, data, len);
wuliqunyy 0:be95bfb06686 203
wuliqunyy 0:be95bfb06686 204 if (state->programHeader.type == SCPI_TOKEN_INVALID) {
wuliqunyy 0:be95bfb06686 205 SCPI_ErrorPush(context, SCPI_ERROR_INVALID_CHARACTER);
wuliqunyy 0:be95bfb06686 206 result = FALSE;
wuliqunyy 0:be95bfb06686 207 } else if (state->programHeader.len > 0) {
wuliqunyy 0:be95bfb06686 208
wuliqunyy 0:be95bfb06686 209 composeCompoundCommand(&cmd_prev, &state->programHeader);
wuliqunyy 0:be95bfb06686 210
wuliqunyy 0:be95bfb06686 211 if (findCommandHeader(context, state->programHeader.ptr, state->programHeader.len)) {
wuliqunyy 0:be95bfb06686 212
wuliqunyy 0:be95bfb06686 213 context->param_list.lex_state.buffer = state->programData.ptr;
wuliqunyy 0:be95bfb06686 214 context->param_list.lex_state.pos = context->param_list.lex_state.buffer;
wuliqunyy 0:be95bfb06686 215 context->param_list.lex_state.len = state->programData.len;
wuliqunyy 0:be95bfb06686 216 context->param_list.cmd_raw.data = state->programHeader.ptr;
wuliqunyy 0:be95bfb06686 217 context->param_list.cmd_raw.position = 0;
wuliqunyy 0:be95bfb06686 218 context->param_list.cmd_raw.length = state->programHeader.len;
wuliqunyy 0:be95bfb06686 219
wuliqunyy 0:be95bfb06686 220 result &= processCommand(context);
wuliqunyy 0:be95bfb06686 221 cmd_prev = state->programHeader;
wuliqunyy 0:be95bfb06686 222 } else {
wuliqunyy 0:be95bfb06686 223 /* place undefined header with error */
wuliqunyy 0:be95bfb06686 224 /* calculate length of errornouse header and trim \r\n */
wuliqunyy 0:be95bfb06686 225 size_t r2 = r;
wuliqunyy 0:be95bfb06686 226 while (r2 > 0 && (data[r2 - 1] == '\r' || data[r2 - 1] == '\n')) r2--;
wuliqunyy 0:be95bfb06686 227 SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data, r2);
wuliqunyy 0:be95bfb06686 228 result = FALSE;
wuliqunyy 0:be95bfb06686 229 }
wuliqunyy 0:be95bfb06686 230 }
wuliqunyy 0:be95bfb06686 231
wuliqunyy 0:be95bfb06686 232 if (r < len) {
wuliqunyy 0:be95bfb06686 233 data += r;
wuliqunyy 0:be95bfb06686 234 len -= r;
wuliqunyy 0:be95bfb06686 235 } else {
wuliqunyy 0:be95bfb06686 236 break;
wuliqunyy 0:be95bfb06686 237 }
wuliqunyy 0:be95bfb06686 238
wuliqunyy 0:be95bfb06686 239 }
wuliqunyy 0:be95bfb06686 240
wuliqunyy 0:be95bfb06686 241 /* conditionaly write new line */
wuliqunyy 0:be95bfb06686 242 writeNewLine(context);
wuliqunyy 0:be95bfb06686 243
wuliqunyy 0:be95bfb06686 244 return result;
wuliqunyy 0:be95bfb06686 245 }
wuliqunyy 0:be95bfb06686 246
wuliqunyy 0:be95bfb06686 247 /**
wuliqunyy 0:be95bfb06686 248 * Initialize SCPI context structure
wuliqunyy 0:be95bfb06686 249 * @param context
wuliqunyy 0:be95bfb06686 250 * @param commands
wuliqunyy 0:be95bfb06686 251 * @param interface
wuliqunyy 0:be95bfb06686 252 * @param units
wuliqunyy 0:be95bfb06686 253 * @param idn1
wuliqunyy 0:be95bfb06686 254 * @param idn2
wuliqunyy 0:be95bfb06686 255 * @param idn3
wuliqunyy 0:be95bfb06686 256 * @param idn4
wuliqunyy 0:be95bfb06686 257 * @param input_buffer
wuliqunyy 0:be95bfb06686 258 * @param input_buffer_length
wuliqunyy 0:be95bfb06686 259 * @param error_queue_data
wuliqunyy 0:be95bfb06686 260 * @param error_queue_size
wuliqunyy 0:be95bfb06686 261 */
wuliqunyy 0:be95bfb06686 262 void SCPI_Init(scpi_t * context,
wuliqunyy 0:be95bfb06686 263 const scpi_command_t * commands,
wuliqunyy 0:be95bfb06686 264 scpi_interface_t * interface,
wuliqunyy 0:be95bfb06686 265 const scpi_unit_def_t * units,
wuliqunyy 0:be95bfb06686 266 const char * idn1, const char * idn2, const char * idn3, const char * idn4,
wuliqunyy 0:be95bfb06686 267 char * input_buffer, size_t input_buffer_length,
wuliqunyy 0:be95bfb06686 268 scpi_error_t * error_queue_data, int16_t error_queue_size) {
wuliqunyy 0:be95bfb06686 269 memset(context, 0, sizeof (*context));
wuliqunyy 0:be95bfb06686 270 context->cmdlist = commands;
wuliqunyy 0:be95bfb06686 271 context->interface = interface;
wuliqunyy 0:be95bfb06686 272 context->units = units;
wuliqunyy 0:be95bfb06686 273 context->idn[0] = idn1;
wuliqunyy 0:be95bfb06686 274 context->idn[1] = idn2;
wuliqunyy 0:be95bfb06686 275 context->idn[2] = idn3;
wuliqunyy 0:be95bfb06686 276 context->idn[3] = idn4;
wuliqunyy 0:be95bfb06686 277 context->buffer.data = input_buffer;
wuliqunyy 0:be95bfb06686 278 context->buffer.length = input_buffer_length;
wuliqunyy 0:be95bfb06686 279 context->buffer.position = 0;
wuliqunyy 0:be95bfb06686 280 SCPI_ErrorInit(context, error_queue_data, error_queue_size);
wuliqunyy 0:be95bfb06686 281 }
wuliqunyy 0:be95bfb06686 282
wuliqunyy 0:be95bfb06686 283 #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE
wuliqunyy 0:be95bfb06686 284
wuliqunyy 0:be95bfb06686 285 /**
wuliqunyy 0:be95bfb06686 286 * Initialize context's
wuliqunyy 0:be95bfb06686 287 * @param context
wuliqunyy 0:be95bfb06686 288 * @param data
wuliqunyy 0:be95bfb06686 289 * @param len
wuliqunyy 0:be95bfb06686 290 * @return
wuliqunyy 0:be95bfb06686 291 */
wuliqunyy 0:be95bfb06686 292 void SCPI_InitHeap(scpi_t * context,
wuliqunyy 0:be95bfb06686 293 char * error_info_heap, size_t error_info_heap_length) {
wuliqunyy 0:be95bfb06686 294 scpiheap_init(&context->error_info_heap, error_info_heap, error_info_heap_length);
wuliqunyy 0:be95bfb06686 295 }
wuliqunyy 0:be95bfb06686 296 #endif
wuliqunyy 0:be95bfb06686 297
wuliqunyy 0:be95bfb06686 298 /**
wuliqunyy 0:be95bfb06686 299 * Interface to the application. Adds data to system buffer and try to search
wuliqunyy 0:be95bfb06686 300 * command line termination. If the termination is found or if len=0, command
wuliqunyy 0:be95bfb06686 301 * parser is called.
wuliqunyy 0:be95bfb06686 302 *
wuliqunyy 0:be95bfb06686 303 * @param context
wuliqunyy 0:be95bfb06686 304 * @param data - data to process
wuliqunyy 0:be95bfb06686 305 * @param len - length of data
wuliqunyy 0:be95bfb06686 306 * @return
wuliqunyy 0:be95bfb06686 307 */
wuliqunyy 0:be95bfb06686 308 scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len) {
wuliqunyy 0:be95bfb06686 309 scpi_bool_t result = TRUE;
wuliqunyy 0:be95bfb06686 310 size_t totcmdlen = 0;
wuliqunyy 0:be95bfb06686 311 int cmdlen = 0;
wuliqunyy 0:be95bfb06686 312
wuliqunyy 0:be95bfb06686 313 if (len == 0) {
wuliqunyy 0:be95bfb06686 314 context->buffer.data[context->buffer.position] = 0;
wuliqunyy 0:be95bfb06686 315 result = SCPI_Parse(context, context->buffer.data, context->buffer.position);
wuliqunyy 0:be95bfb06686 316 context->buffer.position = 0;
wuliqunyy 0:be95bfb06686 317 } else {
wuliqunyy 0:be95bfb06686 318 int buffer_free;
wuliqunyy 0:be95bfb06686 319
wuliqunyy 0:be95bfb06686 320 buffer_free = context->buffer.length - context->buffer.position;
wuliqunyy 0:be95bfb06686 321 if (len > (buffer_free - 1)) {
wuliqunyy 0:be95bfb06686 322 /* Input buffer overrun - invalidate buffer */
wuliqunyy 0:be95bfb06686 323 context->buffer.position = 0;
wuliqunyy 0:be95bfb06686 324 context->buffer.data[context->buffer.position] = 0;
wuliqunyy 0:be95bfb06686 325 SCPI_ErrorPush(context, SCPI_ERROR_INPUT_BUFFER_OVERRUN);
wuliqunyy 0:be95bfb06686 326 return FALSE;
wuliqunyy 0:be95bfb06686 327 }
wuliqunyy 0:be95bfb06686 328 memcpy(&context->buffer.data[context->buffer.position], data, len);
wuliqunyy 0:be95bfb06686 329 context->buffer.position += len;
wuliqunyy 0:be95bfb06686 330 context->buffer.data[context->buffer.position] = 0;
wuliqunyy 0:be95bfb06686 331
wuliqunyy 0:be95bfb06686 332
wuliqunyy 0:be95bfb06686 333 while (1) {
wuliqunyy 0:be95bfb06686 334 cmdlen = scpiParser_detectProgramMessageUnit(&context->parser_state, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen);
wuliqunyy 0:be95bfb06686 335 totcmdlen += cmdlen;
wuliqunyy 0:be95bfb06686 336
wuliqunyy 0:be95bfb06686 337 if (context->parser_state.termination == SCPI_MESSAGE_TERMINATION_NL) {
wuliqunyy 0:be95bfb06686 338 result = SCPI_Parse(context, context->buffer.data, totcmdlen);
wuliqunyy 0:be95bfb06686 339 memmove(context->buffer.data, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen);
wuliqunyy 0:be95bfb06686 340 context->buffer.position -= totcmdlen;
wuliqunyy 0:be95bfb06686 341 totcmdlen = 0;
wuliqunyy 0:be95bfb06686 342 } else {
wuliqunyy 0:be95bfb06686 343 if (context->parser_state.programHeader.type == SCPI_TOKEN_UNKNOWN
wuliqunyy 0:be95bfb06686 344 && context->parser_state.termination == SCPI_MESSAGE_TERMINATION_NONE) break;
wuliqunyy 0:be95bfb06686 345 if (totcmdlen >= context->buffer.position) break;
wuliqunyy 0:be95bfb06686 346 }
wuliqunyy 0:be95bfb06686 347 }
wuliqunyy 0:be95bfb06686 348 }
wuliqunyy 0:be95bfb06686 349
wuliqunyy 0:be95bfb06686 350 return result;
wuliqunyy 0:be95bfb06686 351 }
wuliqunyy 0:be95bfb06686 352
wuliqunyy 0:be95bfb06686 353 /* writing results */
wuliqunyy 0:be95bfb06686 354
wuliqunyy 0:be95bfb06686 355 /**
wuliqunyy 0:be95bfb06686 356 * Write raw string result to the output
wuliqunyy 0:be95bfb06686 357 * @param context
wuliqunyy 0:be95bfb06686 358 * @param data
wuliqunyy 0:be95bfb06686 359 * @return
wuliqunyy 0:be95bfb06686 360 */
wuliqunyy 0:be95bfb06686 361 size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len) {
wuliqunyy 0:be95bfb06686 362 size_t result = 0;
wuliqunyy 0:be95bfb06686 363 result += writeDelimiter(context);
wuliqunyy 0:be95bfb06686 364 result += writeData(context, data, len);
wuliqunyy 0:be95bfb06686 365 context->output_count++;
wuliqunyy 0:be95bfb06686 366 return result;
wuliqunyy 0:be95bfb06686 367 }
wuliqunyy 0:be95bfb06686 368
wuliqunyy 0:be95bfb06686 369 /**
wuliqunyy 0:be95bfb06686 370 * Return prefix of nondecimal base
wuliqunyy 0:be95bfb06686 371 * @param base
wuliqunyy 0:be95bfb06686 372 * @return
wuliqunyy 0:be95bfb06686 373 */
wuliqunyy 0:be95bfb06686 374 static const char * getBasePrefix(int8_t base) {
wuliqunyy 0:be95bfb06686 375 switch (base) {
wuliqunyy 0:be95bfb06686 376 case 2: return "#B";
wuliqunyy 0:be95bfb06686 377 case 8: return "#Q";
wuliqunyy 0:be95bfb06686 378 case 16: return "#H";
wuliqunyy 0:be95bfb06686 379 default: return NULL;
wuliqunyy 0:be95bfb06686 380 }
wuliqunyy 0:be95bfb06686 381 }
wuliqunyy 0:be95bfb06686 382
wuliqunyy 0:be95bfb06686 383 /**
wuliqunyy 0:be95bfb06686 384 * Write signed/unsigned 32 bit integer value in specific base to the result
wuliqunyy 0:be95bfb06686 385 * @param context
wuliqunyy 0:be95bfb06686 386 * @param val
wuliqunyy 0:be95bfb06686 387 * @param base
wuliqunyy 0:be95bfb06686 388 * @param sign
wuliqunyy 0:be95bfb06686 389 * @return
wuliqunyy 0:be95bfb06686 390 */
wuliqunyy 0:be95bfb06686 391 static size_t resultUInt32BaseSign(scpi_t * context, uint32_t val, int8_t base, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 392 char buffer[32 + 1];
wuliqunyy 0:be95bfb06686 393 const char * basePrefix;
wuliqunyy 0:be95bfb06686 394 size_t result = 0;
wuliqunyy 0:be95bfb06686 395 size_t len;
wuliqunyy 0:be95bfb06686 396
wuliqunyy 0:be95bfb06686 397 len = UInt32ToStrBaseSign(val, buffer, sizeof (buffer), base, sign);
wuliqunyy 0:be95bfb06686 398 basePrefix = getBasePrefix(base);
wuliqunyy 0:be95bfb06686 399
wuliqunyy 0:be95bfb06686 400 result += writeDelimiter(context);
wuliqunyy 0:be95bfb06686 401 if (basePrefix != NULL) {
wuliqunyy 0:be95bfb06686 402 result += writeData(context, basePrefix, 2);
wuliqunyy 0:be95bfb06686 403 }
wuliqunyy 0:be95bfb06686 404 result += writeData(context, buffer, len);
wuliqunyy 0:be95bfb06686 405 context->output_count++;
wuliqunyy 0:be95bfb06686 406 return result;
wuliqunyy 0:be95bfb06686 407 }
wuliqunyy 0:be95bfb06686 408
wuliqunyy 0:be95bfb06686 409 /**
wuliqunyy 0:be95bfb06686 410 * Write signed/unsigned 64 bit integer value in specific base to the result
wuliqunyy 0:be95bfb06686 411 * @param context
wuliqunyy 0:be95bfb06686 412 * @param val
wuliqunyy 0:be95bfb06686 413 * @param base
wuliqunyy 0:be95bfb06686 414 * @param sign
wuliqunyy 0:be95bfb06686 415 * @return
wuliqunyy 0:be95bfb06686 416 */
wuliqunyy 0:be95bfb06686 417 static size_t resultUInt64BaseSign(scpi_t * context, uint64_t val, int8_t base, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 418 char buffer[64 + 1];
wuliqunyy 0:be95bfb06686 419 const char * basePrefix;
wuliqunyy 0:be95bfb06686 420 size_t result = 0;
wuliqunyy 0:be95bfb06686 421 size_t len;
wuliqunyy 0:be95bfb06686 422
wuliqunyy 0:be95bfb06686 423 len = UInt64ToStrBaseSign(val, buffer, sizeof (buffer), base, sign);
wuliqunyy 0:be95bfb06686 424 basePrefix = getBasePrefix(base);
wuliqunyy 0:be95bfb06686 425
wuliqunyy 0:be95bfb06686 426 result += writeDelimiter(context);
wuliqunyy 0:be95bfb06686 427 if (basePrefix != NULL) {
wuliqunyy 0:be95bfb06686 428 result += writeData(context, basePrefix, 2);
wuliqunyy 0:be95bfb06686 429 }
wuliqunyy 0:be95bfb06686 430 result += writeData(context, buffer, len);
wuliqunyy 0:be95bfb06686 431 context->output_count++;
wuliqunyy 0:be95bfb06686 432 return result;
wuliqunyy 0:be95bfb06686 433 }
wuliqunyy 0:be95bfb06686 434
wuliqunyy 0:be95bfb06686 435 /**
wuliqunyy 0:be95bfb06686 436 * Write signed 32 bit integer value to the result
wuliqunyy 0:be95bfb06686 437 * @param context
wuliqunyy 0:be95bfb06686 438 * @param val
wuliqunyy 0:be95bfb06686 439 * @return
wuliqunyy 0:be95bfb06686 440 */
wuliqunyy 0:be95bfb06686 441 size_t SCPI_ResultInt32(scpi_t * context, int32_t val) {
wuliqunyy 0:be95bfb06686 442 return resultUInt32BaseSign(context, val, 10, TRUE);
wuliqunyy 0:be95bfb06686 443 }
wuliqunyy 0:be95bfb06686 444
wuliqunyy 0:be95bfb06686 445 /**
wuliqunyy 0:be95bfb06686 446 * Write unsigned 32 bit integer value in specific base to the result
wuliqunyy 0:be95bfb06686 447 * Write signed/unsigned 32 bit integer value in specific base to the result
wuliqunyy 0:be95bfb06686 448 * @param context
wuliqunyy 0:be95bfb06686 449 * @param val
wuliqunyy 0:be95bfb06686 450 * @return
wuliqunyy 0:be95bfb06686 451 */
wuliqunyy 0:be95bfb06686 452 size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base) {
wuliqunyy 0:be95bfb06686 453 return resultUInt32BaseSign(context, val, base, FALSE);
wuliqunyy 0:be95bfb06686 454 }
wuliqunyy 0:be95bfb06686 455
wuliqunyy 0:be95bfb06686 456 /**
wuliqunyy 0:be95bfb06686 457 * Write signed 64 bit integer value to the result
wuliqunyy 0:be95bfb06686 458 * @param context
wuliqunyy 0:be95bfb06686 459 * @param val
wuliqunyy 0:be95bfb06686 460 * @return
wuliqunyy 0:be95bfb06686 461 */
wuliqunyy 0:be95bfb06686 462 size_t SCPI_ResultInt64(scpi_t * context, int64_t val) {
wuliqunyy 0:be95bfb06686 463 return resultUInt64BaseSign(context, val, 10, TRUE);
wuliqunyy 0:be95bfb06686 464 }
wuliqunyy 0:be95bfb06686 465
wuliqunyy 0:be95bfb06686 466 /**
wuliqunyy 0:be95bfb06686 467 * Write unsigned 64 bit integer value in specific base to the result
wuliqunyy 0:be95bfb06686 468 * @param context
wuliqunyy 0:be95bfb06686 469 * @param val
wuliqunyy 0:be95bfb06686 470 * @return
wuliqunyy 0:be95bfb06686 471 */
wuliqunyy 0:be95bfb06686 472 size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base) {
wuliqunyy 0:be95bfb06686 473 return resultUInt64BaseSign(context, val, base, FALSE);
wuliqunyy 0:be95bfb06686 474 }
wuliqunyy 0:be95bfb06686 475
wuliqunyy 0:be95bfb06686 476 /**
wuliqunyy 0:be95bfb06686 477 * Write float (32 bit) value to the result
wuliqunyy 0:be95bfb06686 478 * @param context
wuliqunyy 0:be95bfb06686 479 * @param val
wuliqunyy 0:be95bfb06686 480 * @return
wuliqunyy 0:be95bfb06686 481 */
wuliqunyy 0:be95bfb06686 482 size_t SCPI_ResultFloat(scpi_t * context, float val) {
wuliqunyy 0:be95bfb06686 483 char buffer[32];
wuliqunyy 0:be95bfb06686 484 size_t result = 0;
wuliqunyy 0:be95bfb06686 485 size_t len = SCPI_FloatToStr(val, buffer, sizeof (buffer));
wuliqunyy 0:be95bfb06686 486 result += writeDelimiter(context);
wuliqunyy 0:be95bfb06686 487 result += writeData(context, buffer, len);
wuliqunyy 0:be95bfb06686 488 context->output_count++;
wuliqunyy 0:be95bfb06686 489 return result;
wuliqunyy 0:be95bfb06686 490 }
wuliqunyy 0:be95bfb06686 491
wuliqunyy 0:be95bfb06686 492 /**
wuliqunyy 0:be95bfb06686 493 * Write double (64bit) value to the result
wuliqunyy 0:be95bfb06686 494 * @param context
wuliqunyy 0:be95bfb06686 495 * @param val
wuliqunyy 0:be95bfb06686 496 * @return
wuliqunyy 0:be95bfb06686 497 */
wuliqunyy 0:be95bfb06686 498 size_t SCPI_ResultDouble(scpi_t * context, double val) {
wuliqunyy 0:be95bfb06686 499 char buffer[32];
wuliqunyy 0:be95bfb06686 500 size_t result = 0;
wuliqunyy 0:be95bfb06686 501 size_t len = SCPI_DoubleToStr(val, buffer, sizeof (buffer));
wuliqunyy 0:be95bfb06686 502 result += writeDelimiter(context);
wuliqunyy 0:be95bfb06686 503 result += writeData(context, buffer, len);
wuliqunyy 0:be95bfb06686 504 context->output_count++;
wuliqunyy 0:be95bfb06686 505 return result;
wuliqunyy 0:be95bfb06686 506 }
wuliqunyy 0:be95bfb06686 507
wuliqunyy 0:be95bfb06686 508 /**
wuliqunyy 0:be95bfb06686 509 * Write string withn " to the result
wuliqunyy 0:be95bfb06686 510 * @param context
wuliqunyy 0:be95bfb06686 511 * @param data
wuliqunyy 0:be95bfb06686 512 * @return
wuliqunyy 0:be95bfb06686 513 */
wuliqunyy 0:be95bfb06686 514 size_t SCPI_ResultText(scpi_t * context, const char * data) {
wuliqunyy 0:be95bfb06686 515 size_t result = 0;
wuliqunyy 0:be95bfb06686 516 size_t len = strlen(data);
wuliqunyy 0:be95bfb06686 517 const char * quote;
wuliqunyy 0:be95bfb06686 518 result += writeDelimiter(context);
wuliqunyy 0:be95bfb06686 519 result += writeData(context, "\"", 1);
wuliqunyy 0:be95bfb06686 520 while ((quote = strnpbrk(data, len, "\""))) {
wuliqunyy 0:be95bfb06686 521 result += writeData(context, data, quote - data + 1);
wuliqunyy 0:be95bfb06686 522 result += writeData(context, "\"", 1);
wuliqunyy 0:be95bfb06686 523 len -= quote - data + 1;
wuliqunyy 0:be95bfb06686 524 data = quote + 1;
wuliqunyy 0:be95bfb06686 525 }
wuliqunyy 0:be95bfb06686 526 result += writeData(context, data, len);
wuliqunyy 0:be95bfb06686 527 result += writeData(context, "\"", 1);
wuliqunyy 0:be95bfb06686 528 context->output_count++;
wuliqunyy 0:be95bfb06686 529 return result;
wuliqunyy 0:be95bfb06686 530 }
wuliqunyy 0:be95bfb06686 531
wuliqunyy 0:be95bfb06686 532 /**
wuliqunyy 0:be95bfb06686 533 * SCPI-99:21.8 Device-dependent error information.
wuliqunyy 0:be95bfb06686 534 * Write error information with the following syntax:
wuliqunyy 0:be95bfb06686 535 * <Error/event_number>,"<Error/event_description>[;<Device-dependent_info>]"
wuliqunyy 0:be95bfb06686 536 * The maximum string length of <Error/event_description> plus <Device-dependent_info>
wuliqunyy 0:be95bfb06686 537 * is SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH (255) characters.
wuliqunyy 0:be95bfb06686 538 *
wuliqunyy 0:be95bfb06686 539 * @param context
wuliqunyy 0:be95bfb06686 540 * @param error
wuliqunyy 0:be95bfb06686 541 * @return
wuliqunyy 0:be95bfb06686 542 */
wuliqunyy 0:be95bfb06686 543 size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error) {
wuliqunyy 0:be95bfb06686 544 size_t result = 0;
wuliqunyy 0:be95bfb06686 545 size_t outputlimit = SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH;
wuliqunyy 0:be95bfb06686 546 size_t step = 0;
wuliqunyy 0:be95bfb06686 547 const char * quote;
wuliqunyy 0:be95bfb06686 548
wuliqunyy 0:be95bfb06686 549 const char * data[SCPIDEFINE_DESCRIPTION_MAX_PARTS];
wuliqunyy 0:be95bfb06686 550 size_t len[SCPIDEFINE_DESCRIPTION_MAX_PARTS];
wuliqunyy 0:be95bfb06686 551 size_t i;
wuliqunyy 0:be95bfb06686 552
wuliqunyy 0:be95bfb06686 553 data[0] = SCPI_ErrorTranslate(error->error_code);
wuliqunyy 0:be95bfb06686 554 len[0] = strlen(data[0]);
wuliqunyy 0:be95bfb06686 555
wuliqunyy 0:be95bfb06686 556 #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION
wuliqunyy 0:be95bfb06686 557 data[1] = error->device_dependent_info;
wuliqunyy 0:be95bfb06686 558 #if USE_MEMORY_ALLOCATION_FREE
wuliqunyy 0:be95bfb06686 559 len[1] = error->device_dependent_info ? strlen(data[1]) : 0;
wuliqunyy 0:be95bfb06686 560 #else
wuliqunyy 0:be95bfb06686 561 SCPIDEFINE_get_parts(&context->error_info_heap, data[1], &len[1], &data[2], &len[2]);
wuliqunyy 0:be95bfb06686 562 #endif
wuliqunyy 0:be95bfb06686 563 #endif
wuliqunyy 0:be95bfb06686 564
wuliqunyy 0:be95bfb06686 565 result += SCPI_ResultInt32(context, error->error_code);
wuliqunyy 0:be95bfb06686 566 result += writeDelimiter(context);
wuliqunyy 0:be95bfb06686 567 result += writeData(context, "\"", 1);
wuliqunyy 0:be95bfb06686 568
wuliqunyy 0:be95bfb06686 569 for (i = 0; (i < SCPIDEFINE_DESCRIPTION_MAX_PARTS) && data[i] && outputlimit; i++) {
wuliqunyy 0:be95bfb06686 570 if (i == 1) {
wuliqunyy 0:be95bfb06686 571 result += writeSemicolon(context);
wuliqunyy 0:be95bfb06686 572 outputlimit -= 1;
wuliqunyy 0:be95bfb06686 573 }
wuliqunyy 0:be95bfb06686 574 if (len[i] > outputlimit) {
wuliqunyy 0:be95bfb06686 575 len[i] = outputlimit;
wuliqunyy 0:be95bfb06686 576 }
wuliqunyy 0:be95bfb06686 577
wuliqunyy 0:be95bfb06686 578 while ((quote = strnpbrk(data[i], len[i], "\""))) {
wuliqunyy 0:be95bfb06686 579 if ((step = quote - data[i] + 1) >= outputlimit) {
wuliqunyy 0:be95bfb06686 580 len[i] -= 1;
wuliqunyy 0:be95bfb06686 581 outputlimit -= 1;
wuliqunyy 0:be95bfb06686 582 break;
wuliqunyy 0:be95bfb06686 583 }
wuliqunyy 0:be95bfb06686 584 result += writeData(context, data[i], step);
wuliqunyy 0:be95bfb06686 585 result += writeData(context, "\"", 1);
wuliqunyy 0:be95bfb06686 586 len[i] -= step;
wuliqunyy 0:be95bfb06686 587 outputlimit -= step + 1;
wuliqunyy 0:be95bfb06686 588 data[i] = quote + 1;
wuliqunyy 0:be95bfb06686 589 if (len[i] > outputlimit) {
wuliqunyy 0:be95bfb06686 590 len[i] = outputlimit;
wuliqunyy 0:be95bfb06686 591 }
wuliqunyy 0:be95bfb06686 592 }
wuliqunyy 0:be95bfb06686 593
wuliqunyy 0:be95bfb06686 594 result += writeData(context, data[i], len[i]);
wuliqunyy 0:be95bfb06686 595 outputlimit -= len[i];
wuliqunyy 0:be95bfb06686 596 }
wuliqunyy 0:be95bfb06686 597 result += writeData(context, "\"", 1);
wuliqunyy 0:be95bfb06686 598
wuliqunyy 0:be95bfb06686 599 return result;
wuliqunyy 0:be95bfb06686 600 }
wuliqunyy 0:be95bfb06686 601
wuliqunyy 0:be95bfb06686 602 /**
wuliqunyy 0:be95bfb06686 603 * Write arbitrary block header with length
wuliqunyy 0:be95bfb06686 604 * @param context
wuliqunyy 0:be95bfb06686 605 * @param len
wuliqunyy 0:be95bfb06686 606 * @return
wuliqunyy 0:be95bfb06686 607 */
wuliqunyy 0:be95bfb06686 608 size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len) {
wuliqunyy 0:be95bfb06686 609 char block_header[12];
wuliqunyy 0:be95bfb06686 610 size_t header_len;
wuliqunyy 0:be95bfb06686 611 block_header[0] = '#';
wuliqunyy 0:be95bfb06686 612 SCPI_UInt32ToStrBase((uint32_t) len, block_header + 2, 10, 10);
wuliqunyy 0:be95bfb06686 613
wuliqunyy 0:be95bfb06686 614 header_len = strlen(block_header + 2);
wuliqunyy 0:be95bfb06686 615 block_header[1] = (char) (header_len + '0');
wuliqunyy 0:be95bfb06686 616
wuliqunyy 0:be95bfb06686 617 context->arbitrary_reminding = len;
wuliqunyy 0:be95bfb06686 618 return writeData(context, block_header, header_len + 2);
wuliqunyy 0:be95bfb06686 619 }
wuliqunyy 0:be95bfb06686 620
wuliqunyy 0:be95bfb06686 621 /**
wuliqunyy 0:be95bfb06686 622 * Add data to arbitrary block
wuliqunyy 0:be95bfb06686 623 * @param context
wuliqunyy 0:be95bfb06686 624 * @param data
wuliqunyy 0:be95bfb06686 625 * @param len
wuliqunyy 0:be95bfb06686 626 * @return
wuliqunyy 0:be95bfb06686 627 */
wuliqunyy 0:be95bfb06686 628 size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len) {
wuliqunyy 0:be95bfb06686 629
wuliqunyy 0:be95bfb06686 630 if (context->arbitrary_reminding < len) {
wuliqunyy 0:be95bfb06686 631 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 632 return 0;
wuliqunyy 0:be95bfb06686 633 }
wuliqunyy 0:be95bfb06686 634
wuliqunyy 0:be95bfb06686 635 context->arbitrary_reminding -= len;
wuliqunyy 0:be95bfb06686 636
wuliqunyy 0:be95bfb06686 637 if (context->arbitrary_reminding == 0) {
wuliqunyy 0:be95bfb06686 638 context->output_count++;
wuliqunyy 0:be95bfb06686 639 }
wuliqunyy 0:be95bfb06686 640
wuliqunyy 0:be95bfb06686 641 return writeData(context, (const char *) data, len);
wuliqunyy 0:be95bfb06686 642 }
wuliqunyy 0:be95bfb06686 643
wuliqunyy 0:be95bfb06686 644 /**
wuliqunyy 0:be95bfb06686 645 * Write arbitrary block program data to the result
wuliqunyy 0:be95bfb06686 646 * @param context
wuliqunyy 0:be95bfb06686 647 * @param data
wuliqunyy 0:be95bfb06686 648 * @param len
wuliqunyy 0:be95bfb06686 649 * @return
wuliqunyy 0:be95bfb06686 650 */
wuliqunyy 0:be95bfb06686 651 size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len) {
wuliqunyy 0:be95bfb06686 652 size_t result = 0;
wuliqunyy 0:be95bfb06686 653 result += SCPI_ResultArbitraryBlockHeader(context, len);
wuliqunyy 0:be95bfb06686 654 result += SCPI_ResultArbitraryBlockData(context, data, len);
wuliqunyy 0:be95bfb06686 655 return result;
wuliqunyy 0:be95bfb06686 656 }
wuliqunyy 0:be95bfb06686 657
wuliqunyy 0:be95bfb06686 658 /**
wuliqunyy 0:be95bfb06686 659 * Write boolean value to the result
wuliqunyy 0:be95bfb06686 660 * @param context
wuliqunyy 0:be95bfb06686 661 * @param val
wuliqunyy 0:be95bfb06686 662 * @return
wuliqunyy 0:be95bfb06686 663 */
wuliqunyy 0:be95bfb06686 664 size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val) {
wuliqunyy 0:be95bfb06686 665 return resultUInt32BaseSign(context, val ? 1 : 0, 10, FALSE);
wuliqunyy 0:be95bfb06686 666 }
wuliqunyy 0:be95bfb06686 667
wuliqunyy 0:be95bfb06686 668 /* parsing parameters */
wuliqunyy 0:be95bfb06686 669
wuliqunyy 0:be95bfb06686 670 /**
wuliqunyy 0:be95bfb06686 671 * Invalidate token
wuliqunyy 0:be95bfb06686 672 * @param token
wuliqunyy 0:be95bfb06686 673 * @param ptr
wuliqunyy 0:be95bfb06686 674 */
wuliqunyy 0:be95bfb06686 675 static void invalidateToken(scpi_token_t * token, char * ptr) {
wuliqunyy 0:be95bfb06686 676 token->len = 0;
wuliqunyy 0:be95bfb06686 677 token->ptr = ptr;
wuliqunyy 0:be95bfb06686 678 token->type = SCPI_TOKEN_UNKNOWN;
wuliqunyy 0:be95bfb06686 679 }
wuliqunyy 0:be95bfb06686 680
wuliqunyy 0:be95bfb06686 681 /**
wuliqunyy 0:be95bfb06686 682 * Get one parameter from command line
wuliqunyy 0:be95bfb06686 683 * @param context
wuliqunyy 0:be95bfb06686 684 * @param parameter
wuliqunyy 0:be95bfb06686 685 * @param mandatory
wuliqunyy 0:be95bfb06686 686 * @return
wuliqunyy 0:be95bfb06686 687 */
wuliqunyy 0:be95bfb06686 688 scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 689 lex_state_t * state;
wuliqunyy 0:be95bfb06686 690
wuliqunyy 0:be95bfb06686 691 if (!parameter) {
wuliqunyy 0:be95bfb06686 692 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 693 return FALSE;
wuliqunyy 0:be95bfb06686 694 }
wuliqunyy 0:be95bfb06686 695
wuliqunyy 0:be95bfb06686 696 invalidateToken(parameter, NULL);
wuliqunyy 0:be95bfb06686 697
wuliqunyy 0:be95bfb06686 698 state = &context->param_list.lex_state;
wuliqunyy 0:be95bfb06686 699
wuliqunyy 0:be95bfb06686 700 if (state->pos >= (state->buffer + state->len)) {
wuliqunyy 0:be95bfb06686 701 if (mandatory) {
wuliqunyy 0:be95bfb06686 702 SCPI_ErrorPush(context, SCPI_ERROR_MISSING_PARAMETER);
wuliqunyy 0:be95bfb06686 703 } else {
wuliqunyy 0:be95bfb06686 704 parameter->type = SCPI_TOKEN_PROGRAM_MNEMONIC; /* TODO: select something different */
wuliqunyy 0:be95bfb06686 705 }
wuliqunyy 0:be95bfb06686 706 return FALSE;
wuliqunyy 0:be95bfb06686 707 }
wuliqunyy 0:be95bfb06686 708 if (context->input_count != 0) {
wuliqunyy 0:be95bfb06686 709 scpiLex_Comma(state, parameter);
wuliqunyy 0:be95bfb06686 710 if (parameter->type != SCPI_TOKEN_COMMA) {
wuliqunyy 0:be95bfb06686 711 invalidateToken(parameter, NULL);
wuliqunyy 0:be95bfb06686 712 SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SEPARATOR);
wuliqunyy 0:be95bfb06686 713 return FALSE;
wuliqunyy 0:be95bfb06686 714 }
wuliqunyy 0:be95bfb06686 715 }
wuliqunyy 0:be95bfb06686 716
wuliqunyy 0:be95bfb06686 717 context->input_count++;
wuliqunyy 0:be95bfb06686 718
wuliqunyy 0:be95bfb06686 719 scpiParser_parseProgramData(&context->param_list.lex_state, parameter);
wuliqunyy 0:be95bfb06686 720
wuliqunyy 0:be95bfb06686 721 switch (parameter->type) {
wuliqunyy 0:be95bfb06686 722 case SCPI_TOKEN_HEXNUM:
wuliqunyy 0:be95bfb06686 723 case SCPI_TOKEN_OCTNUM:
wuliqunyy 0:be95bfb06686 724 case SCPI_TOKEN_BINNUM:
wuliqunyy 0:be95bfb06686 725 case SCPI_TOKEN_PROGRAM_MNEMONIC:
wuliqunyy 0:be95bfb06686 726 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 727 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX:
wuliqunyy 0:be95bfb06686 728 case SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 729 case SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 730 case SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 731 case SCPI_TOKEN_PROGRAM_EXPRESSION:
wuliqunyy 0:be95bfb06686 732 return TRUE;
wuliqunyy 0:be95bfb06686 733 default:
wuliqunyy 0:be95bfb06686 734 invalidateToken(parameter, NULL);
wuliqunyy 0:be95bfb06686 735 SCPI_ErrorPush(context, SCPI_ERROR_INVALID_STRING_DATA);
wuliqunyy 0:be95bfb06686 736 return FALSE;
wuliqunyy 0:be95bfb06686 737 }
wuliqunyy 0:be95bfb06686 738 }
wuliqunyy 0:be95bfb06686 739
wuliqunyy 0:be95bfb06686 740 /**
wuliqunyy 0:be95bfb06686 741 * Detect if parameter is number
wuliqunyy 0:be95bfb06686 742 * @param parameter
wuliqunyy 0:be95bfb06686 743 * @param suffixAllowed
wuliqunyy 0:be95bfb06686 744 * @return
wuliqunyy 0:be95bfb06686 745 */
wuliqunyy 0:be95bfb06686 746 scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed) {
wuliqunyy 0:be95bfb06686 747 switch (parameter->type) {
wuliqunyy 0:be95bfb06686 748 case SCPI_TOKEN_HEXNUM:
wuliqunyy 0:be95bfb06686 749 case SCPI_TOKEN_OCTNUM:
wuliqunyy 0:be95bfb06686 750 case SCPI_TOKEN_BINNUM:
wuliqunyy 0:be95bfb06686 751 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 752 return TRUE;
wuliqunyy 0:be95bfb06686 753 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX:
wuliqunyy 0:be95bfb06686 754 return suffixAllowed;
wuliqunyy 0:be95bfb06686 755 default:
wuliqunyy 0:be95bfb06686 756 return FALSE;
wuliqunyy 0:be95bfb06686 757 }
wuliqunyy 0:be95bfb06686 758 }
wuliqunyy 0:be95bfb06686 759
wuliqunyy 0:be95bfb06686 760 /**
wuliqunyy 0:be95bfb06686 761 * Convert parameter to signed/unsigned 32 bit integer
wuliqunyy 0:be95bfb06686 762 * @param context
wuliqunyy 0:be95bfb06686 763 * @param parameter
wuliqunyy 0:be95bfb06686 764 * @param value result
wuliqunyy 0:be95bfb06686 765 * @param sign
wuliqunyy 0:be95bfb06686 766 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 767 */
wuliqunyy 0:be95bfb06686 768 static scpi_bool_t ParamSignToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 769
wuliqunyy 0:be95bfb06686 770 if (!value) {
wuliqunyy 0:be95bfb06686 771 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 772 return FALSE;
wuliqunyy 0:be95bfb06686 773 }
wuliqunyy 0:be95bfb06686 774
wuliqunyy 0:be95bfb06686 775 switch (parameter->type) {
wuliqunyy 0:be95bfb06686 776 case SCPI_TOKEN_HEXNUM:
wuliqunyy 0:be95bfb06686 777 return strBaseToUInt32(parameter->ptr, value, 16) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 778 case SCPI_TOKEN_OCTNUM:
wuliqunyy 0:be95bfb06686 779 return strBaseToUInt32(parameter->ptr, value, 8) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 780 case SCPI_TOKEN_BINNUM:
wuliqunyy 0:be95bfb06686 781 return strBaseToUInt32(parameter->ptr, value, 2) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 782 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 783 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX:
wuliqunyy 0:be95bfb06686 784 if (sign) {
wuliqunyy 0:be95bfb06686 785 return strBaseToInt32(parameter->ptr, (int32_t *) value, 10) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 786 } else {
wuliqunyy 0:be95bfb06686 787 return strBaseToUInt32(parameter->ptr, value, 10) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 788 }
wuliqunyy 0:be95bfb06686 789 default:
wuliqunyy 0:be95bfb06686 790 return FALSE;
wuliqunyy 0:be95bfb06686 791 }
wuliqunyy 0:be95bfb06686 792 }
wuliqunyy 0:be95bfb06686 793
wuliqunyy 0:be95bfb06686 794 /**
wuliqunyy 0:be95bfb06686 795 * Convert parameter to signed/unsigned 64 bit integer
wuliqunyy 0:be95bfb06686 796 * @param context
wuliqunyy 0:be95bfb06686 797 * @param parameter
wuliqunyy 0:be95bfb06686 798 * @param value result
wuliqunyy 0:be95bfb06686 799 * @param sign
wuliqunyy 0:be95bfb06686 800 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 801 */
wuliqunyy 0:be95bfb06686 802 static scpi_bool_t ParamSignToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 803
wuliqunyy 0:be95bfb06686 804 if (!value) {
wuliqunyy 0:be95bfb06686 805 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 806 return FALSE;
wuliqunyy 0:be95bfb06686 807 }
wuliqunyy 0:be95bfb06686 808
wuliqunyy 0:be95bfb06686 809 switch (parameter->type) {
wuliqunyy 0:be95bfb06686 810 case SCPI_TOKEN_HEXNUM:
wuliqunyy 0:be95bfb06686 811 return strBaseToUInt64(parameter->ptr, value, 16) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 812 case SCPI_TOKEN_OCTNUM:
wuliqunyy 0:be95bfb06686 813 return strBaseToUInt64(parameter->ptr, value, 8) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 814 case SCPI_TOKEN_BINNUM:
wuliqunyy 0:be95bfb06686 815 return strBaseToUInt64(parameter->ptr, value, 2) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 816 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 817 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX:
wuliqunyy 0:be95bfb06686 818 if (sign) {
wuliqunyy 0:be95bfb06686 819 return strBaseToInt64(parameter->ptr, (int64_t *) value, 10) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 820 } else {
wuliqunyy 0:be95bfb06686 821 return strBaseToUInt64(parameter->ptr, value, 10) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 822 }
wuliqunyy 0:be95bfb06686 823 default:
wuliqunyy 0:be95bfb06686 824 return FALSE;
wuliqunyy 0:be95bfb06686 825 }
wuliqunyy 0:be95bfb06686 826 }
wuliqunyy 0:be95bfb06686 827
wuliqunyy 0:be95bfb06686 828 /**
wuliqunyy 0:be95bfb06686 829 * Convert parameter to signed 32 bit integer
wuliqunyy 0:be95bfb06686 830 * @param context
wuliqunyy 0:be95bfb06686 831 * @param parameter
wuliqunyy 0:be95bfb06686 832 * @param value result
wuliqunyy 0:be95bfb06686 833 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 834 */
wuliqunyy 0:be95bfb06686 835 scpi_bool_t SCPI_ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value) {
wuliqunyy 0:be95bfb06686 836 return ParamSignToUInt32(context, parameter, (uint32_t *) value, TRUE);
wuliqunyy 0:be95bfb06686 837 }
wuliqunyy 0:be95bfb06686 838
wuliqunyy 0:be95bfb06686 839 /**
wuliqunyy 0:be95bfb06686 840 * Convert parameter to unsigned 32 bit integer
wuliqunyy 0:be95bfb06686 841 * @param context
wuliqunyy 0:be95bfb06686 842 * @param parameter
wuliqunyy 0:be95bfb06686 843 * @param value result
wuliqunyy 0:be95bfb06686 844 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 845 */
wuliqunyy 0:be95bfb06686 846 scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value) {
wuliqunyy 0:be95bfb06686 847 return ParamSignToUInt32(context, parameter, value, FALSE);
wuliqunyy 0:be95bfb06686 848 }
wuliqunyy 0:be95bfb06686 849
wuliqunyy 0:be95bfb06686 850 /**
wuliqunyy 0:be95bfb06686 851 * Convert parameter to signed 64 bit integer
wuliqunyy 0:be95bfb06686 852 * @param context
wuliqunyy 0:be95bfb06686 853 * @param parameter
wuliqunyy 0:be95bfb06686 854 * @param value result
wuliqunyy 0:be95bfb06686 855 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 856 */
wuliqunyy 0:be95bfb06686 857 scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value) {
wuliqunyy 0:be95bfb06686 858 return ParamSignToUInt64(context, parameter, (uint64_t *) value, TRUE);
wuliqunyy 0:be95bfb06686 859 }
wuliqunyy 0:be95bfb06686 860
wuliqunyy 0:be95bfb06686 861 /**
wuliqunyy 0:be95bfb06686 862 * Convert parameter to unsigned 32 bit integer
wuliqunyy 0:be95bfb06686 863 * @param context
wuliqunyy 0:be95bfb06686 864 * @param parameter
wuliqunyy 0:be95bfb06686 865 * @param value result
wuliqunyy 0:be95bfb06686 866 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 867 */
wuliqunyy 0:be95bfb06686 868 scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value) {
wuliqunyy 0:be95bfb06686 869 return ParamSignToUInt64(context, parameter, value, FALSE);
wuliqunyy 0:be95bfb06686 870 }
wuliqunyy 0:be95bfb06686 871
wuliqunyy 0:be95bfb06686 872 /**
wuliqunyy 0:be95bfb06686 873 * Convert parameter to float (32 bit)
wuliqunyy 0:be95bfb06686 874 * @param context
wuliqunyy 0:be95bfb06686 875 * @param parameter
wuliqunyy 0:be95bfb06686 876 * @param value result
wuliqunyy 0:be95bfb06686 877 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 878 */
wuliqunyy 0:be95bfb06686 879 scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value) {
wuliqunyy 0:be95bfb06686 880 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 881 uint32_t valint;
wuliqunyy 0:be95bfb06686 882
wuliqunyy 0:be95bfb06686 883 if (!value) {
wuliqunyy 0:be95bfb06686 884 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 885 return FALSE;
wuliqunyy 0:be95bfb06686 886 }
wuliqunyy 0:be95bfb06686 887
wuliqunyy 0:be95bfb06686 888 switch (parameter->type) {
wuliqunyy 0:be95bfb06686 889 case SCPI_TOKEN_HEXNUM:
wuliqunyy 0:be95bfb06686 890 case SCPI_TOKEN_OCTNUM:
wuliqunyy 0:be95bfb06686 891 case SCPI_TOKEN_BINNUM:
wuliqunyy 0:be95bfb06686 892 result = SCPI_ParamToUInt32(context, parameter, &valint);
wuliqunyy 0:be95bfb06686 893 *value = valint;
wuliqunyy 0:be95bfb06686 894 break;
wuliqunyy 0:be95bfb06686 895 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 896 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX:
wuliqunyy 0:be95bfb06686 897 result = strToFloat(parameter->ptr, value) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 898 break;
wuliqunyy 0:be95bfb06686 899 default:
wuliqunyy 0:be95bfb06686 900 result = FALSE;
wuliqunyy 0:be95bfb06686 901 }
wuliqunyy 0:be95bfb06686 902 return result;
wuliqunyy 0:be95bfb06686 903 }
wuliqunyy 0:be95bfb06686 904
wuliqunyy 0:be95bfb06686 905 /**
wuliqunyy 0:be95bfb06686 906 * Convert parameter to double (64 bit)
wuliqunyy 0:be95bfb06686 907 * @param context
wuliqunyy 0:be95bfb06686 908 * @param parameter
wuliqunyy 0:be95bfb06686 909 * @param value result
wuliqunyy 0:be95bfb06686 910 * @return TRUE if succesful
wuliqunyy 0:be95bfb06686 911 */
wuliqunyy 0:be95bfb06686 912 scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value) {
wuliqunyy 0:be95bfb06686 913 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 914 uint64_t valint;
wuliqunyy 0:be95bfb06686 915
wuliqunyy 0:be95bfb06686 916 if (!value) {
wuliqunyy 0:be95bfb06686 917 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 918 return FALSE;
wuliqunyy 0:be95bfb06686 919 }
wuliqunyy 0:be95bfb06686 920
wuliqunyy 0:be95bfb06686 921 switch (parameter->type) {
wuliqunyy 0:be95bfb06686 922 case SCPI_TOKEN_HEXNUM:
wuliqunyy 0:be95bfb06686 923 case SCPI_TOKEN_OCTNUM:
wuliqunyy 0:be95bfb06686 924 case SCPI_TOKEN_BINNUM:
wuliqunyy 0:be95bfb06686 925 result = SCPI_ParamToUInt64(context, parameter, &valint);
wuliqunyy 0:be95bfb06686 926 *value = valint;
wuliqunyy 0:be95bfb06686 927 break;
wuliqunyy 0:be95bfb06686 928 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 929 case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX:
wuliqunyy 0:be95bfb06686 930 result = strToDouble(parameter->ptr, value) > 0 ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 931 break;
wuliqunyy 0:be95bfb06686 932 default:
wuliqunyy 0:be95bfb06686 933 result = FALSE;
wuliqunyy 0:be95bfb06686 934 }
wuliqunyy 0:be95bfb06686 935 return result;
wuliqunyy 0:be95bfb06686 936 }
wuliqunyy 0:be95bfb06686 937
wuliqunyy 0:be95bfb06686 938 /**
wuliqunyy 0:be95bfb06686 939 * Read floating point float (32 bit) parameter
wuliqunyy 0:be95bfb06686 940 * @param context
wuliqunyy 0:be95bfb06686 941 * @param value
wuliqunyy 0:be95bfb06686 942 * @param mandatory
wuliqunyy 0:be95bfb06686 943 * @return
wuliqunyy 0:be95bfb06686 944 */
wuliqunyy 0:be95bfb06686 945 scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 946 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 947 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 948
wuliqunyy 0:be95bfb06686 949 if (!value) {
wuliqunyy 0:be95bfb06686 950 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 951 return FALSE;
wuliqunyy 0:be95bfb06686 952 }
wuliqunyy 0:be95bfb06686 953
wuliqunyy 0:be95bfb06686 954 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 955 if (result) {
wuliqunyy 0:be95bfb06686 956 if (SCPI_ParamIsNumber(&param, FALSE)) {
wuliqunyy 0:be95bfb06686 957 SCPI_ParamToFloat(context, &param, value);
wuliqunyy 0:be95bfb06686 958 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
wuliqunyy 0:be95bfb06686 959 SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
wuliqunyy 0:be95bfb06686 960 result = FALSE;
wuliqunyy 0:be95bfb06686 961 } else {
wuliqunyy 0:be95bfb06686 962 SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
wuliqunyy 0:be95bfb06686 963 result = FALSE;
wuliqunyy 0:be95bfb06686 964 }
wuliqunyy 0:be95bfb06686 965 }
wuliqunyy 0:be95bfb06686 966 return result;
wuliqunyy 0:be95bfb06686 967 }
wuliqunyy 0:be95bfb06686 968
wuliqunyy 0:be95bfb06686 969 /**
wuliqunyy 0:be95bfb06686 970 * Read floating point double (64 bit) parameter
wuliqunyy 0:be95bfb06686 971 * @param context
wuliqunyy 0:be95bfb06686 972 * @param value
wuliqunyy 0:be95bfb06686 973 * @param mandatory
wuliqunyy 0:be95bfb06686 974 * @return
wuliqunyy 0:be95bfb06686 975 */
wuliqunyy 0:be95bfb06686 976 scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 977 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 978 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 979
wuliqunyy 0:be95bfb06686 980 if (!value) {
wuliqunyy 0:be95bfb06686 981 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 982 return FALSE;
wuliqunyy 0:be95bfb06686 983 }
wuliqunyy 0:be95bfb06686 984
wuliqunyy 0:be95bfb06686 985 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 986 if (result) {
wuliqunyy 0:be95bfb06686 987 if (SCPI_ParamIsNumber(&param, FALSE)) {
wuliqunyy 0:be95bfb06686 988 SCPI_ParamToDouble(context, &param, value);
wuliqunyy 0:be95bfb06686 989 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
wuliqunyy 0:be95bfb06686 990 SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
wuliqunyy 0:be95bfb06686 991 result = FALSE;
wuliqunyy 0:be95bfb06686 992 } else {
wuliqunyy 0:be95bfb06686 993 SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
wuliqunyy 0:be95bfb06686 994 result = FALSE;
wuliqunyy 0:be95bfb06686 995 }
wuliqunyy 0:be95bfb06686 996 }
wuliqunyy 0:be95bfb06686 997 return result;
wuliqunyy 0:be95bfb06686 998 }
wuliqunyy 0:be95bfb06686 999
wuliqunyy 0:be95bfb06686 1000 /**
wuliqunyy 0:be95bfb06686 1001 * Read signed/unsigned 32 bit integer parameter
wuliqunyy 0:be95bfb06686 1002 * @param context
wuliqunyy 0:be95bfb06686 1003 * @param value
wuliqunyy 0:be95bfb06686 1004 * @param mandatory
wuliqunyy 0:be95bfb06686 1005 * @param sign
wuliqunyy 0:be95bfb06686 1006 * @return
wuliqunyy 0:be95bfb06686 1007 */
wuliqunyy 0:be95bfb06686 1008 static scpi_bool_t ParamSignUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 1009 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 1010 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 1011
wuliqunyy 0:be95bfb06686 1012 if (!value) {
wuliqunyy 0:be95bfb06686 1013 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1014 return FALSE;
wuliqunyy 0:be95bfb06686 1015 }
wuliqunyy 0:be95bfb06686 1016
wuliqunyy 0:be95bfb06686 1017 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 1018 if (result) {
wuliqunyy 0:be95bfb06686 1019 if (SCPI_ParamIsNumber(&param, FALSE)) {
wuliqunyy 0:be95bfb06686 1020 result = ParamSignToUInt32(context, &param, value, sign);
wuliqunyy 0:be95bfb06686 1021 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
wuliqunyy 0:be95bfb06686 1022 SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
wuliqunyy 0:be95bfb06686 1023 result = FALSE;
wuliqunyy 0:be95bfb06686 1024 } else {
wuliqunyy 0:be95bfb06686 1025 SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
wuliqunyy 0:be95bfb06686 1026 result = FALSE;
wuliqunyy 0:be95bfb06686 1027 }
wuliqunyy 0:be95bfb06686 1028 }
wuliqunyy 0:be95bfb06686 1029 return result;
wuliqunyy 0:be95bfb06686 1030 }
wuliqunyy 0:be95bfb06686 1031
wuliqunyy 0:be95bfb06686 1032 /**
wuliqunyy 0:be95bfb06686 1033 * Read signed/unsigned 64 bit integer parameter
wuliqunyy 0:be95bfb06686 1034 * @param context
wuliqunyy 0:be95bfb06686 1035 * @param value
wuliqunyy 0:be95bfb06686 1036 * @param mandatory
wuliqunyy 0:be95bfb06686 1037 * @param sign
wuliqunyy 0:be95bfb06686 1038 * @return
wuliqunyy 0:be95bfb06686 1039 */
wuliqunyy 0:be95bfb06686 1040 static scpi_bool_t ParamSignUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 1041 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 1042 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 1043
wuliqunyy 0:be95bfb06686 1044 if (!value) {
wuliqunyy 0:be95bfb06686 1045 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1046 return FALSE;
wuliqunyy 0:be95bfb06686 1047 }
wuliqunyy 0:be95bfb06686 1048
wuliqunyy 0:be95bfb06686 1049 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 1050 if (result) {
wuliqunyy 0:be95bfb06686 1051 if (SCPI_ParamIsNumber(&param, FALSE)) {
wuliqunyy 0:be95bfb06686 1052 result = ParamSignToUInt64(context, &param, value, sign);
wuliqunyy 0:be95bfb06686 1053 } else if (SCPI_ParamIsNumber(&param, TRUE)) {
wuliqunyy 0:be95bfb06686 1054 SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
wuliqunyy 0:be95bfb06686 1055 result = FALSE;
wuliqunyy 0:be95bfb06686 1056 } else {
wuliqunyy 0:be95bfb06686 1057 SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
wuliqunyy 0:be95bfb06686 1058 result = FALSE;
wuliqunyy 0:be95bfb06686 1059 }
wuliqunyy 0:be95bfb06686 1060 }
wuliqunyy 0:be95bfb06686 1061 return result;
wuliqunyy 0:be95bfb06686 1062 }
wuliqunyy 0:be95bfb06686 1063
wuliqunyy 0:be95bfb06686 1064 /**
wuliqunyy 0:be95bfb06686 1065 * Read signed 32 bit integer parameter
wuliqunyy 0:be95bfb06686 1066 * @param context
wuliqunyy 0:be95bfb06686 1067 * @param value
wuliqunyy 0:be95bfb06686 1068 * @param mandatory
wuliqunyy 0:be95bfb06686 1069 * @return
wuliqunyy 0:be95bfb06686 1070 */
wuliqunyy 0:be95bfb06686 1071 scpi_bool_t SCPI_ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1072 return ParamSignUInt32(context, (uint32_t *) value, mandatory, TRUE);
wuliqunyy 0:be95bfb06686 1073 }
wuliqunyy 0:be95bfb06686 1074
wuliqunyy 0:be95bfb06686 1075 /**
wuliqunyy 0:be95bfb06686 1076 * Read unsigned 32 bit integer parameter
wuliqunyy 0:be95bfb06686 1077 * @param context
wuliqunyy 0:be95bfb06686 1078 * @param value
wuliqunyy 0:be95bfb06686 1079 * @param mandatory
wuliqunyy 0:be95bfb06686 1080 * @return
wuliqunyy 0:be95bfb06686 1081 */
wuliqunyy 0:be95bfb06686 1082 scpi_bool_t SCPI_ParamUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1083 return ParamSignUInt32(context, value, mandatory, FALSE);
wuliqunyy 0:be95bfb06686 1084 }
wuliqunyy 0:be95bfb06686 1085
wuliqunyy 0:be95bfb06686 1086 /**
wuliqunyy 0:be95bfb06686 1087 * Read signed 64 bit integer parameter
wuliqunyy 0:be95bfb06686 1088 * @param context
wuliqunyy 0:be95bfb06686 1089 * @param value
wuliqunyy 0:be95bfb06686 1090 * @param mandatory
wuliqunyy 0:be95bfb06686 1091 * @return
wuliqunyy 0:be95bfb06686 1092 */
wuliqunyy 0:be95bfb06686 1093 scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1094 return ParamSignUInt64(context, (uint64_t *) value, mandatory, TRUE);
wuliqunyy 0:be95bfb06686 1095 }
wuliqunyy 0:be95bfb06686 1096
wuliqunyy 0:be95bfb06686 1097 /**
wuliqunyy 0:be95bfb06686 1098 * Read unsigned 64 bit integer parameter
wuliqunyy 0:be95bfb06686 1099 * @param context
wuliqunyy 0:be95bfb06686 1100 * @param value
wuliqunyy 0:be95bfb06686 1101 * @param mandatory
wuliqunyy 0:be95bfb06686 1102 * @return
wuliqunyy 0:be95bfb06686 1103 */
wuliqunyy 0:be95bfb06686 1104 scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1105 return ParamSignUInt64(context, value, mandatory, FALSE);
wuliqunyy 0:be95bfb06686 1106 }
wuliqunyy 0:be95bfb06686 1107
wuliqunyy 0:be95bfb06686 1108 /**
wuliqunyy 0:be95bfb06686 1109 * Read character parameter
wuliqunyy 0:be95bfb06686 1110 * @param context
wuliqunyy 0:be95bfb06686 1111 * @param value
wuliqunyy 0:be95bfb06686 1112 * @param len
wuliqunyy 0:be95bfb06686 1113 * @param mandatory
wuliqunyy 0:be95bfb06686 1114 * @return
wuliqunyy 0:be95bfb06686 1115 */
wuliqunyy 0:be95bfb06686 1116 scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1117 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 1118 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 1119
wuliqunyy 0:be95bfb06686 1120 if (!value || !len) {
wuliqunyy 0:be95bfb06686 1121 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1122 return FALSE;
wuliqunyy 0:be95bfb06686 1123 }
wuliqunyy 0:be95bfb06686 1124
wuliqunyy 0:be95bfb06686 1125 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 1126 if (result) {
wuliqunyy 0:be95bfb06686 1127 switch (param.type) {
wuliqunyy 0:be95bfb06686 1128 case SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 1129 case SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 1130 *value = param.ptr + 1;
wuliqunyy 0:be95bfb06686 1131 *len = param.len - 2;
wuliqunyy 0:be95bfb06686 1132 break;
wuliqunyy 0:be95bfb06686 1133 default:
wuliqunyy 0:be95bfb06686 1134 *value = param.ptr;
wuliqunyy 0:be95bfb06686 1135 *len = param.len;
wuliqunyy 0:be95bfb06686 1136 break;
wuliqunyy 0:be95bfb06686 1137 }
wuliqunyy 0:be95bfb06686 1138
wuliqunyy 0:be95bfb06686 1139 /* TODO: return also parameter type (ProgramMnemonic, ArbitraryBlockProgramData, SingleQuoteProgramData, DoubleQuoteProgramData */
wuliqunyy 0:be95bfb06686 1140 }
wuliqunyy 0:be95bfb06686 1141
wuliqunyy 0:be95bfb06686 1142 return result;
wuliqunyy 0:be95bfb06686 1143 }
wuliqunyy 0:be95bfb06686 1144
wuliqunyy 0:be95bfb06686 1145 /**
wuliqunyy 0:be95bfb06686 1146 * Get arbitrary block program data and returns pointer to data
wuliqunyy 0:be95bfb06686 1147 * @param context
wuliqunyy 0:be95bfb06686 1148 * @param value result pointer to data
wuliqunyy 0:be95bfb06686 1149 * @param len result length of data
wuliqunyy 0:be95bfb06686 1150 * @param mandatory
wuliqunyy 0:be95bfb06686 1151 * @return
wuliqunyy 0:be95bfb06686 1152 */
wuliqunyy 0:be95bfb06686 1153 scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1154 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 1155 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 1156
wuliqunyy 0:be95bfb06686 1157 if (!value || !len) {
wuliqunyy 0:be95bfb06686 1158 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1159 return FALSE;
wuliqunyy 0:be95bfb06686 1160 }
wuliqunyy 0:be95bfb06686 1161
wuliqunyy 0:be95bfb06686 1162 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 1163 if (result) {
wuliqunyy 0:be95bfb06686 1164 if (param.type == SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA) {
wuliqunyy 0:be95bfb06686 1165 *value = param.ptr;
wuliqunyy 0:be95bfb06686 1166 *len = param.len;
wuliqunyy 0:be95bfb06686 1167 } else {
wuliqunyy 0:be95bfb06686 1168 SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
wuliqunyy 0:be95bfb06686 1169 result = FALSE;
wuliqunyy 0:be95bfb06686 1170 }
wuliqunyy 0:be95bfb06686 1171 }
wuliqunyy 0:be95bfb06686 1172
wuliqunyy 0:be95bfb06686 1173 return result;
wuliqunyy 0:be95bfb06686 1174 }
wuliqunyy 0:be95bfb06686 1175
wuliqunyy 0:be95bfb06686 1176 scpi_bool_t SCPI_ParamCopyText(scpi_t * context, char * buffer, size_t buffer_len, size_t * copy_len, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1177 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 1178 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 1179 size_t i_from;
wuliqunyy 0:be95bfb06686 1180 size_t i_to;
wuliqunyy 0:be95bfb06686 1181 char quote;
wuliqunyy 0:be95bfb06686 1182
wuliqunyy 0:be95bfb06686 1183 if (!buffer || !copy_len) {
wuliqunyy 0:be95bfb06686 1184 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1185 return FALSE;
wuliqunyy 0:be95bfb06686 1186 }
wuliqunyy 0:be95bfb06686 1187
wuliqunyy 0:be95bfb06686 1188 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 1189 if (result) {
wuliqunyy 0:be95bfb06686 1190
wuliqunyy 0:be95bfb06686 1191 switch (param.type) {
wuliqunyy 0:be95bfb06686 1192 case SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 1193 case SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA:
wuliqunyy 0:be95bfb06686 1194 quote = param.type == SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA ? '\'' : '"';
wuliqunyy 0:be95bfb06686 1195 for (i_from = 1, i_to = 0; i_from < (size_t) (param.len - 1); i_from++) {
wuliqunyy 0:be95bfb06686 1196 if (i_from >= buffer_len) {
wuliqunyy 0:be95bfb06686 1197 break;
wuliqunyy 0:be95bfb06686 1198 }
wuliqunyy 0:be95bfb06686 1199 buffer[i_to] = param.ptr[i_from];
wuliqunyy 0:be95bfb06686 1200 i_to++;
wuliqunyy 0:be95bfb06686 1201 if (param.ptr[i_from] == quote) {
wuliqunyy 0:be95bfb06686 1202 i_from++;
wuliqunyy 0:be95bfb06686 1203 }
wuliqunyy 0:be95bfb06686 1204 }
wuliqunyy 0:be95bfb06686 1205 *copy_len = i_to;
wuliqunyy 0:be95bfb06686 1206 if (i_to < buffer_len) {
wuliqunyy 0:be95bfb06686 1207 buffer[i_to] = 0;
wuliqunyy 0:be95bfb06686 1208 }
wuliqunyy 0:be95bfb06686 1209 break;
wuliqunyy 0:be95bfb06686 1210 default:
wuliqunyy 0:be95bfb06686 1211 SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
wuliqunyy 0:be95bfb06686 1212 result = FALSE;
wuliqunyy 0:be95bfb06686 1213 }
wuliqunyy 0:be95bfb06686 1214 }
wuliqunyy 0:be95bfb06686 1215
wuliqunyy 0:be95bfb06686 1216 return result;
wuliqunyy 0:be95bfb06686 1217 }
wuliqunyy 0:be95bfb06686 1218
wuliqunyy 0:be95bfb06686 1219 /**
wuliqunyy 0:be95bfb06686 1220 * Convert parameter to choice
wuliqunyy 0:be95bfb06686 1221 * @param context
wuliqunyy 0:be95bfb06686 1222 * @param parameter - should be PROGRAM_MNEMONIC
wuliqunyy 0:be95bfb06686 1223 * @param options - NULL terminated list of choices
wuliqunyy 0:be95bfb06686 1224 * @param value - index to options
wuliqunyy 0:be95bfb06686 1225 * @return
wuliqunyy 0:be95bfb06686 1226 */
wuliqunyy 0:be95bfb06686 1227 scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value) {
wuliqunyy 0:be95bfb06686 1228 size_t res;
wuliqunyy 0:be95bfb06686 1229 scpi_bool_t result = FALSE;
wuliqunyy 0:be95bfb06686 1230
wuliqunyy 0:be95bfb06686 1231 if (!options || !value) {
wuliqunyy 0:be95bfb06686 1232 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1233 return FALSE;
wuliqunyy 0:be95bfb06686 1234 }
wuliqunyy 0:be95bfb06686 1235
wuliqunyy 0:be95bfb06686 1236 if (parameter->type == SCPI_TOKEN_PROGRAM_MNEMONIC) {
wuliqunyy 0:be95bfb06686 1237 for (res = 0; options[res].name; ++res) {
wuliqunyy 0:be95bfb06686 1238 if (matchPattern(options[res].name, strlen(options[res].name), parameter->ptr, parameter->len, NULL)) {
wuliqunyy 0:be95bfb06686 1239 *value = options[res].tag;
wuliqunyy 0:be95bfb06686 1240 result = TRUE;
wuliqunyy 0:be95bfb06686 1241 break;
wuliqunyy 0:be95bfb06686 1242 }
wuliqunyy 0:be95bfb06686 1243 }
wuliqunyy 0:be95bfb06686 1244
wuliqunyy 0:be95bfb06686 1245 if (!result) {
wuliqunyy 0:be95bfb06686 1246 SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE);
wuliqunyy 0:be95bfb06686 1247 }
wuliqunyy 0:be95bfb06686 1248 } else {
wuliqunyy 0:be95bfb06686 1249 SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
wuliqunyy 0:be95bfb06686 1250 }
wuliqunyy 0:be95bfb06686 1251
wuliqunyy 0:be95bfb06686 1252 return result;
wuliqunyy 0:be95bfb06686 1253 }
wuliqunyy 0:be95bfb06686 1254
wuliqunyy 0:be95bfb06686 1255 /**
wuliqunyy 0:be95bfb06686 1256 * Find tag in choices and returns its first textual representation
wuliqunyy 0:be95bfb06686 1257 * @param options specifications of choices numbers (patterns)
wuliqunyy 0:be95bfb06686 1258 * @param tag numerical representatio of choice
wuliqunyy 0:be95bfb06686 1259 * @param text result text
wuliqunyy 0:be95bfb06686 1260 * @return TRUE if succesfule, else FALSE
wuliqunyy 0:be95bfb06686 1261 */
wuliqunyy 0:be95bfb06686 1262 scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text) {
wuliqunyy 0:be95bfb06686 1263 int i;
wuliqunyy 0:be95bfb06686 1264
wuliqunyy 0:be95bfb06686 1265 for (i = 0; options[i].name != NULL; i++) {
wuliqunyy 0:be95bfb06686 1266 if (options[i].tag == tag) {
wuliqunyy 0:be95bfb06686 1267 *text = options[i].name;
wuliqunyy 0:be95bfb06686 1268 return TRUE;
wuliqunyy 0:be95bfb06686 1269 }
wuliqunyy 0:be95bfb06686 1270 }
wuliqunyy 0:be95bfb06686 1271
wuliqunyy 0:be95bfb06686 1272 return FALSE;
wuliqunyy 0:be95bfb06686 1273 }
wuliqunyy 0:be95bfb06686 1274
wuliqunyy 0:be95bfb06686 1275 /*
wuliqunyy 0:be95bfb06686 1276 * Definition of BOOL choice list
wuliqunyy 0:be95bfb06686 1277 */
wuliqunyy 0:be95bfb06686 1278 const scpi_choice_def_t scpi_bool_def[] = {
wuliqunyy 0:be95bfb06686 1279 {"OFF", 0},
wuliqunyy 0:be95bfb06686 1280 {"ON", 1},
wuliqunyy 0:be95bfb06686 1281 SCPI_CHOICE_LIST_END /* termination of option list */
wuliqunyy 0:be95bfb06686 1282 };
wuliqunyy 0:be95bfb06686 1283
wuliqunyy 0:be95bfb06686 1284 /**
wuliqunyy 0:be95bfb06686 1285 * Read BOOL parameter (0,1,ON,OFF)
wuliqunyy 0:be95bfb06686 1286 * @param context
wuliqunyy 0:be95bfb06686 1287 * @param value
wuliqunyy 0:be95bfb06686 1288 * @param mandatory
wuliqunyy 0:be95bfb06686 1289 * @return
wuliqunyy 0:be95bfb06686 1290 */
wuliqunyy 0:be95bfb06686 1291 scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1292 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 1293 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 1294 int32_t intval;
wuliqunyy 0:be95bfb06686 1295
wuliqunyy 0:be95bfb06686 1296 if (!value) {
wuliqunyy 0:be95bfb06686 1297 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1298 return FALSE;
wuliqunyy 0:be95bfb06686 1299 }
wuliqunyy 0:be95bfb06686 1300
wuliqunyy 0:be95bfb06686 1301 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 1302
wuliqunyy 0:be95bfb06686 1303 if (result) {
wuliqunyy 0:be95bfb06686 1304 if (param.type == SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA) {
wuliqunyy 0:be95bfb06686 1305 SCPI_ParamToInt32(context, &param, &intval);
wuliqunyy 0:be95bfb06686 1306 *value = intval ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 1307 } else {
wuliqunyy 0:be95bfb06686 1308 result = SCPI_ParamToChoice(context, &param, scpi_bool_def, &intval);
wuliqunyy 0:be95bfb06686 1309 if (result) {
wuliqunyy 0:be95bfb06686 1310 *value = intval ? TRUE : FALSE;
wuliqunyy 0:be95bfb06686 1311 }
wuliqunyy 0:be95bfb06686 1312 }
wuliqunyy 0:be95bfb06686 1313 }
wuliqunyy 0:be95bfb06686 1314
wuliqunyy 0:be95bfb06686 1315 return result;
wuliqunyy 0:be95bfb06686 1316 }
wuliqunyy 0:be95bfb06686 1317
wuliqunyy 0:be95bfb06686 1318 /**
wuliqunyy 0:be95bfb06686 1319 * Read value from list of options
wuliqunyy 0:be95bfb06686 1320 * @param context
wuliqunyy 0:be95bfb06686 1321 * @param options
wuliqunyy 0:be95bfb06686 1322 * @param value
wuliqunyy 0:be95bfb06686 1323 * @param mandatory
wuliqunyy 0:be95bfb06686 1324 * @return
wuliqunyy 0:be95bfb06686 1325 */
wuliqunyy 0:be95bfb06686 1326 scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory) {
wuliqunyy 0:be95bfb06686 1327 scpi_bool_t result;
wuliqunyy 0:be95bfb06686 1328 scpi_parameter_t param;
wuliqunyy 0:be95bfb06686 1329
wuliqunyy 0:be95bfb06686 1330 if (!options || !value) {
wuliqunyy 0:be95bfb06686 1331 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1332 return FALSE;
wuliqunyy 0:be95bfb06686 1333 }
wuliqunyy 0:be95bfb06686 1334
wuliqunyy 0:be95bfb06686 1335 result = SCPI_Parameter(context, &param, mandatory);
wuliqunyy 0:be95bfb06686 1336 if (result) {
wuliqunyy 0:be95bfb06686 1337 result = SCPI_ParamToChoice(context, &param, options, value);
wuliqunyy 0:be95bfb06686 1338 }
wuliqunyy 0:be95bfb06686 1339
wuliqunyy 0:be95bfb06686 1340 return result;
wuliqunyy 0:be95bfb06686 1341 }
wuliqunyy 0:be95bfb06686 1342
wuliqunyy 0:be95bfb06686 1343 /**
wuliqunyy 0:be95bfb06686 1344 * Parse one parameter and detect type
wuliqunyy 0:be95bfb06686 1345 * @param state
wuliqunyy 0:be95bfb06686 1346 * @param token
wuliqunyy 0:be95bfb06686 1347 * @return
wuliqunyy 0:be95bfb06686 1348 */
wuliqunyy 0:be95bfb06686 1349 int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) {
wuliqunyy 0:be95bfb06686 1350 scpi_token_t tmp;
wuliqunyy 0:be95bfb06686 1351 int result = 0;
wuliqunyy 0:be95bfb06686 1352 int wsLen;
wuliqunyy 0:be95bfb06686 1353 int suffixLen;
wuliqunyy 0:be95bfb06686 1354 int realLen = 0;
wuliqunyy 0:be95bfb06686 1355 realLen += scpiLex_WhiteSpace(state, &tmp);
wuliqunyy 0:be95bfb06686 1356
wuliqunyy 0:be95bfb06686 1357 if (result == 0) result = scpiLex_NondecimalNumericData(state, token);
wuliqunyy 0:be95bfb06686 1358 if (result == 0) result = scpiLex_CharacterProgramData(state, token);
wuliqunyy 0:be95bfb06686 1359 if (result == 0) {
wuliqunyy 0:be95bfb06686 1360 result = scpiLex_DecimalNumericProgramData(state, token);
wuliqunyy 0:be95bfb06686 1361 if (result != 0) {
wuliqunyy 0:be95bfb06686 1362 wsLen = scpiLex_WhiteSpace(state, &tmp);
wuliqunyy 0:be95bfb06686 1363 suffixLen = scpiLex_SuffixProgramData(state, &tmp);
wuliqunyy 0:be95bfb06686 1364 if (suffixLen > 0) {
wuliqunyy 0:be95bfb06686 1365 token->len += wsLen + suffixLen;
wuliqunyy 0:be95bfb06686 1366 token->type = SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX;
wuliqunyy 0:be95bfb06686 1367 result = token->len;
wuliqunyy 0:be95bfb06686 1368 }
wuliqunyy 0:be95bfb06686 1369 }
wuliqunyy 0:be95bfb06686 1370 }
wuliqunyy 0:be95bfb06686 1371
wuliqunyy 0:be95bfb06686 1372 if (result == 0) result = scpiLex_StringProgramData(state, token);
wuliqunyy 0:be95bfb06686 1373 if (result == 0) result = scpiLex_ArbitraryBlockProgramData(state, token);
wuliqunyy 0:be95bfb06686 1374 if (result == 0) result = scpiLex_ProgramExpression(state, token);
wuliqunyy 0:be95bfb06686 1375
wuliqunyy 0:be95bfb06686 1376 realLen += scpiLex_WhiteSpace(state, &tmp);
wuliqunyy 0:be95bfb06686 1377
wuliqunyy 0:be95bfb06686 1378 return result + realLen;
wuliqunyy 0:be95bfb06686 1379 }
wuliqunyy 0:be95bfb06686 1380
wuliqunyy 0:be95bfb06686 1381 /**
wuliqunyy 0:be95bfb06686 1382 * Skip all parameters to correctly detect end of command line.
wuliqunyy 0:be95bfb06686 1383 * @param state
wuliqunyy 0:be95bfb06686 1384 * @param token
wuliqunyy 0:be95bfb06686 1385 * @param numberOfParameters
wuliqunyy 0:be95bfb06686 1386 * @return
wuliqunyy 0:be95bfb06686 1387 */
wuliqunyy 0:be95bfb06686 1388 int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) {
wuliqunyy 0:be95bfb06686 1389
wuliqunyy 0:be95bfb06686 1390 int result;
wuliqunyy 0:be95bfb06686 1391 scpi_token_t tmp;
wuliqunyy 0:be95bfb06686 1392 int paramCount = 0;
wuliqunyy 0:be95bfb06686 1393
wuliqunyy 0:be95bfb06686 1394 token->len = -1;
wuliqunyy 0:be95bfb06686 1395 token->type = SCPI_TOKEN_ALL_PROGRAM_DATA;
wuliqunyy 0:be95bfb06686 1396 token->ptr = state->pos;
wuliqunyy 0:be95bfb06686 1397
wuliqunyy 0:be95bfb06686 1398
wuliqunyy 0:be95bfb06686 1399 for (result = 1; result != 0; result = scpiLex_Comma(state, &tmp)) {
wuliqunyy 0:be95bfb06686 1400 token->len += result;
wuliqunyy 0:be95bfb06686 1401
wuliqunyy 0:be95bfb06686 1402 result = scpiParser_parseProgramData(state, &tmp);
wuliqunyy 0:be95bfb06686 1403 if (tmp.type != SCPI_TOKEN_UNKNOWN) {
wuliqunyy 0:be95bfb06686 1404 token->len += result;
wuliqunyy 0:be95bfb06686 1405 } else {
wuliqunyy 0:be95bfb06686 1406 token->type = SCPI_TOKEN_UNKNOWN;
wuliqunyy 0:be95bfb06686 1407 token->len = 0;
wuliqunyy 0:be95bfb06686 1408 paramCount = -1;
wuliqunyy 0:be95bfb06686 1409 break;
wuliqunyy 0:be95bfb06686 1410 }
wuliqunyy 0:be95bfb06686 1411 paramCount++;
wuliqunyy 0:be95bfb06686 1412 }
wuliqunyy 0:be95bfb06686 1413
wuliqunyy 0:be95bfb06686 1414 if (numberOfParameters != NULL) {
wuliqunyy 0:be95bfb06686 1415 *numberOfParameters = paramCount;
wuliqunyy 0:be95bfb06686 1416 }
wuliqunyy 0:be95bfb06686 1417 return token->len;
wuliqunyy 0:be95bfb06686 1418 }
wuliqunyy 0:be95bfb06686 1419
wuliqunyy 0:be95bfb06686 1420 /**
wuliqunyy 0:be95bfb06686 1421 * Skip complete command line - program header and parameters
wuliqunyy 0:be95bfb06686 1422 * @param state
wuliqunyy 0:be95bfb06686 1423 * @param buffer
wuliqunyy 0:be95bfb06686 1424 * @param len
wuliqunyy 0:be95bfb06686 1425 * @return
wuliqunyy 0:be95bfb06686 1426 */
wuliqunyy 0:be95bfb06686 1427 int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, char * buffer, int len) {
wuliqunyy 0:be95bfb06686 1428 lex_state_t lex_state;
wuliqunyy 0:be95bfb06686 1429 scpi_token_t tmp;
wuliqunyy 0:be95bfb06686 1430 int result = 0;
wuliqunyy 0:be95bfb06686 1431
wuliqunyy 0:be95bfb06686 1432 lex_state.buffer = lex_state.pos = buffer;
wuliqunyy 0:be95bfb06686 1433 lex_state.len = len;
wuliqunyy 0:be95bfb06686 1434 state->numberOfParameters = 0;
wuliqunyy 0:be95bfb06686 1435
wuliqunyy 0:be95bfb06686 1436 /* ignore whitespace at the begginig */
wuliqunyy 0:be95bfb06686 1437 scpiLex_WhiteSpace(&lex_state, &tmp);
wuliqunyy 0:be95bfb06686 1438
wuliqunyy 0:be95bfb06686 1439 if (scpiLex_ProgramHeader(&lex_state, &state->programHeader) >= 0) {
wuliqunyy 0:be95bfb06686 1440 if (scpiLex_WhiteSpace(&lex_state, &tmp) > 0) {
wuliqunyy 0:be95bfb06686 1441 scpiParser_parseAllProgramData(&lex_state, &state->programData, &state->numberOfParameters);
wuliqunyy 0:be95bfb06686 1442 } else {
wuliqunyy 0:be95bfb06686 1443 invalidateToken(&state->programData, lex_state.pos);
wuliqunyy 0:be95bfb06686 1444 }
wuliqunyy 0:be95bfb06686 1445 } else {
wuliqunyy 0:be95bfb06686 1446 invalidateToken(&state->programHeader, lex_state.buffer);
wuliqunyy 0:be95bfb06686 1447 invalidateToken(&state->programData, lex_state.buffer);
wuliqunyy 0:be95bfb06686 1448 }
wuliqunyy 0:be95bfb06686 1449
wuliqunyy 0:be95bfb06686 1450 if (result == 0) result = scpiLex_NewLine(&lex_state, &tmp);
wuliqunyy 0:be95bfb06686 1451 if (result == 0) result = scpiLex_Semicolon(&lex_state, &tmp);
wuliqunyy 0:be95bfb06686 1452
wuliqunyy 0:be95bfb06686 1453 if (!scpiLex_IsEos(&lex_state) && (result == 0)) {
wuliqunyy 0:be95bfb06686 1454 lex_state.pos++;
wuliqunyy 0:be95bfb06686 1455
wuliqunyy 0:be95bfb06686 1456 state->programHeader.len = 1;
wuliqunyy 0:be95bfb06686 1457 state->programHeader.type = SCPI_TOKEN_INVALID;
wuliqunyy 0:be95bfb06686 1458
wuliqunyy 0:be95bfb06686 1459 invalidateToken(&state->programData, lex_state.buffer);
wuliqunyy 0:be95bfb06686 1460 }
wuliqunyy 0:be95bfb06686 1461
wuliqunyy 0:be95bfb06686 1462 if (SCPI_TOKEN_SEMICOLON == tmp.type) {
wuliqunyy 0:be95bfb06686 1463 state->termination = SCPI_MESSAGE_TERMINATION_SEMICOLON;
wuliqunyy 0:be95bfb06686 1464 } else if (SCPI_TOKEN_NL == tmp.type) {
wuliqunyy 0:be95bfb06686 1465 state->termination = SCPI_MESSAGE_TERMINATION_NL;
wuliqunyy 0:be95bfb06686 1466 } else {
wuliqunyy 0:be95bfb06686 1467 state->termination = SCPI_MESSAGE_TERMINATION_NONE;
wuliqunyy 0:be95bfb06686 1468 }
wuliqunyy 0:be95bfb06686 1469
wuliqunyy 0:be95bfb06686 1470 return lex_state.pos - lex_state.buffer;
wuliqunyy 0:be95bfb06686 1471 }
wuliqunyy 0:be95bfb06686 1472
wuliqunyy 0:be95bfb06686 1473 /**
wuliqunyy 0:be95bfb06686 1474 * Check current command
wuliqunyy 0:be95bfb06686 1475 * - suitable for one handle to multiple commands
wuliqunyy 0:be95bfb06686 1476 * @param context
wuliqunyy 0:be95bfb06686 1477 * @param cmd
wuliqunyy 0:be95bfb06686 1478 * @return
wuliqunyy 0:be95bfb06686 1479 */
wuliqunyy 0:be95bfb06686 1480 scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd) {
wuliqunyy 0:be95bfb06686 1481 const char * pattern;
wuliqunyy 0:be95bfb06686 1482
wuliqunyy 0:be95bfb06686 1483 if (!context->param_list.cmd) {
wuliqunyy 0:be95bfb06686 1484 return FALSE;
wuliqunyy 0:be95bfb06686 1485 }
wuliqunyy 0:be95bfb06686 1486
wuliqunyy 0:be95bfb06686 1487 pattern = context->param_list.cmd->pattern;
wuliqunyy 0:be95bfb06686 1488 return matchCommand(pattern, cmd, strlen(cmd), NULL, 0, 0);
wuliqunyy 0:be95bfb06686 1489 }
wuliqunyy 0:be95bfb06686 1490
wuliqunyy 0:be95bfb06686 1491 #if USE_COMMAND_TAGS
wuliqunyy 0:be95bfb06686 1492
wuliqunyy 0:be95bfb06686 1493 /**
wuliqunyy 0:be95bfb06686 1494 * Return the .tag field of the matching scpi_command_t
wuliqunyy 0:be95bfb06686 1495 * @param context
wuliqunyy 0:be95bfb06686 1496 * @return
wuliqunyy 0:be95bfb06686 1497 */
wuliqunyy 0:be95bfb06686 1498 int32_t SCPI_CmdTag(scpi_t * context) {
wuliqunyy 0:be95bfb06686 1499 if (context->param_list.cmd) {
wuliqunyy 0:be95bfb06686 1500 return context->param_list.cmd->tag;
wuliqunyy 0:be95bfb06686 1501 } else {
wuliqunyy 0:be95bfb06686 1502 return 0;
wuliqunyy 0:be95bfb06686 1503 }
wuliqunyy 0:be95bfb06686 1504 }
wuliqunyy 0:be95bfb06686 1505 #endif /* USE_COMMAND_TAGS */
wuliqunyy 0:be95bfb06686 1506
wuliqunyy 0:be95bfb06686 1507 scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len) {
wuliqunyy 0:be95bfb06686 1508 return matchCommand(pattern, value, len, NULL, 0, 0);
wuliqunyy 0:be95bfb06686 1509 }
wuliqunyy 0:be95bfb06686 1510
wuliqunyy 0:be95bfb06686 1511 scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value) {
wuliqunyy 0:be95bfb06686 1512 return matchCommand(context->param_list.cmd->pattern, context->param_list.cmd_raw.data, context->param_list.cmd_raw.length, numbers, len, default_value);
wuliqunyy 0:be95bfb06686 1513 }
wuliqunyy 0:be95bfb06686 1514
wuliqunyy 0:be95bfb06686 1515 /**
wuliqunyy 0:be95bfb06686 1516 * If SCPI_Parameter() returns FALSE, this function can detect, if the parameter
wuliqunyy 0:be95bfb06686 1517 * is just missing (TRUE) or if there was an error during processing of the command (FALSE)
wuliqunyy 0:be95bfb06686 1518 * @param parameter
wuliqunyy 0:be95bfb06686 1519 * @return
wuliqunyy 0:be95bfb06686 1520 */
wuliqunyy 0:be95bfb06686 1521 scpi_bool_t SCPI_ParamIsValid(scpi_parameter_t * parameter) {
wuliqunyy 0:be95bfb06686 1522 return parameter->type == SCPI_TOKEN_UNKNOWN ? FALSE : TRUE;
wuliqunyy 0:be95bfb06686 1523 }
wuliqunyy 0:be95bfb06686 1524
wuliqunyy 0:be95bfb06686 1525 /**
wuliqunyy 0:be95bfb06686 1526 * Returns TRUE if there was an error during parameter handling
wuliqunyy 0:be95bfb06686 1527 * @param context
wuliqunyy 0:be95bfb06686 1528 * @return
wuliqunyy 0:be95bfb06686 1529 */
wuliqunyy 0:be95bfb06686 1530 scpi_bool_t SCPI_ParamErrorOccurred(scpi_t * context) {
wuliqunyy 0:be95bfb06686 1531 return context->cmd_error;
wuliqunyy 0:be95bfb06686 1532 }
wuliqunyy 0:be95bfb06686 1533
wuliqunyy 0:be95bfb06686 1534 /**
wuliqunyy 0:be95bfb06686 1535 * Result binary array and swap bytes if needed (native endiannes != required endiannes)
wuliqunyy 0:be95bfb06686 1536 * @param context
wuliqunyy 0:be95bfb06686 1537 * @param array
wuliqunyy 0:be95bfb06686 1538 * @param count
wuliqunyy 0:be95bfb06686 1539 * @param item_size
wuliqunyy 0:be95bfb06686 1540 * @param format
wuliqunyy 0:be95bfb06686 1541 * @return
wuliqunyy 0:be95bfb06686 1542 */
wuliqunyy 0:be95bfb06686 1543 static size_t produceResultArrayBinary(scpi_t * context, const void * array, size_t count, size_t item_size, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1544
wuliqunyy 0:be95bfb06686 1545 if (SCPI_GetNativeFormat() == format) {
wuliqunyy 0:be95bfb06686 1546 switch (item_size) {
wuliqunyy 0:be95bfb06686 1547 case 1:
wuliqunyy 0:be95bfb06686 1548 case 2:
wuliqunyy 0:be95bfb06686 1549 case 4:
wuliqunyy 0:be95bfb06686 1550 case 8:
wuliqunyy 0:be95bfb06686 1551 return SCPI_ResultArbitraryBlock(context, array, count * item_size);
wuliqunyy 0:be95bfb06686 1552 default:
wuliqunyy 0:be95bfb06686 1553 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1554 return 0;
wuliqunyy 0:be95bfb06686 1555 }
wuliqunyy 0:be95bfb06686 1556 } else {
wuliqunyy 0:be95bfb06686 1557 size_t result = 0;
wuliqunyy 0:be95bfb06686 1558 size_t i;
wuliqunyy 0:be95bfb06686 1559 switch (item_size) {
wuliqunyy 0:be95bfb06686 1560 case 1:
wuliqunyy 0:be95bfb06686 1561 case 2:
wuliqunyy 0:be95bfb06686 1562 case 4:
wuliqunyy 0:be95bfb06686 1563 case 8:
wuliqunyy 0:be95bfb06686 1564 result += SCPI_ResultArbitraryBlockHeader(context, count * item_size);
wuliqunyy 0:be95bfb06686 1565 break;
wuliqunyy 0:be95bfb06686 1566 default:
wuliqunyy 0:be95bfb06686 1567 SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
wuliqunyy 0:be95bfb06686 1568 return 0;
wuliqunyy 0:be95bfb06686 1569 }
wuliqunyy 0:be95bfb06686 1570
wuliqunyy 0:be95bfb06686 1571 switch (item_size) {
wuliqunyy 0:be95bfb06686 1572 case 1:
wuliqunyy 0:be95bfb06686 1573 result += SCPI_ResultArbitraryBlockData(context, array, count);
wuliqunyy 0:be95bfb06686 1574 break;
wuliqunyy 0:be95bfb06686 1575 case 2:
wuliqunyy 0:be95bfb06686 1576 for (i = 0; i < count; i++) {
wuliqunyy 0:be95bfb06686 1577 uint16_t val = SCPI_Swap16(((uint16_t*) array)[i]);
wuliqunyy 0:be95bfb06686 1578 result += SCPI_ResultArbitraryBlockData(context, &val, item_size);
wuliqunyy 0:be95bfb06686 1579 }
wuliqunyy 0:be95bfb06686 1580 break;
wuliqunyy 0:be95bfb06686 1581 case 4:
wuliqunyy 0:be95bfb06686 1582 for (i = 0; i < count; i++) {
wuliqunyy 0:be95bfb06686 1583 uint32_t val = SCPI_Swap32(((uint32_t*) array)[i]);
wuliqunyy 0:be95bfb06686 1584 result += SCPI_ResultArbitraryBlockData(context, &val, item_size);
wuliqunyy 0:be95bfb06686 1585 }
wuliqunyy 0:be95bfb06686 1586 break;
wuliqunyy 0:be95bfb06686 1587 case 8:
wuliqunyy 0:be95bfb06686 1588 for (i = 0; i < count; i++) {
wuliqunyy 0:be95bfb06686 1589 uint64_t val = SCPI_Swap64(((uint64_t*) array)[i]);
wuliqunyy 0:be95bfb06686 1590 result += SCPI_ResultArbitraryBlockData(context, &val, item_size);
wuliqunyy 0:be95bfb06686 1591 }
wuliqunyy 0:be95bfb06686 1592 break;
wuliqunyy 0:be95bfb06686 1593 }
wuliqunyy 0:be95bfb06686 1594
wuliqunyy 0:be95bfb06686 1595 return result;
wuliqunyy 0:be95bfb06686 1596 }
wuliqunyy 0:be95bfb06686 1597 }
wuliqunyy 0:be95bfb06686 1598
wuliqunyy 0:be95bfb06686 1599
wuliqunyy 0:be95bfb06686 1600 #define RESULT_ARRAY(func) do {\
wuliqunyy 0:be95bfb06686 1601 size_t result = 0;\
wuliqunyy 0:be95bfb06686 1602 if (format == SCPI_FORMAT_ASCII) {\
wuliqunyy 0:be95bfb06686 1603 size_t i;\
wuliqunyy 0:be95bfb06686 1604 for (i = 0; i < count; i++) {\
wuliqunyy 0:be95bfb06686 1605 result += func(context, array[i]);\
wuliqunyy 0:be95bfb06686 1606 }\
wuliqunyy 0:be95bfb06686 1607 } else {\
wuliqunyy 0:be95bfb06686 1608 result = produceResultArrayBinary(context, array, count, sizeof(*array), format);\
wuliqunyy 0:be95bfb06686 1609 }\
wuliqunyy 0:be95bfb06686 1610 return result;\
wuliqunyy 0:be95bfb06686 1611 } while(0)
wuliqunyy 0:be95bfb06686 1612
wuliqunyy 0:be95bfb06686 1613 /**
wuliqunyy 0:be95bfb06686 1614 * Result array of signed 8bit integers
wuliqunyy 0:be95bfb06686 1615 * @param context
wuliqunyy 0:be95bfb06686 1616 * @param array
wuliqunyy 0:be95bfb06686 1617 * @param count
wuliqunyy 0:be95bfb06686 1618 * @param format
wuliqunyy 0:be95bfb06686 1619 * @return
wuliqunyy 0:be95bfb06686 1620 */
wuliqunyy 0:be95bfb06686 1621 size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1622 RESULT_ARRAY(SCPI_ResultInt8);
wuliqunyy 0:be95bfb06686 1623 }
wuliqunyy 0:be95bfb06686 1624
wuliqunyy 0:be95bfb06686 1625 /**
wuliqunyy 0:be95bfb06686 1626 * Result array of unsigned 8bit integers
wuliqunyy 0:be95bfb06686 1627 * @param context
wuliqunyy 0:be95bfb06686 1628 * @param array
wuliqunyy 0:be95bfb06686 1629 * @param count
wuliqunyy 0:be95bfb06686 1630 * @param format
wuliqunyy 0:be95bfb06686 1631 * @return
wuliqunyy 0:be95bfb06686 1632 */
wuliqunyy 0:be95bfb06686 1633 size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1634 RESULT_ARRAY(SCPI_ResultUInt8);
wuliqunyy 0:be95bfb06686 1635 }
wuliqunyy 0:be95bfb06686 1636
wuliqunyy 0:be95bfb06686 1637 /**
wuliqunyy 0:be95bfb06686 1638 * Result array of signed 16bit integers
wuliqunyy 0:be95bfb06686 1639 * @param context
wuliqunyy 0:be95bfb06686 1640 * @param array
wuliqunyy 0:be95bfb06686 1641 * @param count
wuliqunyy 0:be95bfb06686 1642 * @param format
wuliqunyy 0:be95bfb06686 1643 * @return
wuliqunyy 0:be95bfb06686 1644 */
wuliqunyy 0:be95bfb06686 1645 size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1646 RESULT_ARRAY(SCPI_ResultInt16);
wuliqunyy 0:be95bfb06686 1647 }
wuliqunyy 0:be95bfb06686 1648
wuliqunyy 0:be95bfb06686 1649 /**
wuliqunyy 0:be95bfb06686 1650 * Result array of unsigned 16bit integers
wuliqunyy 0:be95bfb06686 1651 * @param context
wuliqunyy 0:be95bfb06686 1652 * @param array
wuliqunyy 0:be95bfb06686 1653 * @param count
wuliqunyy 0:be95bfb06686 1654 * @param format
wuliqunyy 0:be95bfb06686 1655 * @return
wuliqunyy 0:be95bfb06686 1656 */
wuliqunyy 0:be95bfb06686 1657 size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1658 RESULT_ARRAY(SCPI_ResultUInt16);
wuliqunyy 0:be95bfb06686 1659 }
wuliqunyy 0:be95bfb06686 1660
wuliqunyy 0:be95bfb06686 1661 /**
wuliqunyy 0:be95bfb06686 1662 * Result array of signed 32bit integers
wuliqunyy 0:be95bfb06686 1663 * @param context
wuliqunyy 0:be95bfb06686 1664 * @param array
wuliqunyy 0:be95bfb06686 1665 * @param count
wuliqunyy 0:be95bfb06686 1666 * @param format
wuliqunyy 0:be95bfb06686 1667 * @return
wuliqunyy 0:be95bfb06686 1668 */
wuliqunyy 0:be95bfb06686 1669 size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1670 RESULT_ARRAY(SCPI_ResultInt32);
wuliqunyy 0:be95bfb06686 1671 }
wuliqunyy 0:be95bfb06686 1672
wuliqunyy 0:be95bfb06686 1673 /**
wuliqunyy 0:be95bfb06686 1674 * Result array of unsigned 32bit integers
wuliqunyy 0:be95bfb06686 1675 * @param context
wuliqunyy 0:be95bfb06686 1676 * @param array
wuliqunyy 0:be95bfb06686 1677 * @param count
wuliqunyy 0:be95bfb06686 1678 * @param format
wuliqunyy 0:be95bfb06686 1679 * @return
wuliqunyy 0:be95bfb06686 1680 */
wuliqunyy 0:be95bfb06686 1681 size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1682 RESULT_ARRAY(SCPI_ResultUInt32);
wuliqunyy 0:be95bfb06686 1683 }
wuliqunyy 0:be95bfb06686 1684
wuliqunyy 0:be95bfb06686 1685 /**
wuliqunyy 0:be95bfb06686 1686 * Result array of signed 64bit integers
wuliqunyy 0:be95bfb06686 1687 * @param context
wuliqunyy 0:be95bfb06686 1688 * @param array
wuliqunyy 0:be95bfb06686 1689 * @param count
wuliqunyy 0:be95bfb06686 1690 * @param format
wuliqunyy 0:be95bfb06686 1691 * @return
wuliqunyy 0:be95bfb06686 1692 */
wuliqunyy 0:be95bfb06686 1693 size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1694 RESULT_ARRAY(SCPI_ResultInt64);
wuliqunyy 0:be95bfb06686 1695 }
wuliqunyy 0:be95bfb06686 1696
wuliqunyy 0:be95bfb06686 1697 /**
wuliqunyy 0:be95bfb06686 1698 * Result array of unsigned 64bit integers
wuliqunyy 0:be95bfb06686 1699 * @param context
wuliqunyy 0:be95bfb06686 1700 * @param array
wuliqunyy 0:be95bfb06686 1701 * @param count
wuliqunyy 0:be95bfb06686 1702 * @param format
wuliqunyy 0:be95bfb06686 1703 * @return
wuliqunyy 0:be95bfb06686 1704 */
wuliqunyy 0:be95bfb06686 1705 size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1706 RESULT_ARRAY(SCPI_ResultUInt64);
wuliqunyy 0:be95bfb06686 1707 }
wuliqunyy 0:be95bfb06686 1708
wuliqunyy 0:be95bfb06686 1709 /**
wuliqunyy 0:be95bfb06686 1710 * Result array of floats
wuliqunyy 0:be95bfb06686 1711 * @param context
wuliqunyy 0:be95bfb06686 1712 * @param array
wuliqunyy 0:be95bfb06686 1713 * @param count
wuliqunyy 0:be95bfb06686 1714 * @param format
wuliqunyy 0:be95bfb06686 1715 * @return
wuliqunyy 0:be95bfb06686 1716 */
wuliqunyy 0:be95bfb06686 1717 size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1718 RESULT_ARRAY(SCPI_ResultFloat);
wuliqunyy 0:be95bfb06686 1719 }
wuliqunyy 0:be95bfb06686 1720
wuliqunyy 0:be95bfb06686 1721 /**
wuliqunyy 0:be95bfb06686 1722 * Result array of doubles
wuliqunyy 0:be95bfb06686 1723 * @param context
wuliqunyy 0:be95bfb06686 1724 * @param array
wuliqunyy 0:be95bfb06686 1725 * @param count
wuliqunyy 0:be95bfb06686 1726 * @param format
wuliqunyy 0:be95bfb06686 1727 * @return
wuliqunyy 0:be95bfb06686 1728 */
wuliqunyy 0:be95bfb06686 1729 size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format) {
wuliqunyy 0:be95bfb06686 1730 RESULT_ARRAY(SCPI_ResultDouble);
wuliqunyy 0:be95bfb06686 1731 }
wuliqunyy 0:be95bfb06686 1732
wuliqunyy 0:be95bfb06686 1733 /*
wuliqunyy 0:be95bfb06686 1734 * Template macro to generate all SCPI_ParamArrayXYZ function
wuliqunyy 0:be95bfb06686 1735 */
wuliqunyy 0:be95bfb06686 1736 #define PARAM_ARRAY_TEMPLATE(func) do{\
wuliqunyy 0:be95bfb06686 1737 if (format != SCPI_FORMAT_ASCII) return FALSE;\
wuliqunyy 0:be95bfb06686 1738 for (*o_count = 0; *o_count < i_count; (*o_count)++) {\
wuliqunyy 0:be95bfb06686 1739 if (!func(context, &data[*o_count], mandatory)) {\
wuliqunyy 0:be95bfb06686 1740 break;\
wuliqunyy 0:be95bfb06686 1741 }\
wuliqunyy 0:be95bfb06686 1742 mandatory = FALSE;\
wuliqunyy 0:be95bfb06686 1743 }\
wuliqunyy 0:be95bfb06686 1744 return mandatory ? FALSE : TRUE;\
wuliqunyy 0:be95bfb06686 1745 }while(0)
wuliqunyy 0:be95bfb06686 1746
wuliqunyy 0:be95bfb06686 1747 /**
wuliqunyy 0:be95bfb06686 1748 * Read list of values up to i_count
wuliqunyy 0:be95bfb06686 1749 * @param context
wuliqunyy 0:be95bfb06686 1750 * @param data - array to fill
wuliqunyy 0:be95bfb06686 1751 * @param i_count - number of elements of data
wuliqunyy 0:be95bfb06686 1752 * @param o_count - real number of filled elements
wuliqunyy 0:be95bfb06686 1753 * @param mandatory
wuliqunyy 0:be95bfb06686 1754 * @return TRUE on success
wuliqunyy 0:be95bfb06686 1755 */
wuliqunyy 0:be95bfb06686 1756 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) {
wuliqunyy 0:be95bfb06686 1757 PARAM_ARRAY_TEMPLATE(SCPI_ParamInt32);
wuliqunyy 0:be95bfb06686 1758 }
wuliqunyy 0:be95bfb06686 1759
wuliqunyy 0:be95bfb06686 1760 /**
wuliqunyy 0:be95bfb06686 1761 * Read list of values up to i_count
wuliqunyy 0:be95bfb06686 1762 * @param context
wuliqunyy 0:be95bfb06686 1763 * @param data - array to fill
wuliqunyy 0:be95bfb06686 1764 * @param i_count - number of elements of data
wuliqunyy 0:be95bfb06686 1765 * @param o_count - real number of filled elements
wuliqunyy 0:be95bfb06686 1766 * @param mandatory
wuliqunyy 0:be95bfb06686 1767 * @return TRUE on success
wuliqunyy 0:be95bfb06686 1768 */
wuliqunyy 0:be95bfb06686 1769 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) {
wuliqunyy 0:be95bfb06686 1770 PARAM_ARRAY_TEMPLATE(SCPI_ParamUInt32);
wuliqunyy 0:be95bfb06686 1771 }
wuliqunyy 0:be95bfb06686 1772
wuliqunyy 0:be95bfb06686 1773 /**
wuliqunyy 0:be95bfb06686 1774 * Read list of values up to i_count
wuliqunyy 0:be95bfb06686 1775 * @param context
wuliqunyy 0:be95bfb06686 1776 * @param data - array to fill
wuliqunyy 0:be95bfb06686 1777 * @param i_count - number of elements of data
wuliqunyy 0:be95bfb06686 1778 * @param o_count - real number of filled elements
wuliqunyy 0:be95bfb06686 1779 * @param mandatory
wuliqunyy 0:be95bfb06686 1780 * @return TRUE on success
wuliqunyy 0:be95bfb06686 1781 */
wuliqunyy 0:be95bfb06686 1782 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) {
wuliqunyy 0:be95bfb06686 1783 PARAM_ARRAY_TEMPLATE(SCPI_ParamInt64);
wuliqunyy 0:be95bfb06686 1784 }
wuliqunyy 0:be95bfb06686 1785
wuliqunyy 0:be95bfb06686 1786 /**
wuliqunyy 0:be95bfb06686 1787 * Read list of values up to i_count
wuliqunyy 0:be95bfb06686 1788 * @param context
wuliqunyy 0:be95bfb06686 1789 * @param data - array to fill
wuliqunyy 0:be95bfb06686 1790 * @param i_count - number of elements of data
wuliqunyy 0:be95bfb06686 1791 * @param o_count - real number of filled elements
wuliqunyy 0:be95bfb06686 1792 * @param mandatory
wuliqunyy 0:be95bfb06686 1793 * @return TRUE on success
wuliqunyy 0:be95bfb06686 1794 */
wuliqunyy 0:be95bfb06686 1795 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) {
wuliqunyy 0:be95bfb06686 1796 PARAM_ARRAY_TEMPLATE(SCPI_ParamUInt64);
wuliqunyy 0:be95bfb06686 1797 }
wuliqunyy 0:be95bfb06686 1798
wuliqunyy 0:be95bfb06686 1799 /**
wuliqunyy 0:be95bfb06686 1800 * Read list of values up to i_count
wuliqunyy 0:be95bfb06686 1801 * @param context
wuliqunyy 0:be95bfb06686 1802 * @param data - array to fill
wuliqunyy 0:be95bfb06686 1803 * @param i_count - number of elements of data
wuliqunyy 0:be95bfb06686 1804 * @param o_count - real number of filled elements
wuliqunyy 0:be95bfb06686 1805 * @param mandatory
wuliqunyy 0:be95bfb06686 1806 * @return TRUE on success
wuliqunyy 0:be95bfb06686 1807 */
wuliqunyy 0:be95bfb06686 1808 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) {
wuliqunyy 0:be95bfb06686 1809 PARAM_ARRAY_TEMPLATE(SCPI_ParamFloat);
wuliqunyy 0:be95bfb06686 1810 }
wuliqunyy 0:be95bfb06686 1811
wuliqunyy 0:be95bfb06686 1812 /**
wuliqunyy 0:be95bfb06686 1813 * Read list of values up to i_count
wuliqunyy 0:be95bfb06686 1814 * @param context
wuliqunyy 0:be95bfb06686 1815 * @param data - array to fill
wuliqunyy 0:be95bfb06686 1816 * @param i_count - number of elements of data
wuliqunyy 0:be95bfb06686 1817 * @param o_count - real number of filled elements
wuliqunyy 0:be95bfb06686 1818 * @param mandatory
wuliqunyy 0:be95bfb06686 1819 * @return TRUE on success
wuliqunyy 0:be95bfb06686 1820 */
wuliqunyy 0:be95bfb06686 1821 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) {
wuliqunyy 0:be95bfb06686 1822 PARAM_ARRAY_TEMPLATE(SCPI_ParamDouble);
wuliqunyy 0:be95bfb06686 1823 }
wuliqunyy 0:be95bfb06686 1824