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, Richard.hmm
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_utils.c
wuliqunyy 0:be95bfb06686 31 * @date Thu Nov 15 10:58:45 UTC 2012
wuliqunyy 0:be95bfb06686 32 *
wuliqunyy 0:be95bfb06686 33 * @brief Conversion routines and string manipulation routines
wuliqunyy 0:be95bfb06686 34 *
wuliqunyy 0:be95bfb06686 35 *
wuliqunyy 0:be95bfb06686 36 */
wuliqunyy 0:be95bfb06686 37
wuliqunyy 0:be95bfb06686 38 #include <stdio.h>
wuliqunyy 0:be95bfb06686 39 #include <stdlib.h>
wuliqunyy 0:be95bfb06686 40 #include <string.h>
wuliqunyy 0:be95bfb06686 41 #include <ctype.h>
wuliqunyy 0:be95bfb06686 42 #include <math.h>
wuliqunyy 0:be95bfb06686 43
wuliqunyy 0:be95bfb06686 44 #include "utils_private.h"
wuliqunyy 0:be95bfb06686 45 #include "scpi/utils.h"
wuliqunyy 0:be95bfb06686 46
wuliqunyy 0:be95bfb06686 47 static size_t patternSeparatorShortPos(const char * pattern, size_t len);
wuliqunyy 0:be95bfb06686 48 static size_t patternSeparatorPos(const char * pattern, size_t len);
wuliqunyy 0:be95bfb06686 49 static size_t cmdSeparatorPos(const char * cmd, size_t len);
wuliqunyy 0:be95bfb06686 50
wuliqunyy 0:be95bfb06686 51 /**
wuliqunyy 0:be95bfb06686 52 * Find the first occurrence in str of a character in set.
wuliqunyy 0:be95bfb06686 53 * @param str
wuliqunyy 0:be95bfb06686 54 * @param size
wuliqunyy 0:be95bfb06686 55 * @param set
wuliqunyy 0:be95bfb06686 56 * @return
wuliqunyy 0:be95bfb06686 57 */
wuliqunyy 0:be95bfb06686 58 char * strnpbrk(const char *str, size_t size, const char *set) {
wuliqunyy 0:be95bfb06686 59 const char *scanp;
wuliqunyy 0:be95bfb06686 60 long c, sc;
wuliqunyy 0:be95bfb06686 61 const char * strend = str + size;
wuliqunyy 0:be95bfb06686 62
wuliqunyy 0:be95bfb06686 63 while ((strend != str) && ((c = *str++) != 0)) {
wuliqunyy 0:be95bfb06686 64 for (scanp = set; (sc = *scanp++) != '\0';)
wuliqunyy 0:be95bfb06686 65 if (sc == c)
wuliqunyy 0:be95bfb06686 66 return ((char *) (str - 1));
wuliqunyy 0:be95bfb06686 67 }
wuliqunyy 0:be95bfb06686 68 return (NULL);
wuliqunyy 0:be95bfb06686 69 }
wuliqunyy 0:be95bfb06686 70
wuliqunyy 0:be95bfb06686 71 /**
wuliqunyy 0:be95bfb06686 72 * Converts signed/unsigned 32 bit integer value to string in specific base
wuliqunyy 0:be95bfb06686 73 * @param val integer value
wuliqunyy 0:be95bfb06686 74 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 75 * @param len string buffer length
wuliqunyy 0:be95bfb06686 76 * @param base output base
wuliqunyy 0:be95bfb06686 77 * @param sign
wuliqunyy 0:be95bfb06686 78 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 79 */
wuliqunyy 0:be95bfb06686 80 size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 81 const char digits[] = "0123456789ABCDEF";
wuliqunyy 0:be95bfb06686 82
wuliqunyy 0:be95bfb06686 83 #define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
wuliqunyy 0:be95bfb06686 84 uint32_t x = 0;
wuliqunyy 0:be95bfb06686 85 int_fast8_t digit;
wuliqunyy 0:be95bfb06686 86 size_t pos = 0;
wuliqunyy 0:be95bfb06686 87 uint32_t uval = val;
wuliqunyy 0:be95bfb06686 88
wuliqunyy 0:be95bfb06686 89 if (uval == 0) {
wuliqunyy 0:be95bfb06686 90 ADD_CHAR('0');
wuliqunyy 0:be95bfb06686 91 } else {
wuliqunyy 0:be95bfb06686 92
wuliqunyy 0:be95bfb06686 93 switch (base) {
wuliqunyy 0:be95bfb06686 94 case 2:
wuliqunyy 0:be95bfb06686 95 x = 0x80000000L;
wuliqunyy 0:be95bfb06686 96 break;
wuliqunyy 0:be95bfb06686 97 case 8:
wuliqunyy 0:be95bfb06686 98 x = 0x40000000L;
wuliqunyy 0:be95bfb06686 99 break;
wuliqunyy 0:be95bfb06686 100 default:
wuliqunyy 0:be95bfb06686 101 case 10:
wuliqunyy 0:be95bfb06686 102 base = 10;
wuliqunyy 0:be95bfb06686 103 x = 1000000000L;
wuliqunyy 0:be95bfb06686 104 break;
wuliqunyy 0:be95bfb06686 105 case 16:
wuliqunyy 0:be95bfb06686 106 x = 0x10000000L;
wuliqunyy 0:be95bfb06686 107 break;
wuliqunyy 0:be95bfb06686 108 }
wuliqunyy 0:be95bfb06686 109
wuliqunyy 0:be95bfb06686 110 /* add sign for numbers in base 10 */
wuliqunyy 0:be95bfb06686 111 if (sign && ((int32_t) val < 0) && (base == 10)) {
wuliqunyy 0:be95bfb06686 112 uval = -val;
wuliqunyy 0:be95bfb06686 113 ADD_CHAR('-');
wuliqunyy 0:be95bfb06686 114 }
wuliqunyy 0:be95bfb06686 115
wuliqunyy 0:be95bfb06686 116 /* remove leading zeros */
wuliqunyy 0:be95bfb06686 117 while ((uval / x) == 0) {
wuliqunyy 0:be95bfb06686 118 x /= base;
wuliqunyy 0:be95bfb06686 119 }
wuliqunyy 0:be95bfb06686 120
wuliqunyy 0:be95bfb06686 121 do {
wuliqunyy 0:be95bfb06686 122 digit = (uint8_t) (uval / x);
wuliqunyy 0:be95bfb06686 123 ADD_CHAR(digits[digit]);
wuliqunyy 0:be95bfb06686 124 uval -= digit * x;
wuliqunyy 0:be95bfb06686 125 x /= base;
wuliqunyy 0:be95bfb06686 126 } while (x && (pos < len));
wuliqunyy 0:be95bfb06686 127 }
wuliqunyy 0:be95bfb06686 128
wuliqunyy 0:be95bfb06686 129 if (pos < len) str[pos] = 0;
wuliqunyy 0:be95bfb06686 130 return pos;
wuliqunyy 0:be95bfb06686 131 #undef ADD_CHAR
wuliqunyy 0:be95bfb06686 132 }
wuliqunyy 0:be95bfb06686 133
wuliqunyy 0:be95bfb06686 134 /**
wuliqunyy 0:be95bfb06686 135 * Converts signed 32 bit integer value to string
wuliqunyy 0:be95bfb06686 136 * @param val integer value
wuliqunyy 0:be95bfb06686 137 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 138 * @param len string buffer length
wuliqunyy 0:be95bfb06686 139 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 140 */
wuliqunyy 0:be95bfb06686 141 size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len) {
wuliqunyy 0:be95bfb06686 142 return UInt32ToStrBaseSign((uint32_t) val, str, len, 10, TRUE);
wuliqunyy 0:be95bfb06686 143 }
wuliqunyy 0:be95bfb06686 144
wuliqunyy 0:be95bfb06686 145 /**
wuliqunyy 0:be95bfb06686 146 * Converts unsigned 32 bit integer value to string in specific base
wuliqunyy 0:be95bfb06686 147 * @param val integer value
wuliqunyy 0:be95bfb06686 148 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 149 * @param len string buffer length
wuliqunyy 0:be95bfb06686 150 * @param base output base
wuliqunyy 0:be95bfb06686 151 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 152 */
wuliqunyy 0:be95bfb06686 153 size_t SCPI_UInt32ToStrBase(uint32_t val, char * str, size_t len, int8_t base) {
wuliqunyy 0:be95bfb06686 154 return UInt32ToStrBaseSign(val, str, len, base, FALSE);
wuliqunyy 0:be95bfb06686 155 }
wuliqunyy 0:be95bfb06686 156
wuliqunyy 0:be95bfb06686 157 /**
wuliqunyy 0:be95bfb06686 158 * Converts signed/unsigned 64 bit integer value to string in specific base
wuliqunyy 0:be95bfb06686 159 * @param val integer value
wuliqunyy 0:be95bfb06686 160 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 161 * @param len string buffer length
wuliqunyy 0:be95bfb06686 162 * @param base output base
wuliqunyy 0:be95bfb06686 163 * @param sign
wuliqunyy 0:be95bfb06686 164 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 165 */
wuliqunyy 0:be95bfb06686 166 size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) {
wuliqunyy 0:be95bfb06686 167 const char digits[] = "0123456789ABCDEF";
wuliqunyy 0:be95bfb06686 168
wuliqunyy 0:be95bfb06686 169 #define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
wuliqunyy 0:be95bfb06686 170 uint64_t x = 0;
wuliqunyy 0:be95bfb06686 171 int_fast8_t digit;
wuliqunyy 0:be95bfb06686 172 size_t pos = 0;
wuliqunyy 0:be95bfb06686 173 uint64_t uval = val;
wuliqunyy 0:be95bfb06686 174
wuliqunyy 0:be95bfb06686 175 if (uval == 0) {
wuliqunyy 0:be95bfb06686 176 ADD_CHAR('0');
wuliqunyy 0:be95bfb06686 177 } else {
wuliqunyy 0:be95bfb06686 178
wuliqunyy 0:be95bfb06686 179 switch (base) {
wuliqunyy 0:be95bfb06686 180 case 2:
wuliqunyy 0:be95bfb06686 181 x = 0x8000000000000000ULL;
wuliqunyy 0:be95bfb06686 182 break;
wuliqunyy 0:be95bfb06686 183 case 8:
wuliqunyy 0:be95bfb06686 184 x = 0x8000000000000000ULL;
wuliqunyy 0:be95bfb06686 185 break;
wuliqunyy 0:be95bfb06686 186 default:
wuliqunyy 0:be95bfb06686 187 case 10:
wuliqunyy 0:be95bfb06686 188 x = 10000000000000000000ULL;
wuliqunyy 0:be95bfb06686 189 base = 10;
wuliqunyy 0:be95bfb06686 190 break;
wuliqunyy 0:be95bfb06686 191 case 16:
wuliqunyy 0:be95bfb06686 192 x = 0x1000000000000000ULL;
wuliqunyy 0:be95bfb06686 193 break;
wuliqunyy 0:be95bfb06686 194 }
wuliqunyy 0:be95bfb06686 195
wuliqunyy 0:be95bfb06686 196 /* add sign for numbers in base 10 */
wuliqunyy 0:be95bfb06686 197 if (sign && ((int64_t) val < 0) && (base == 10)) {
wuliqunyy 0:be95bfb06686 198 uval = -val;
wuliqunyy 0:be95bfb06686 199 ADD_CHAR('-');
wuliqunyy 0:be95bfb06686 200 }
wuliqunyy 0:be95bfb06686 201
wuliqunyy 0:be95bfb06686 202 /* remove leading zeros */
wuliqunyy 0:be95bfb06686 203 while ((uval / x) == 0) {
wuliqunyy 0:be95bfb06686 204 x /= base;
wuliqunyy 0:be95bfb06686 205 }
wuliqunyy 0:be95bfb06686 206
wuliqunyy 0:be95bfb06686 207 do {
wuliqunyy 0:be95bfb06686 208 digit = (uint8_t) (uval / x);
wuliqunyy 0:be95bfb06686 209 ADD_CHAR(digits[digit]);
wuliqunyy 0:be95bfb06686 210 uval -= digit * x;
wuliqunyy 0:be95bfb06686 211 x /= base;
wuliqunyy 0:be95bfb06686 212 } while (x && (pos < len));
wuliqunyy 0:be95bfb06686 213 }
wuliqunyy 0:be95bfb06686 214
wuliqunyy 0:be95bfb06686 215 if (pos < len) str[pos] = 0;
wuliqunyy 0:be95bfb06686 216 return pos;
wuliqunyy 0:be95bfb06686 217 #undef ADD_CHAR
wuliqunyy 0:be95bfb06686 218 }
wuliqunyy 0:be95bfb06686 219
wuliqunyy 0:be95bfb06686 220 /**
wuliqunyy 0:be95bfb06686 221 * Converts signed 64 bit integer value to string
wuliqunyy 0:be95bfb06686 222 * @param val integer value
wuliqunyy 0:be95bfb06686 223 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 224 * @param len string buffer length
wuliqunyy 0:be95bfb06686 225 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 226 */
wuliqunyy 0:be95bfb06686 227 size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len) {
wuliqunyy 0:be95bfb06686 228 return UInt64ToStrBaseSign((uint64_t) val, str, len, 10, TRUE);
wuliqunyy 0:be95bfb06686 229 }
wuliqunyy 0:be95bfb06686 230
wuliqunyy 0:be95bfb06686 231 /**
wuliqunyy 0:be95bfb06686 232 * Converts signed/unsigned 64 bit integer value to string in specific base
wuliqunyy 0:be95bfb06686 233 * @param val integer value
wuliqunyy 0:be95bfb06686 234 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 235 * @param len string buffer length
wuliqunyy 0:be95bfb06686 236 * @param base output base
wuliqunyy 0:be95bfb06686 237 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 238 */
wuliqunyy 0:be95bfb06686 239 size_t SCPI_UInt64ToStrBase(uint64_t val, char * str, size_t len, int8_t base) {
wuliqunyy 0:be95bfb06686 240 return UInt64ToStrBaseSign(val, str, len, base, FALSE);
wuliqunyy 0:be95bfb06686 241 }
wuliqunyy 0:be95bfb06686 242
wuliqunyy 0:be95bfb06686 243 /**
wuliqunyy 0:be95bfb06686 244 * Converts float (32 bit) value to string
wuliqunyy 0:be95bfb06686 245 * @param val long value
wuliqunyy 0:be95bfb06686 246 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 247 * @param len string buffer length
wuliqunyy 0:be95bfb06686 248 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 249 */
wuliqunyy 0:be95bfb06686 250 size_t SCPI_FloatToStr(float val, char * str, size_t len) {
wuliqunyy 0:be95bfb06686 251 SCPIDEFINE_floatToStr(val, str, len);
wuliqunyy 0:be95bfb06686 252 return strlen(str);
wuliqunyy 0:be95bfb06686 253 }
wuliqunyy 0:be95bfb06686 254
wuliqunyy 0:be95bfb06686 255 /**
wuliqunyy 0:be95bfb06686 256 * Converts double (64 bit) value to string
wuliqunyy 0:be95bfb06686 257 * @param val double value
wuliqunyy 0:be95bfb06686 258 * @param str converted textual representation
wuliqunyy 0:be95bfb06686 259 * @param len string buffer length
wuliqunyy 0:be95bfb06686 260 * @return number of bytes written to str (without '\0')
wuliqunyy 0:be95bfb06686 261 */
wuliqunyy 0:be95bfb06686 262 size_t SCPI_DoubleToStr(double val, char * str, size_t len) {
wuliqunyy 0:be95bfb06686 263 SCPIDEFINE_doubleToStr(val, str, len);
wuliqunyy 0:be95bfb06686 264 return strlen(str);
wuliqunyy 0:be95bfb06686 265 }
wuliqunyy 0:be95bfb06686 266
wuliqunyy 0:be95bfb06686 267 /**
wuliqunyy 0:be95bfb06686 268 * Converts string to signed 32bit integer representation
wuliqunyy 0:be95bfb06686 269 * @param str string value
wuliqunyy 0:be95bfb06686 270 * @param val 32bit integer result
wuliqunyy 0:be95bfb06686 271 * @return number of bytes used in string
wuliqunyy 0:be95bfb06686 272 */
wuliqunyy 0:be95bfb06686 273 size_t strBaseToInt32(const char * str, int32_t * val, int8_t base) {
wuliqunyy 0:be95bfb06686 274 char * endptr;
wuliqunyy 0:be95bfb06686 275 *val = strtol(str, &endptr, base);
wuliqunyy 0:be95bfb06686 276 return endptr - str;
wuliqunyy 0:be95bfb06686 277 }
wuliqunyy 0:be95bfb06686 278
wuliqunyy 0:be95bfb06686 279 /**
wuliqunyy 0:be95bfb06686 280 * Converts string to unsigned 32bit integer representation
wuliqunyy 0:be95bfb06686 281 * @param str string value
wuliqunyy 0:be95bfb06686 282 * @param val 32bit integer result
wuliqunyy 0:be95bfb06686 283 * @return number of bytes used in string
wuliqunyy 0:be95bfb06686 284 */
wuliqunyy 0:be95bfb06686 285 size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) {
wuliqunyy 0:be95bfb06686 286 char * endptr;
wuliqunyy 0:be95bfb06686 287 *val = strtoul(str, &endptr, base);
wuliqunyy 0:be95bfb06686 288 return endptr - str;
wuliqunyy 0:be95bfb06686 289 }
wuliqunyy 0:be95bfb06686 290
wuliqunyy 0:be95bfb06686 291 /**
wuliqunyy 0:be95bfb06686 292 * Converts string to signed 64bit integer representation
wuliqunyy 0:be95bfb06686 293 * @param str string value
wuliqunyy 0:be95bfb06686 294 * @param val 64bit integer result
wuliqunyy 0:be95bfb06686 295 * @return number of bytes used in string
wuliqunyy 0:be95bfb06686 296 */
wuliqunyy 0:be95bfb06686 297 size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) {
wuliqunyy 0:be95bfb06686 298 char * endptr;
wuliqunyy 0:be95bfb06686 299 *val = SCPIDEFINE_strtoll(str, &endptr, base);
wuliqunyy 0:be95bfb06686 300 return endptr - str;
wuliqunyy 0:be95bfb06686 301 }
wuliqunyy 0:be95bfb06686 302
wuliqunyy 0:be95bfb06686 303 /**
wuliqunyy 0:be95bfb06686 304 * Converts string to unsigned 64bit integer representation
wuliqunyy 0:be95bfb06686 305 * @param str string value
wuliqunyy 0:be95bfb06686 306 * @param val 64bit integer result
wuliqunyy 0:be95bfb06686 307 * @return number of bytes used in string
wuliqunyy 0:be95bfb06686 308 */
wuliqunyy 0:be95bfb06686 309 size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) {
wuliqunyy 0:be95bfb06686 310 char * endptr;
wuliqunyy 0:be95bfb06686 311 *val = SCPIDEFINE_strtoull(str, &endptr, base);
wuliqunyy 0:be95bfb06686 312 return endptr - str;
wuliqunyy 0:be95bfb06686 313 }
wuliqunyy 0:be95bfb06686 314
wuliqunyy 0:be95bfb06686 315 /**
wuliqunyy 0:be95bfb06686 316 * Converts string to float (32 bit) representation
wuliqunyy 0:be95bfb06686 317 * @param str string value
wuliqunyy 0:be95bfb06686 318 * @param val float result
wuliqunyy 0:be95bfb06686 319 * @return number of bytes used in string
wuliqunyy 0:be95bfb06686 320 */
wuliqunyy 0:be95bfb06686 321 size_t strToFloat(const char * str, float * val) {
wuliqunyy 0:be95bfb06686 322 char * endptr;
wuliqunyy 0:be95bfb06686 323 *val = SCPIDEFINE_strtof(str, &endptr);
wuliqunyy 0:be95bfb06686 324 return endptr - str;
wuliqunyy 0:be95bfb06686 325 }
wuliqunyy 0:be95bfb06686 326
wuliqunyy 0:be95bfb06686 327 /**
wuliqunyy 0:be95bfb06686 328 * Converts string to double (64 bit) representation
wuliqunyy 0:be95bfb06686 329 * @param str string value
wuliqunyy 0:be95bfb06686 330 * @param val double result
wuliqunyy 0:be95bfb06686 331 * @return number of bytes used in string
wuliqunyy 0:be95bfb06686 332 */
wuliqunyy 0:be95bfb06686 333 size_t strToDouble(const char * str, double * val) {
wuliqunyy 0:be95bfb06686 334 char * endptr;
wuliqunyy 0:be95bfb06686 335 *val = strtod(str, &endptr);
wuliqunyy 0:be95bfb06686 336 return endptr - str;
wuliqunyy 0:be95bfb06686 337 }
wuliqunyy 0:be95bfb06686 338
wuliqunyy 0:be95bfb06686 339 /**
wuliqunyy 0:be95bfb06686 340 * Compare two strings with exact length
wuliqunyy 0:be95bfb06686 341 * @param str1
wuliqunyy 0:be95bfb06686 342 * @param len1
wuliqunyy 0:be95bfb06686 343 * @param str2
wuliqunyy 0:be95bfb06686 344 * @param len2
wuliqunyy 0:be95bfb06686 345 * @return TRUE if len1==len2 and "len" characters of both strings are equal
wuliqunyy 0:be95bfb06686 346 */
wuliqunyy 0:be95bfb06686 347 scpi_bool_t compareStr(const char * str1, size_t len1, const char * str2, size_t len2) {
wuliqunyy 0:be95bfb06686 348 if (len1 != len2) {
wuliqunyy 0:be95bfb06686 349 return FALSE;
wuliqunyy 0:be95bfb06686 350 }
wuliqunyy 0:be95bfb06686 351
wuliqunyy 0:be95bfb06686 352 if (SCPIDEFINE_strncasecmp(str1, str2, len2) == 0) {
wuliqunyy 0:be95bfb06686 353 return TRUE;
wuliqunyy 0:be95bfb06686 354 }
wuliqunyy 0:be95bfb06686 355
wuliqunyy 0:be95bfb06686 356 return FALSE;
wuliqunyy 0:be95bfb06686 357 }
wuliqunyy 0:be95bfb06686 358
wuliqunyy 0:be95bfb06686 359 /**
wuliqunyy 0:be95bfb06686 360 * Compare two strings, one be longer but may contains only numbers in that section
wuliqunyy 0:be95bfb06686 361 * @param str1
wuliqunyy 0:be95bfb06686 362 * @param len1
wuliqunyy 0:be95bfb06686 363 * @param str2
wuliqunyy 0:be95bfb06686 364 * @param len2
wuliqunyy 0:be95bfb06686 365 * @return TRUE if strings match
wuliqunyy 0:be95bfb06686 366 */
wuliqunyy 0:be95bfb06686 367 scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) {
wuliqunyy 0:be95bfb06686 368 scpi_bool_t result = FALSE;
wuliqunyy 0:be95bfb06686 369 size_t i;
wuliqunyy 0:be95bfb06686 370
wuliqunyy 0:be95bfb06686 371 if (len2 < len1) {
wuliqunyy 0:be95bfb06686 372 return FALSE;
wuliqunyy 0:be95bfb06686 373 }
wuliqunyy 0:be95bfb06686 374
wuliqunyy 0:be95bfb06686 375 if (SCPIDEFINE_strncasecmp(str1, str2, len1) == 0) {
wuliqunyy 0:be95bfb06686 376 result = TRUE;
wuliqunyy 0:be95bfb06686 377
wuliqunyy 0:be95bfb06686 378 if (num) {
wuliqunyy 0:be95bfb06686 379 if (len1 == len2) {
wuliqunyy 0:be95bfb06686 380 /* *num = 1; */
wuliqunyy 0:be95bfb06686 381 } else {
wuliqunyy 0:be95bfb06686 382 int32_t tmpNum;
wuliqunyy 0:be95bfb06686 383 i = len1 + strBaseToInt32(str2 + len1, &tmpNum, 10);
wuliqunyy 0:be95bfb06686 384 if (i != len2) {
wuliqunyy 0:be95bfb06686 385 result = FALSE;
wuliqunyy 0:be95bfb06686 386 } else {
wuliqunyy 0:be95bfb06686 387 *num = tmpNum;
wuliqunyy 0:be95bfb06686 388 }
wuliqunyy 0:be95bfb06686 389 }
wuliqunyy 0:be95bfb06686 390 } else {
wuliqunyy 0:be95bfb06686 391 for (i = len1; i < len2; i++) {
wuliqunyy 0:be95bfb06686 392 if (!isdigit((int) str2[i])) {
wuliqunyy 0:be95bfb06686 393 result = FALSE;
wuliqunyy 0:be95bfb06686 394 break;
wuliqunyy 0:be95bfb06686 395 }
wuliqunyy 0:be95bfb06686 396 }
wuliqunyy 0:be95bfb06686 397 }
wuliqunyy 0:be95bfb06686 398 }
wuliqunyy 0:be95bfb06686 399
wuliqunyy 0:be95bfb06686 400 return result;
wuliqunyy 0:be95bfb06686 401 }
wuliqunyy 0:be95bfb06686 402
wuliqunyy 0:be95bfb06686 403 /**
wuliqunyy 0:be95bfb06686 404 * Count white spaces from the beggining
wuliqunyy 0:be95bfb06686 405 * @param cmd - command
wuliqunyy 0:be95bfb06686 406 * @param len - max search length
wuliqunyy 0:be95bfb06686 407 * @return number of white spaces
wuliqunyy 0:be95bfb06686 408 */
wuliqunyy 0:be95bfb06686 409 size_t skipWhitespace(const char * cmd, size_t len) {
wuliqunyy 0:be95bfb06686 410 size_t i;
wuliqunyy 0:be95bfb06686 411 for (i = 0; i < len; i++) {
wuliqunyy 0:be95bfb06686 412 if (!isspace((unsigned char) cmd[i])) {
wuliqunyy 0:be95bfb06686 413 return i;
wuliqunyy 0:be95bfb06686 414 }
wuliqunyy 0:be95bfb06686 415 }
wuliqunyy 0:be95bfb06686 416 return len;
wuliqunyy 0:be95bfb06686 417 }
wuliqunyy 0:be95bfb06686 418
wuliqunyy 0:be95bfb06686 419 /**
wuliqunyy 0:be95bfb06686 420 * Pattern is composed from upper case an lower case letters. This function
wuliqunyy 0:be95bfb06686 421 * search the first lowercase letter
wuliqunyy 0:be95bfb06686 422 * @param pattern
wuliqunyy 0:be95bfb06686 423 * @param len - max search length
wuliqunyy 0:be95bfb06686 424 * @return position of separator or len
wuliqunyy 0:be95bfb06686 425 */
wuliqunyy 0:be95bfb06686 426 static size_t patternSeparatorShortPos(const char * pattern, size_t len) {
wuliqunyy 0:be95bfb06686 427 size_t i;
wuliqunyy 0:be95bfb06686 428 for (i = 0; (i < len) && pattern[i]; i++) {
wuliqunyy 0:be95bfb06686 429 if (islower((unsigned char) pattern[i])) {
wuliqunyy 0:be95bfb06686 430 return i;
wuliqunyy 0:be95bfb06686 431 }
wuliqunyy 0:be95bfb06686 432 }
wuliqunyy 0:be95bfb06686 433 return i;
wuliqunyy 0:be95bfb06686 434 }
wuliqunyy 0:be95bfb06686 435
wuliqunyy 0:be95bfb06686 436 /**
wuliqunyy 0:be95bfb06686 437 * Find pattern separator position
wuliqunyy 0:be95bfb06686 438 * @param pattern
wuliqunyy 0:be95bfb06686 439 * @param len - max search length
wuliqunyy 0:be95bfb06686 440 * @return position of separator or len
wuliqunyy 0:be95bfb06686 441 */
wuliqunyy 0:be95bfb06686 442 static size_t patternSeparatorPos(const char * pattern, size_t len) {
wuliqunyy 0:be95bfb06686 443
wuliqunyy 0:be95bfb06686 444 char * separator = strnpbrk(pattern, len, "?:[]");
wuliqunyy 0:be95bfb06686 445 if (separator == NULL) {
wuliqunyy 0:be95bfb06686 446 return len;
wuliqunyy 0:be95bfb06686 447 } else {
wuliqunyy 0:be95bfb06686 448 return separator - pattern;
wuliqunyy 0:be95bfb06686 449 }
wuliqunyy 0:be95bfb06686 450 }
wuliqunyy 0:be95bfb06686 451
wuliqunyy 0:be95bfb06686 452 /**
wuliqunyy 0:be95bfb06686 453 * Find command separator position
wuliqunyy 0:be95bfb06686 454 * @param cmd - input command
wuliqunyy 0:be95bfb06686 455 * @param len - max search length
wuliqunyy 0:be95bfb06686 456 * @return position of separator or len
wuliqunyy 0:be95bfb06686 457 */
wuliqunyy 0:be95bfb06686 458 static size_t cmdSeparatorPos(const char * cmd, size_t len) {
wuliqunyy 0:be95bfb06686 459 char * separator = strnpbrk(cmd, len, ":?");
wuliqunyy 0:be95bfb06686 460 size_t result;
wuliqunyy 0:be95bfb06686 461 if (separator == NULL) {
wuliqunyy 0:be95bfb06686 462 result = len;
wuliqunyy 0:be95bfb06686 463 } else {
wuliqunyy 0:be95bfb06686 464 result = separator - cmd;
wuliqunyy 0:be95bfb06686 465 }
wuliqunyy 0:be95bfb06686 466
wuliqunyy 0:be95bfb06686 467 return result;
wuliqunyy 0:be95bfb06686 468 }
wuliqunyy 0:be95bfb06686 469
wuliqunyy 0:be95bfb06686 470 /**
wuliqunyy 0:be95bfb06686 471 * Match pattern and str. Pattern is in format UPPERCASElowercase
wuliqunyy 0:be95bfb06686 472 * @param pattern
wuliqunyy 0:be95bfb06686 473 * @param pattern_len
wuliqunyy 0:be95bfb06686 474 * @param str
wuliqunyy 0:be95bfb06686 475 * @param str_len
wuliqunyy 0:be95bfb06686 476 * @return
wuliqunyy 0:be95bfb06686 477 */
wuliqunyy 0:be95bfb06686 478 scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len, int32_t * num) {
wuliqunyy 0:be95bfb06686 479 int pattern_sep_pos_short;
wuliqunyy 0:be95bfb06686 480
wuliqunyy 0:be95bfb06686 481 if ((pattern_len > 0) && pattern[pattern_len - 1] == '#') {
wuliqunyy 0:be95bfb06686 482 size_t new_pattern_len = pattern_len - 1;
wuliqunyy 0:be95bfb06686 483
wuliqunyy 0:be95bfb06686 484 pattern_sep_pos_short = patternSeparatorShortPos(pattern, new_pattern_len);
wuliqunyy 0:be95bfb06686 485
wuliqunyy 0:be95bfb06686 486 return compareStrAndNum(pattern, new_pattern_len, str, str_len, num) ||
wuliqunyy 0:be95bfb06686 487 compareStrAndNum(pattern, pattern_sep_pos_short, str, str_len, num);
wuliqunyy 0:be95bfb06686 488 } else {
wuliqunyy 0:be95bfb06686 489
wuliqunyy 0:be95bfb06686 490 pattern_sep_pos_short = patternSeparatorShortPos(pattern, pattern_len);
wuliqunyy 0:be95bfb06686 491
wuliqunyy 0:be95bfb06686 492 return compareStr(pattern, pattern_len, str, str_len) ||
wuliqunyy 0:be95bfb06686 493 compareStr(pattern, pattern_sep_pos_short, str, str_len);
wuliqunyy 0:be95bfb06686 494 }
wuliqunyy 0:be95bfb06686 495 }
wuliqunyy 0:be95bfb06686 496
wuliqunyy 0:be95bfb06686 497 /**
wuliqunyy 0:be95bfb06686 498 * Compare pattern and command
wuliqunyy 0:be95bfb06686 499 * @param pattern eg. [:MEASure]:VOLTage:DC?
wuliqunyy 0:be95bfb06686 500 * @param cmd - command
wuliqunyy 0:be95bfb06686 501 * @param len - max search length
wuliqunyy 0:be95bfb06686 502 * @return TRUE if pattern matches, FALSE otherwise
wuliqunyy 0:be95bfb06686 503 */
wuliqunyy 0:be95bfb06686 504 scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value) {
wuliqunyy 0:be95bfb06686 505 #define SKIP_PATTERN(n) do {pattern_ptr += (n); pattern_len -= (n);} while(0)
wuliqunyy 0:be95bfb06686 506 #define SKIP_CMD(n) do {cmd_ptr += (n); cmd_len -= (n);} while(0)
wuliqunyy 0:be95bfb06686 507
wuliqunyy 0:be95bfb06686 508 scpi_bool_t result = FALSE;
wuliqunyy 0:be95bfb06686 509 int brackets = 0;
wuliqunyy 0:be95bfb06686 510 int cmd_sep_pos = 0;
wuliqunyy 0:be95bfb06686 511
wuliqunyy 0:be95bfb06686 512 size_t numbers_idx = 0;
wuliqunyy 0:be95bfb06686 513 int32_t *number_ptr = NULL;
wuliqunyy 0:be95bfb06686 514
wuliqunyy 0:be95bfb06686 515 const char * pattern_ptr = pattern;
wuliqunyy 0:be95bfb06686 516 int pattern_len = strlen(pattern);
wuliqunyy 0:be95bfb06686 517
wuliqunyy 0:be95bfb06686 518 const char * cmd_ptr = cmd;
wuliqunyy 0:be95bfb06686 519 size_t cmd_len = SCPIDEFINE_strnlen(cmd, len);
wuliqunyy 0:be95bfb06686 520
wuliqunyy 0:be95bfb06686 521 /* both commands are query commands? */
wuliqunyy 0:be95bfb06686 522 if (pattern_ptr[pattern_len - 1] == '?') {
wuliqunyy 0:be95bfb06686 523 if (cmd_ptr[cmd_len - 1] == '?') {
wuliqunyy 0:be95bfb06686 524 cmd_len -= 1;
wuliqunyy 0:be95bfb06686 525 pattern_len -= 1;
wuliqunyy 0:be95bfb06686 526 } else {
wuliqunyy 0:be95bfb06686 527 return FALSE;
wuliqunyy 0:be95bfb06686 528 }
wuliqunyy 0:be95bfb06686 529 }
wuliqunyy 0:be95bfb06686 530
wuliqunyy 0:be95bfb06686 531 /* now support optional keywords in pattern style, e.g. [:MEASure]:VOLTage:DC? */
wuliqunyy 0:be95bfb06686 532 if (pattern_ptr[0] == '[') { /* skip first '[' */
wuliqunyy 0:be95bfb06686 533 SKIP_PATTERN(1);
wuliqunyy 0:be95bfb06686 534 brackets++;
wuliqunyy 0:be95bfb06686 535 }
wuliqunyy 0:be95bfb06686 536 if (pattern_ptr[0] == ':') { /* skip first ':' */
wuliqunyy 0:be95bfb06686 537 SKIP_PATTERN(1);
wuliqunyy 0:be95bfb06686 538 }
wuliqunyy 0:be95bfb06686 539
wuliqunyy 0:be95bfb06686 540 if (cmd_ptr[0] == ':') {
wuliqunyy 0:be95bfb06686 541 /* handle errornouse ":*IDN?" */
wuliqunyy 0:be95bfb06686 542 if (cmd_len >= 2) {
wuliqunyy 0:be95bfb06686 543 if (cmd_ptr[1] != '*') {
wuliqunyy 0:be95bfb06686 544 SKIP_CMD(1);
wuliqunyy 0:be95bfb06686 545 } else {
wuliqunyy 0:be95bfb06686 546 return FALSE;
wuliqunyy 0:be95bfb06686 547 }
wuliqunyy 0:be95bfb06686 548 }
wuliqunyy 0:be95bfb06686 549 }
wuliqunyy 0:be95bfb06686 550
wuliqunyy 0:be95bfb06686 551 while (1) {
wuliqunyy 0:be95bfb06686 552 int pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_len);
wuliqunyy 0:be95bfb06686 553
wuliqunyy 0:be95bfb06686 554 cmd_sep_pos = cmdSeparatorPos(cmd_ptr, cmd_len);
wuliqunyy 0:be95bfb06686 555
wuliqunyy 0:be95bfb06686 556 if ((pattern_sep_pos > 0) && pattern_ptr[pattern_sep_pos - 1] == '#') {
wuliqunyy 0:be95bfb06686 557 if (numbers && (numbers_idx < numbers_len)) {
wuliqunyy 0:be95bfb06686 558 number_ptr = numbers + numbers_idx;
wuliqunyy 0:be95bfb06686 559 *number_ptr = default_value; /* default value */
wuliqunyy 0:be95bfb06686 560 } else {
wuliqunyy 0:be95bfb06686 561 number_ptr = NULL;
wuliqunyy 0:be95bfb06686 562 }
wuliqunyy 0:be95bfb06686 563 numbers_idx++;
wuliqunyy 0:be95bfb06686 564 } else {
wuliqunyy 0:be95bfb06686 565 number_ptr = NULL;
wuliqunyy 0:be95bfb06686 566 }
wuliqunyy 0:be95bfb06686 567
wuliqunyy 0:be95bfb06686 568 if (matchPattern(pattern_ptr, pattern_sep_pos, cmd_ptr, cmd_sep_pos, number_ptr)) {
wuliqunyy 0:be95bfb06686 569 SKIP_PATTERN(pattern_sep_pos);
wuliqunyy 0:be95bfb06686 570 SKIP_CMD(cmd_sep_pos);
wuliqunyy 0:be95bfb06686 571 result = TRUE;
wuliqunyy 0:be95bfb06686 572
wuliqunyy 0:be95bfb06686 573 /* command is complete */
wuliqunyy 0:be95bfb06686 574 if ((pattern_len == 0) && (cmd_len == 0)) {
wuliqunyy 0:be95bfb06686 575 break;
wuliqunyy 0:be95bfb06686 576 }
wuliqunyy 0:be95bfb06686 577
wuliqunyy 0:be95bfb06686 578 /* pattern complete, but command not */
wuliqunyy 0:be95bfb06686 579 if ((pattern_len == 0) && (cmd_len > 0)) {
wuliqunyy 0:be95bfb06686 580 result = FALSE;
wuliqunyy 0:be95bfb06686 581 break;
wuliqunyy 0:be95bfb06686 582 }
wuliqunyy 0:be95bfb06686 583
wuliqunyy 0:be95bfb06686 584 /* command complete, but pattern not */
wuliqunyy 0:be95bfb06686 585 if (cmd_len == 0) {
wuliqunyy 0:be95bfb06686 586 /* verify all subsequent pattern parts are also optional */
wuliqunyy 0:be95bfb06686 587 while (pattern_len) {
wuliqunyy 0:be95bfb06686 588 pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_len);
wuliqunyy 0:be95bfb06686 589 switch (pattern_ptr[pattern_sep_pos]) {
wuliqunyy 0:be95bfb06686 590 case '[':
wuliqunyy 0:be95bfb06686 591 brackets++;
wuliqunyy 0:be95bfb06686 592 break;
wuliqunyy 0:be95bfb06686 593 case ']':
wuliqunyy 0:be95bfb06686 594 brackets--;
wuliqunyy 0:be95bfb06686 595 break;
wuliqunyy 0:be95bfb06686 596 default:
wuliqunyy 0:be95bfb06686 597 break;
wuliqunyy 0:be95bfb06686 598 }
wuliqunyy 0:be95bfb06686 599 SKIP_PATTERN(pattern_sep_pos + 1);
wuliqunyy 0:be95bfb06686 600 if (brackets == 0) {
wuliqunyy 0:be95bfb06686 601 if ((pattern_len > 0) && (pattern_ptr[0] == '[')) {
wuliqunyy 0:be95bfb06686 602 continue;
wuliqunyy 0:be95bfb06686 603 } else {
wuliqunyy 0:be95bfb06686 604 break;
wuliqunyy 0:be95bfb06686 605 }
wuliqunyy 0:be95bfb06686 606 }
wuliqunyy 0:be95bfb06686 607 }
wuliqunyy 0:be95bfb06686 608 if (pattern_len != 0) {
wuliqunyy 0:be95bfb06686 609 result = FALSE;
wuliqunyy 0:be95bfb06686 610 }
wuliqunyy 0:be95bfb06686 611 break; /* exist optional keyword, command is complete */
wuliqunyy 0:be95bfb06686 612 }
wuliqunyy 0:be95bfb06686 613
wuliqunyy 0:be95bfb06686 614 /* both command and patter contains command separator at this position */
wuliqunyy 0:be95bfb06686 615 if ((pattern_len > 0)
wuliqunyy 0:be95bfb06686 616 && ((pattern_ptr[0] == cmd_ptr[0])
wuliqunyy 0:be95bfb06686 617 && (pattern_ptr[0] == ':'))) {
wuliqunyy 0:be95bfb06686 618 SKIP_PATTERN(1);
wuliqunyy 0:be95bfb06686 619 SKIP_CMD(1);
wuliqunyy 0:be95bfb06686 620 } else if ((pattern_len > 1)
wuliqunyy 0:be95bfb06686 621 && (pattern_ptr[1] == cmd_ptr[0])
wuliqunyy 0:be95bfb06686 622 && (pattern_ptr[0] == '[')
wuliqunyy 0:be95bfb06686 623 && (pattern_ptr[1] == ':')) {
wuliqunyy 0:be95bfb06686 624 SKIP_PATTERN(2); /* for skip '[' in "[:" */
wuliqunyy 0:be95bfb06686 625 SKIP_CMD(1);
wuliqunyy 0:be95bfb06686 626 brackets++;
wuliqunyy 0:be95bfb06686 627 } else if ((pattern_len > 1)
wuliqunyy 0:be95bfb06686 628 && (pattern_ptr[1] == cmd_ptr[0])
wuliqunyy 0:be95bfb06686 629 && (pattern_ptr[0] == ']')
wuliqunyy 0:be95bfb06686 630 && (pattern_ptr[1] == ':')) {
wuliqunyy 0:be95bfb06686 631 SKIP_PATTERN(2); /* for skip ']' in "]:" */
wuliqunyy 0:be95bfb06686 632 SKIP_CMD(1);
wuliqunyy 0:be95bfb06686 633 brackets--;
wuliqunyy 0:be95bfb06686 634 } else if ((pattern_len > 2)
wuliqunyy 0:be95bfb06686 635 && (pattern_ptr[2] == cmd_ptr[0])
wuliqunyy 0:be95bfb06686 636 && (pattern_ptr[0] == ']')
wuliqunyy 0:be95bfb06686 637 && (pattern_ptr[1] == '[')
wuliqunyy 0:be95bfb06686 638 && (pattern_ptr[2] == ':')) {
wuliqunyy 0:be95bfb06686 639 SKIP_PATTERN(3); /* for skip '][' in "][:" */
wuliqunyy 0:be95bfb06686 640 SKIP_CMD(1);
wuliqunyy 0:be95bfb06686 641 /* brackets++; */
wuliqunyy 0:be95bfb06686 642 /* brackets--; */
wuliqunyy 0:be95bfb06686 643 } else {
wuliqunyy 0:be95bfb06686 644 result = FALSE;
wuliqunyy 0:be95bfb06686 645 break;
wuliqunyy 0:be95bfb06686 646 }
wuliqunyy 0:be95bfb06686 647 } else {
wuliqunyy 0:be95bfb06686 648 SKIP_PATTERN(pattern_sep_pos);
wuliqunyy 0:be95bfb06686 649 if ((pattern_ptr[0] == ']') && (pattern_ptr[1] == ':')) {
wuliqunyy 0:be95bfb06686 650 SKIP_PATTERN(2); /* for skip ']' in "]:" , pattern_ptr continue, while cmd_ptr remain unchanged */
wuliqunyy 0:be95bfb06686 651 brackets--;
wuliqunyy 0:be95bfb06686 652 } else if ((pattern_len > 2) && (pattern_ptr[0] == ']')
wuliqunyy 0:be95bfb06686 653 && (pattern_ptr[1] == '[')
wuliqunyy 0:be95bfb06686 654 && (pattern_ptr[2] == ':')) {
wuliqunyy 0:be95bfb06686 655 SKIP_PATTERN(3); /* for skip ']' in "][:" , pattern_ptr continue, while cmd_ptr remain unchanged */
wuliqunyy 0:be95bfb06686 656 /* brackets++; */
wuliqunyy 0:be95bfb06686 657 /* brackets--; */
wuliqunyy 0:be95bfb06686 658 } else {
wuliqunyy 0:be95bfb06686 659 result = FALSE;
wuliqunyy 0:be95bfb06686 660 break;
wuliqunyy 0:be95bfb06686 661 }
wuliqunyy 0:be95bfb06686 662 }
wuliqunyy 0:be95bfb06686 663 }
wuliqunyy 0:be95bfb06686 664
wuliqunyy 0:be95bfb06686 665 return result;
wuliqunyy 0:be95bfb06686 666 #undef SKIP_PATTERN
wuliqunyy 0:be95bfb06686 667 #undef SKIP_CMD
wuliqunyy 0:be95bfb06686 668 }
wuliqunyy 0:be95bfb06686 669
wuliqunyy 0:be95bfb06686 670 /**
wuliqunyy 0:be95bfb06686 671 * Compose command from previous command anc current command
wuliqunyy 0:be95bfb06686 672 *
wuliqunyy 0:be95bfb06686 673 * @param prev pointer to previous command
wuliqunyy 0:be95bfb06686 674 * @param current pointer of current command
wuliqunyy 0:be95bfb06686 675 *
wuliqunyy 0:be95bfb06686 676 * prev and current should be in the same memory buffer
wuliqunyy 0:be95bfb06686 677 */
wuliqunyy 0:be95bfb06686 678 scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) {
wuliqunyy 0:be95bfb06686 679 size_t i;
wuliqunyy 0:be95bfb06686 680
wuliqunyy 0:be95bfb06686 681 /* Invalid input */
wuliqunyy 0:be95bfb06686 682 if (current == NULL || current->ptr == NULL || current->len == 0)
wuliqunyy 0:be95bfb06686 683 return FALSE;
wuliqunyy 0:be95bfb06686 684
wuliqunyy 0:be95bfb06686 685 /* no previous command - nothing to do*/
wuliqunyy 0:be95bfb06686 686 if (prev->ptr == NULL || prev->len == 0)
wuliqunyy 0:be95bfb06686 687 return TRUE;
wuliqunyy 0:be95bfb06686 688
wuliqunyy 0:be95bfb06686 689 /* Common command or command root - nothing to do */
wuliqunyy 0:be95bfb06686 690 if (current->ptr[0] == '*' || current->ptr[0] == ':')
wuliqunyy 0:be95bfb06686 691 return TRUE;
wuliqunyy 0:be95bfb06686 692
wuliqunyy 0:be95bfb06686 693 /* Previsou command was common command - nothing to do */
wuliqunyy 0:be95bfb06686 694 if (prev->ptr[0] == '*')
wuliqunyy 0:be95bfb06686 695 return TRUE;
wuliqunyy 0:be95bfb06686 696
wuliqunyy 0:be95bfb06686 697 /* Find last occurence of ':' */
wuliqunyy 0:be95bfb06686 698 for (i = prev->len; i > 0; i--) {
wuliqunyy 0:be95bfb06686 699 if (prev->ptr[i - 1] == ':') {
wuliqunyy 0:be95bfb06686 700 break;
wuliqunyy 0:be95bfb06686 701 }
wuliqunyy 0:be95bfb06686 702 }
wuliqunyy 0:be95bfb06686 703
wuliqunyy 0:be95bfb06686 704 /* Previous command was simple command - nothing to do*/
wuliqunyy 0:be95bfb06686 705 if (i == 0)
wuliqunyy 0:be95bfb06686 706 return TRUE;
wuliqunyy 0:be95bfb06686 707
wuliqunyy 0:be95bfb06686 708 current->ptr -= i;
wuliqunyy 0:be95bfb06686 709 current->len += i;
wuliqunyy 0:be95bfb06686 710 memmove(current->ptr, prev->ptr, i);
wuliqunyy 0:be95bfb06686 711 return TRUE;
wuliqunyy 0:be95bfb06686 712 }
wuliqunyy 0:be95bfb06686 713
wuliqunyy 0:be95bfb06686 714
wuliqunyy 0:be95bfb06686 715
wuliqunyy 0:be95bfb06686 716 #if !HAVE_STRNLEN
wuliqunyy 0:be95bfb06686 717 /* use FreeBSD strnlen */
wuliqunyy 0:be95bfb06686 718
wuliqunyy 0:be95bfb06686 719 /*-
wuliqunyy 0:be95bfb06686 720 * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
wuliqunyy 0:be95bfb06686 721 * All rights reserved.
wuliqunyy 0:be95bfb06686 722 */
wuliqunyy 0:be95bfb06686 723 size_t
wuliqunyy 0:be95bfb06686 724 BSD_strnlen(const char *s, size_t maxlen) {
wuliqunyy 0:be95bfb06686 725 size_t len;
wuliqunyy 0:be95bfb06686 726
wuliqunyy 0:be95bfb06686 727 for (len = 0; len < maxlen; len++, s++) {
wuliqunyy 0:be95bfb06686 728 if (!*s)
wuliqunyy 0:be95bfb06686 729 break;
wuliqunyy 0:be95bfb06686 730 }
wuliqunyy 0:be95bfb06686 731 return (len);
wuliqunyy 0:be95bfb06686 732 }
wuliqunyy 0:be95bfb06686 733 #endif
wuliqunyy 0:be95bfb06686 734
wuliqunyy 0:be95bfb06686 735 #if !HAVE_STRNCASECMP && !HAVE_STRNICMP
wuliqunyy 0:be95bfb06686 736
wuliqunyy 0:be95bfb06686 737 int OUR_strncasecmp(const char *s1, const char *s2, size_t n) {
wuliqunyy 0:be95bfb06686 738 unsigned char c1, c2;
wuliqunyy 0:be95bfb06686 739
wuliqunyy 0:be95bfb06686 740 for (; n != 0; n--) {
wuliqunyy 0:be95bfb06686 741 c1 = tolower((unsigned char) *s1++);
wuliqunyy 0:be95bfb06686 742 c2 = tolower((unsigned char) *s2++);
wuliqunyy 0:be95bfb06686 743 if (c1 != c2) {
wuliqunyy 0:be95bfb06686 744 return c1 - c2;
wuliqunyy 0:be95bfb06686 745 }
wuliqunyy 0:be95bfb06686 746 if (c1 == '\0') {
wuliqunyy 0:be95bfb06686 747 return 0;
wuliqunyy 0:be95bfb06686 748 }
wuliqunyy 0:be95bfb06686 749 }
wuliqunyy 0:be95bfb06686 750 return 0;
wuliqunyy 0:be95bfb06686 751 }
wuliqunyy 0:be95bfb06686 752 #endif
wuliqunyy 0:be95bfb06686 753
wuliqunyy 0:be95bfb06686 754 #if USE_MEMORY_ALLOCATION_FREE && !HAVE_STRNDUP
wuliqunyy 0:be95bfb06686 755 char *OUR_strndup(const char *s, size_t n) {
wuliqunyy 0:be95bfb06686 756 size_t len = SCPIDEFINE_strnlen(s, n);
wuliqunyy 0:be95bfb06686 757 char * result = malloc(len + 1);
wuliqunyy 0:be95bfb06686 758 if (!result) {
wuliqunyy 0:be95bfb06686 759 return NULL;
wuliqunyy 0:be95bfb06686 760 }
wuliqunyy 0:be95bfb06686 761 memcpy(result, s, len);
wuliqunyy 0:be95bfb06686 762 result[len] = '\0';
wuliqunyy 0:be95bfb06686 763 return result;
wuliqunyy 0:be95bfb06686 764 }
wuliqunyy 0:be95bfb06686 765 #endif
wuliqunyy 0:be95bfb06686 766
wuliqunyy 0:be95bfb06686 767 #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE
wuliqunyy 0:be95bfb06686 768
wuliqunyy 0:be95bfb06686 769 /**
wuliqunyy 0:be95bfb06686 770 * Initialize heap structure
wuliqunyy 0:be95bfb06686 771 * @param heap - pointer to manual allocated heap buffer
wuliqunyy 0:be95bfb06686 772 * @param error_info_heap - buffer for the heap
wuliqunyy 0:be95bfb06686 773 * @param error_info_heap_length - length of the heap
wuliqunyy 0:be95bfb06686 774 */
wuliqunyy 0:be95bfb06686 775 void scpiheap_init(scpi_error_info_heap_t * heap, char * error_info_heap, size_t error_info_heap_length)
wuliqunyy 0:be95bfb06686 776 {
wuliqunyy 0:be95bfb06686 777 heap->data = error_info_heap;
wuliqunyy 0:be95bfb06686 778 heap->wr = 0;
wuliqunyy 0:be95bfb06686 779 heap->size = error_info_heap_length;
wuliqunyy 0:be95bfb06686 780 heap->count = heap->size;
wuliqunyy 0:be95bfb06686 781 memset(heap->data, 0, heap->size);
wuliqunyy 0:be95bfb06686 782 }
wuliqunyy 0:be95bfb06686 783
wuliqunyy 0:be95bfb06686 784 /**
wuliqunyy 0:be95bfb06686 785 * Duplicate string if "strdup" ("malloc/free") not supported on system.
wuliqunyy 0:be95bfb06686 786 * Allocate space in heap if it possible
wuliqunyy 0:be95bfb06686 787 *
wuliqunyy 0:be95bfb06686 788 * @param heap - pointer to manual allocated heap buffer
wuliqunyy 0:be95bfb06686 789 * @param s - current pointer of duplication string
wuliqunyy 0:be95bfb06686 790 * @return - pointer of duplicated string or NULL, if duplicate is not possible.
wuliqunyy 0:be95bfb06686 791 */
wuliqunyy 0:be95bfb06686 792 char * scpiheap_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) {
wuliqunyy 0:be95bfb06686 793 if (!s || !heap || !heap->size) {
wuliqunyy 0:be95bfb06686 794 return NULL;
wuliqunyy 0:be95bfb06686 795 }
wuliqunyy 0:be95bfb06686 796
wuliqunyy 0:be95bfb06686 797 if (heap->data[heap->wr] != '\0') {
wuliqunyy 0:be95bfb06686 798 return NULL;
wuliqunyy 0:be95bfb06686 799 }
wuliqunyy 0:be95bfb06686 800
wuliqunyy 0:be95bfb06686 801 if (*s == '\0') {
wuliqunyy 0:be95bfb06686 802 return NULL;
wuliqunyy 0:be95bfb06686 803 }
wuliqunyy 0:be95bfb06686 804
wuliqunyy 0:be95bfb06686 805 size_t len = SCPIDEFINE_strnlen(s, n) + 1; /* additional '\0' at end */
wuliqunyy 0:be95bfb06686 806 if (len > heap->count) {
wuliqunyy 0:be95bfb06686 807 return NULL;
wuliqunyy 0:be95bfb06686 808 }
wuliqunyy 0:be95bfb06686 809 const char * ptrs = s;
wuliqunyy 0:be95bfb06686 810 char * head = &heap->data[heap->wr];
wuliqunyy 0:be95bfb06686 811 size_t rem = heap->size - (&heap->data[heap->wr] - heap->data);
wuliqunyy 0:be95bfb06686 812
wuliqunyy 0:be95bfb06686 813 if (len >= rem) {
wuliqunyy 0:be95bfb06686 814 memcpy(&heap->data[heap->wr], s, rem);
wuliqunyy 0:be95bfb06686 815 len = len - rem;
wuliqunyy 0:be95bfb06686 816 ptrs += rem;
wuliqunyy 0:be95bfb06686 817 heap->wr = 0;
wuliqunyy 0:be95bfb06686 818 heap->count -= rem;
wuliqunyy 0:be95bfb06686 819 }
wuliqunyy 0:be95bfb06686 820
wuliqunyy 0:be95bfb06686 821 memcpy(&heap->data[heap->wr], ptrs, len);
wuliqunyy 0:be95bfb06686 822 heap->wr += len;
wuliqunyy 0:be95bfb06686 823 heap->count -= len;
wuliqunyy 0:be95bfb06686 824
wuliqunyy 0:be95bfb06686 825 /* ensure '\0' a the end */
wuliqunyy 0:be95bfb06686 826 if (heap->wr > 0) {
wuliqunyy 0:be95bfb06686 827 heap->data[heap->wr - 1] = '\0';
wuliqunyy 0:be95bfb06686 828 } else {
wuliqunyy 0:be95bfb06686 829 heap->data[heap->size - 1] = '\0';
wuliqunyy 0:be95bfb06686 830 }
wuliqunyy 0:be95bfb06686 831 return head;
wuliqunyy 0:be95bfb06686 832 }
wuliqunyy 0:be95bfb06686 833
wuliqunyy 0:be95bfb06686 834 /**
wuliqunyy 0:be95bfb06686 835 * Return pointers and lengths two parts of string in the circular buffer from heap
wuliqunyy 0:be95bfb06686 836 *
wuliqunyy 0:be95bfb06686 837 * @param heap - pointer to manual allocated heap buffer
wuliqunyy 0:be95bfb06686 838 * @param s - pointer of duplicate string.
wuliqunyy 0:be95bfb06686 839 * @return len1 - lenght of first part of string.
wuliqunyy 0:be95bfb06686 840 * @return s2 - pointer of second part of string, if string splited .
wuliqunyy 0:be95bfb06686 841 * @return len2 - lenght of second part of string.
wuliqunyy 0:be95bfb06686 842 */
wuliqunyy 0:be95bfb06686 843 scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap, const char * s, size_t * len1, const char ** s2, size_t * len2) {
wuliqunyy 0:be95bfb06686 844 if (!heap || !s || !len1 || !s2 || !len2) {
wuliqunyy 0:be95bfb06686 845 return FALSE;
wuliqunyy 0:be95bfb06686 846 }
wuliqunyy 0:be95bfb06686 847
wuliqunyy 0:be95bfb06686 848 if (*s == '\0') {
wuliqunyy 0:be95bfb06686 849 return FALSE;
wuliqunyy 0:be95bfb06686 850 }
wuliqunyy 0:be95bfb06686 851
wuliqunyy 0:be95bfb06686 852 *len1 = 0;
wuliqunyy 0:be95bfb06686 853 size_t rem = heap->size - (s - heap->data);
wuliqunyy 0:be95bfb06686 854 *len1 = strnlen(s, rem);
wuliqunyy 0:be95bfb06686 855
wuliqunyy 0:be95bfb06686 856 if (&s[*len1 - 1] == &heap->data[heap->size - 1]) {
wuliqunyy 0:be95bfb06686 857 *s2 = heap->data;
wuliqunyy 0:be95bfb06686 858 *len2 = strnlen(*s2, heap->size);
wuliqunyy 0:be95bfb06686 859 } else {
wuliqunyy 0:be95bfb06686 860 *s2 = NULL;
wuliqunyy 0:be95bfb06686 861 *len2 = 0;
wuliqunyy 0:be95bfb06686 862 }
wuliqunyy 0:be95bfb06686 863 return TRUE;
wuliqunyy 0:be95bfb06686 864 }
wuliqunyy 0:be95bfb06686 865
wuliqunyy 0:be95bfb06686 866 /**
wuliqunyy 0:be95bfb06686 867 * Frees space in heap, if "malloc/free" not supported on system, or nothing.
wuliqunyy 0:be95bfb06686 868 *
wuliqunyy 0:be95bfb06686 869 * @param heap - pointer to manual allocated heap buffer
wuliqunyy 0:be95bfb06686 870 * @param s - pointer of duplicate string
wuliqunyy 0:be95bfb06686 871 * @param rollback - backward write pointer in heap
wuliqunyy 0:be95bfb06686 872 */
wuliqunyy 0:be95bfb06686 873 void scpiheap_free(scpi_error_info_heap_t * heap, char * s, scpi_bool_t rollback) {
wuliqunyy 0:be95bfb06686 874
wuliqunyy 0:be95bfb06686 875 if (!s) return;
wuliqunyy 0:be95bfb06686 876
wuliqunyy 0:be95bfb06686 877 char * data_add;
wuliqunyy 0:be95bfb06686 878 size_t len[2];
wuliqunyy 0:be95bfb06686 879
wuliqunyy 0:be95bfb06686 880 if (!scpiheap_get_parts(heap, s, &len[0], (const char **)&data_add, &len[1])) return;
wuliqunyy 0:be95bfb06686 881
wuliqunyy 0:be95bfb06686 882 if (data_add) {
wuliqunyy 0:be95bfb06686 883 len[1]++;
wuliqunyy 0:be95bfb06686 884 memset(data_add, 0, len[1]);
wuliqunyy 0:be95bfb06686 885 heap->count += len[1];
wuliqunyy 0:be95bfb06686 886 } else {
wuliqunyy 0:be95bfb06686 887 len[0]++;
wuliqunyy 0:be95bfb06686 888 }
wuliqunyy 0:be95bfb06686 889 memset(s, 0, len[0]);
wuliqunyy 0:be95bfb06686 890 heap->count += len[0];
wuliqunyy 0:be95bfb06686 891 if (heap->count == heap->size) {
wuliqunyy 0:be95bfb06686 892 heap->wr = 0;
wuliqunyy 0:be95bfb06686 893 return;
wuliqunyy 0:be95bfb06686 894 }
wuliqunyy 0:be95bfb06686 895 if (rollback) {
wuliqunyy 0:be95bfb06686 896 size_t rb = len[0] + len[1];
wuliqunyy 0:be95bfb06686 897 if (rb > heap->wr) {
wuliqunyy 0:be95bfb06686 898 heap->wr += heap->size;
wuliqunyy 0:be95bfb06686 899 }
wuliqunyy 0:be95bfb06686 900 heap->wr -= rb;
wuliqunyy 0:be95bfb06686 901 }
wuliqunyy 0:be95bfb06686 902 }
wuliqunyy 0:be95bfb06686 903
wuliqunyy 0:be95bfb06686 904 #endif
wuliqunyy 0:be95bfb06686 905
wuliqunyy 0:be95bfb06686 906 /*
wuliqunyy 0:be95bfb06686 907 * Floating point to string conversion routines
wuliqunyy 0:be95bfb06686 908 *
wuliqunyy 0:be95bfb06686 909 * Copyright (C) 2002 Michael Ringgaard. All rights reserved.
wuliqunyy 0:be95bfb06686 910 *
wuliqunyy 0:be95bfb06686 911 * Redistribution and use in source and binary forms, with or without
wuliqunyy 0:be95bfb06686 912 * modification, are permitted provided that the following conditions
wuliqunyy 0:be95bfb06686 913 * are met:
wuliqunyy 0:be95bfb06686 914 *
wuliqunyy 0:be95bfb06686 915 * 1. Redistributions of source code must retain the above copyright
wuliqunyy 0:be95bfb06686 916 * notice, this list of conditions and the following disclaimer.
wuliqunyy 0:be95bfb06686 917 * 2. Redistributions in binary form must reproduce the above copyright
wuliqunyy 0:be95bfb06686 918 * notice, this list of conditions and the following disclaimer in the
wuliqunyy 0:be95bfb06686 919 * documentation and/or other materials provided with the distribution.
wuliqunyy 0:be95bfb06686 920 * 3. Neither the name of the project nor the names of its contributors
wuliqunyy 0:be95bfb06686 921 * may be used to endorse or promote products derived from this software
wuliqunyy 0:be95bfb06686 922 * without specific prior written permission.
wuliqunyy 0:be95bfb06686 923 *
wuliqunyy 0:be95bfb06686 924 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
wuliqunyy 0:be95bfb06686 925 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
wuliqunyy 0:be95bfb06686 926 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
wuliqunyy 0:be95bfb06686 927 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
wuliqunyy 0:be95bfb06686 928 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
wuliqunyy 0:be95bfb06686 929 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
wuliqunyy 0:be95bfb06686 930 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
wuliqunyy 0:be95bfb06686 931 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
wuliqunyy 0:be95bfb06686 932 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
wuliqunyy 0:be95bfb06686 933 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
wuliqunyy 0:be95bfb06686 934 * SUCH DAMAGE.
wuliqunyy 0:be95bfb06686 935 */
wuliqunyy 0:be95bfb06686 936
wuliqunyy 0:be95bfb06686 937 static char *scpi_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf, size_t bufsize) {
wuliqunyy 0:be95bfb06686 938 int r1, r2;
wuliqunyy 0:be95bfb06686 939 double fi, fj;
wuliqunyy 0:be95bfb06686 940 int w1, w2;
wuliqunyy 0:be95bfb06686 941
wuliqunyy 0:be95bfb06686 942 if (ndigits < 0) ndigits = 0;
wuliqunyy 0:be95bfb06686 943 if (ndigits >= (int) (bufsize - 1)) ndigits = bufsize - 2;
wuliqunyy 0:be95bfb06686 944
wuliqunyy 0:be95bfb06686 945 r2 = 0;
wuliqunyy 0:be95bfb06686 946 *sign = 0;
wuliqunyy 0:be95bfb06686 947 w1 = 0;
wuliqunyy 0:be95bfb06686 948 if (arg < 0) {
wuliqunyy 0:be95bfb06686 949 *sign = 1;
wuliqunyy 0:be95bfb06686 950 arg = -arg;
wuliqunyy 0:be95bfb06686 951 }
wuliqunyy 0:be95bfb06686 952 frexp(arg, &r1);
wuliqunyy 0:be95bfb06686 953 arg = modf(arg, &fi);
wuliqunyy 0:be95bfb06686 954
wuliqunyy 0:be95bfb06686 955 if (fi != 0) {
wuliqunyy 0:be95bfb06686 956 r1 = r1 * 308 / 1024 - ndigits;
wuliqunyy 0:be95bfb06686 957 w2 = bufsize;
wuliqunyy 0:be95bfb06686 958 while (r1 > 0) {
wuliqunyy 0:be95bfb06686 959 fj = modf(fi / 10, &fi);
wuliqunyy 0:be95bfb06686 960 r2++;
wuliqunyy 0:be95bfb06686 961 r1--;
wuliqunyy 0:be95bfb06686 962 }
wuliqunyy 0:be95bfb06686 963 while (fi != 0) {
wuliqunyy 0:be95bfb06686 964 fj = modf(fi / 10, &fi);
wuliqunyy 0:be95bfb06686 965 buf[--w2] = (int) ((fj + .03) * 10) + '0';
wuliqunyy 0:be95bfb06686 966 r2++;
wuliqunyy 0:be95bfb06686 967 }
wuliqunyy 0:be95bfb06686 968 while (w2 < (int) bufsize) buf[w1++] = buf[w2++];
wuliqunyy 0:be95bfb06686 969 } else if (arg > 0) {
wuliqunyy 0:be95bfb06686 970 while ((fj = arg * 10) < 1) {
wuliqunyy 0:be95bfb06686 971 arg = fj;
wuliqunyy 0:be95bfb06686 972 r2--;
wuliqunyy 0:be95bfb06686 973 }
wuliqunyy 0:be95bfb06686 974 }
wuliqunyy 0:be95bfb06686 975 w2 = ndigits;
wuliqunyy 0:be95bfb06686 976 *decpt = r2;
wuliqunyy 0:be95bfb06686 977 if (w2 < 0) {
wuliqunyy 0:be95bfb06686 978 buf[0] = '\0';
wuliqunyy 0:be95bfb06686 979 return buf;
wuliqunyy 0:be95bfb06686 980 }
wuliqunyy 0:be95bfb06686 981 while (w1 <= w2 && w1 < (int) bufsize) {
wuliqunyy 0:be95bfb06686 982 arg *= 10;
wuliqunyy 0:be95bfb06686 983 arg = modf(arg, &fj);
wuliqunyy 0:be95bfb06686 984 buf[w1++] = (int) fj + '0';
wuliqunyy 0:be95bfb06686 985 }
wuliqunyy 0:be95bfb06686 986 if (w2 >= (int) bufsize) {
wuliqunyy 0:be95bfb06686 987 buf[bufsize - 1] = '\0';
wuliqunyy 0:be95bfb06686 988 return buf;
wuliqunyy 0:be95bfb06686 989 }
wuliqunyy 0:be95bfb06686 990 w1 = w2;
wuliqunyy 0:be95bfb06686 991 buf[w2] += 5;
wuliqunyy 0:be95bfb06686 992 while (buf[w2] > '9') {
wuliqunyy 0:be95bfb06686 993 buf[w2] = '0';
wuliqunyy 0:be95bfb06686 994 if (w2 > 0) {
wuliqunyy 0:be95bfb06686 995 ++buf[--w2];
wuliqunyy 0:be95bfb06686 996 } else {
wuliqunyy 0:be95bfb06686 997 buf[w2] = '1';
wuliqunyy 0:be95bfb06686 998 (*decpt)++;
wuliqunyy 0:be95bfb06686 999 }
wuliqunyy 0:be95bfb06686 1000 }
wuliqunyy 0:be95bfb06686 1001 buf[w1] = '\0';
wuliqunyy 0:be95bfb06686 1002 return buf;
wuliqunyy 0:be95bfb06686 1003 }
wuliqunyy 0:be95bfb06686 1004
wuliqunyy 0:be95bfb06686 1005 #define SCPI_DTOSTRE_BUFFER_SIZE 32
wuliqunyy 0:be95bfb06686 1006
wuliqunyy 0:be95bfb06686 1007 char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags) {
wuliqunyy 0:be95bfb06686 1008 char buffer[SCPI_DTOSTRE_BUFFER_SIZE];
wuliqunyy 0:be95bfb06686 1009
wuliqunyy 0:be95bfb06686 1010 int sign = SCPIDEFINE_signbit(__val);
wuliqunyy 0:be95bfb06686 1011 char * s = buffer;
wuliqunyy 0:be95bfb06686 1012 int decpt;
wuliqunyy 0:be95bfb06686 1013 if (sign) {
wuliqunyy 0:be95bfb06686 1014 __val = -__val;
wuliqunyy 0:be95bfb06686 1015 s[0] = '-';
wuliqunyy 0:be95bfb06686 1016 s++;
wuliqunyy 0:be95bfb06686 1017 } else if (!SCPIDEFINE_isnan(__val)) {
wuliqunyy 0:be95bfb06686 1018 if (SCPI_DTOSTRE_PLUS_SIGN & __flags) {
wuliqunyy 0:be95bfb06686 1019 s[0] = '+';
wuliqunyy 0:be95bfb06686 1020 s++;
wuliqunyy 0:be95bfb06686 1021 } else if (SCPI_DTOSTRE_ALWAYS_SIGN & __flags) {
wuliqunyy 0:be95bfb06686 1022 s[0] = ' ';
wuliqunyy 0:be95bfb06686 1023 s++;
wuliqunyy 0:be95bfb06686 1024 }
wuliqunyy 0:be95bfb06686 1025 }
wuliqunyy 0:be95bfb06686 1026
wuliqunyy 0:be95bfb06686 1027 if (!SCPIDEFINE_isfinite(__val)) {
wuliqunyy 0:be95bfb06686 1028 if (SCPIDEFINE_isnan(__val)) {
wuliqunyy 0:be95bfb06686 1029 strcpy(s, (__flags & SCPI_DTOSTRE_UPPERCASE) ? "NAN" : "nan");
wuliqunyy 0:be95bfb06686 1030 } else {
wuliqunyy 0:be95bfb06686 1031 strcpy(s, (__flags & SCPI_DTOSTRE_UPPERCASE) ? "INF" : "inf");
wuliqunyy 0:be95bfb06686 1032 }
wuliqunyy 0:be95bfb06686 1033 strncpy(__s, buffer, __ssize);
wuliqunyy 0:be95bfb06686 1034 __s[__ssize - 1] = '\0';
wuliqunyy 0:be95bfb06686 1035 return __s;
wuliqunyy 0:be95bfb06686 1036 }
wuliqunyy 0:be95bfb06686 1037
wuliqunyy 0:be95bfb06686 1038 scpi_ecvt(__val, __prec, &decpt, &sign, s, SCPI_DTOSTRE_BUFFER_SIZE - 1);
wuliqunyy 0:be95bfb06686 1039 if (decpt > 1 && decpt <= __prec) {
wuliqunyy 0:be95bfb06686 1040 memmove(s + decpt + 1, s + decpt, __prec + 1 - decpt);
wuliqunyy 0:be95bfb06686 1041 s[decpt] = '.';
wuliqunyy 0:be95bfb06686 1042 decpt = 0;
wuliqunyy 0:be95bfb06686 1043 } else if (decpt > -4 && decpt <= 0) {
wuliqunyy 0:be95bfb06686 1044 decpt = -decpt + 1;
wuliqunyy 0:be95bfb06686 1045 memmove(s + decpt + 1, s, __prec + 1);
wuliqunyy 0:be95bfb06686 1046 memset(s, '0', decpt + 1);
wuliqunyy 0:be95bfb06686 1047 s[1] = '.';
wuliqunyy 0:be95bfb06686 1048 decpt = 0;
wuliqunyy 0:be95bfb06686 1049 } else {
wuliqunyy 0:be95bfb06686 1050 memmove(s + 2, s + 1, __prec + 1);
wuliqunyy 0:be95bfb06686 1051 s[1] = '.';
wuliqunyy 0:be95bfb06686 1052 decpt--;
wuliqunyy 0:be95bfb06686 1053 }
wuliqunyy 0:be95bfb06686 1054
wuliqunyy 0:be95bfb06686 1055 s = &s[__prec];
wuliqunyy 0:be95bfb06686 1056 while (s[0] == '0') {
wuliqunyy 0:be95bfb06686 1057 s[0] = 0;
wuliqunyy 0:be95bfb06686 1058 s--;
wuliqunyy 0:be95bfb06686 1059 }
wuliqunyy 0:be95bfb06686 1060 if (s[0] == '.') {
wuliqunyy 0:be95bfb06686 1061 s[0] = 0;
wuliqunyy 0:be95bfb06686 1062 s--;
wuliqunyy 0:be95bfb06686 1063 }
wuliqunyy 0:be95bfb06686 1064
wuliqunyy 0:be95bfb06686 1065 if (decpt != 0) {
wuliqunyy 0:be95bfb06686 1066 s++;
wuliqunyy 0:be95bfb06686 1067 s[0] = 'e';
wuliqunyy 0:be95bfb06686 1068 s++;
wuliqunyy 0:be95bfb06686 1069 if (decpt != 0) {
wuliqunyy 0:be95bfb06686 1070 if (decpt > 0) {
wuliqunyy 0:be95bfb06686 1071 s[0] = '+';
wuliqunyy 0:be95bfb06686 1072 }
wuliqunyy 0:be95bfb06686 1073 if (decpt < 0) {
wuliqunyy 0:be95bfb06686 1074 s[0] = '-';
wuliqunyy 0:be95bfb06686 1075 decpt = -decpt;
wuliqunyy 0:be95bfb06686 1076 }
wuliqunyy 0:be95bfb06686 1077 s++;
wuliqunyy 0:be95bfb06686 1078 }
wuliqunyy 0:be95bfb06686 1079 UInt32ToStrBaseSign(decpt, s, 5, 10, 0);
wuliqunyy 0:be95bfb06686 1080 if (s[1] == 0) {
wuliqunyy 0:be95bfb06686 1081 s[2] = s[1];
wuliqunyy 0:be95bfb06686 1082 s[1] = s[0];
wuliqunyy 0:be95bfb06686 1083 s[0] = '0';
wuliqunyy 0:be95bfb06686 1084 }
wuliqunyy 0:be95bfb06686 1085 }
wuliqunyy 0:be95bfb06686 1086
wuliqunyy 0:be95bfb06686 1087 strncpy(__s, buffer, __ssize);
wuliqunyy 0:be95bfb06686 1088 __s[__ssize - 1] = '\0';
wuliqunyy 0:be95bfb06686 1089 return __s;
wuliqunyy 0:be95bfb06686 1090 }
wuliqunyy 0:be95bfb06686 1091
wuliqunyy 0:be95bfb06686 1092 /**
wuliqunyy 0:be95bfb06686 1093 * Get native CPU endiannes
wuliqunyy 0:be95bfb06686 1094 * @return
wuliqunyy 0:be95bfb06686 1095 */
wuliqunyy 0:be95bfb06686 1096 scpi_array_format_t SCPI_GetNativeFormat(void) {
wuliqunyy 0:be95bfb06686 1097
wuliqunyy 0:be95bfb06686 1098 union {
wuliqunyy 0:be95bfb06686 1099 uint32_t i;
wuliqunyy 0:be95bfb06686 1100 char c[4];
wuliqunyy 0:be95bfb06686 1101 } bint = {0x01020304};
wuliqunyy 0:be95bfb06686 1102
wuliqunyy 0:be95bfb06686 1103 return bint.c[0] == 1 ? SCPI_FORMAT_BIGENDIAN : SCPI_FORMAT_LITTLEENDIAN;
wuliqunyy 0:be95bfb06686 1104 }
wuliqunyy 0:be95bfb06686 1105
wuliqunyy 0:be95bfb06686 1106 /**
wuliqunyy 0:be95bfb06686 1107 * Swap 16bit number
wuliqunyy 0:be95bfb06686 1108 * @param val
wuliqunyy 0:be95bfb06686 1109 * @return
wuliqunyy 0:be95bfb06686 1110 */
wuliqunyy 0:be95bfb06686 1111 uint16_t SCPI_Swap16(uint16_t val) {
wuliqunyy 0:be95bfb06686 1112 return ((val & 0x00FF) << 8) |
wuliqunyy 0:be95bfb06686 1113 ((val & 0xFF00) >> 8);
wuliqunyy 0:be95bfb06686 1114 }
wuliqunyy 0:be95bfb06686 1115
wuliqunyy 0:be95bfb06686 1116 /**
wuliqunyy 0:be95bfb06686 1117 * Swap 32bit number
wuliqunyy 0:be95bfb06686 1118 * @param val
wuliqunyy 0:be95bfb06686 1119 * @return
wuliqunyy 0:be95bfb06686 1120 */
wuliqunyy 0:be95bfb06686 1121 uint32_t SCPI_Swap32(uint32_t val) {
wuliqunyy 0:be95bfb06686 1122 return ((val & 0x000000FFul) << 24) |
wuliqunyy 0:be95bfb06686 1123 ((val & 0x0000FF00ul) << 8) |
wuliqunyy 0:be95bfb06686 1124 ((val & 0x00FF0000ul) >> 8) |
wuliqunyy 0:be95bfb06686 1125 ((val & 0xFF000000ul) >> 24);
wuliqunyy 0:be95bfb06686 1126 }
wuliqunyy 0:be95bfb06686 1127
wuliqunyy 0:be95bfb06686 1128 /**
wuliqunyy 0:be95bfb06686 1129 * Swap 64bit number
wuliqunyy 0:be95bfb06686 1130 * @param val
wuliqunyy 0:be95bfb06686 1131 * @return
wuliqunyy 0:be95bfb06686 1132 */
wuliqunyy 0:be95bfb06686 1133 uint64_t SCPI_Swap64(uint64_t val) {
wuliqunyy 0:be95bfb06686 1134 return ((val & 0x00000000000000FFull) << 56) |
wuliqunyy 0:be95bfb06686 1135 ((val & 0x000000000000FF00ull) << 40) |
wuliqunyy 0:be95bfb06686 1136 ((val & 0x0000000000FF0000ull) << 24) |
wuliqunyy 0:be95bfb06686 1137 ((val & 0x00000000FF000000ull) << 8) |
wuliqunyy 0:be95bfb06686 1138 ((val & 0x000000FF00000000ull) >> 8) |
wuliqunyy 0:be95bfb06686 1139 ((val & 0x0000FF0000000000ull) >> 24) |
wuliqunyy 0:be95bfb06686 1140 ((val & 0x00FF000000000000ull) >> 40) |
wuliqunyy 0:be95bfb06686 1141 ((val & 0xFF00000000000000ull) >> 56);
wuliqunyy 0:be95bfb06686 1142 }
wuliqunyy 0:be95bfb06686 1143