Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
libscpi/src/utils.c@0:be95bfb06686, 2022-01-17 (annotated)
- 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?
| User | Revision | Line number | New 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 |
