From 11f2f2e329ef404d0e9c022cb2f9fbbb45bae285 Mon Sep 17 00:00:00 2001 From: nancy.liao <huihui.liao@greentest.com.cn> Date: 周日, 27 4月 2025 17:33:31 +0800 Subject: [PATCH] 完成了SCPI命令语法分析器的完整规则 --- libscpi/src/utils.c | 310 +++++++++++++++++++++++++++------------------------ 1 files changed, 166 insertions(+), 144 deletions(-) diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index cb34cc7..17d057c 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1,30 +1,29 @@ /*- - * Copyright (c) 2013 Jan Breuer - * Richard.hmm - * Copyright (c) 2012 Jan Breuer + * BSD 2-Clause License * - * All Rights Reserved + * Copyright (c) 2012-2018, Jan Breuer, Richard.hmm + * All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * modification, are permitted provided that the following conditions are met: * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -41,7 +40,6 @@ #include <string.h> #include <ctype.h> #include <math.h> - #include "utils_private.h" #include "scpi/utils.h" @@ -92,29 +90,29 @@ } else { switch (base) { - case 2: - x = 0x80000000L; - break; - case 8: - x = 0x40000000L; - break; - default: - case 10: - base = 10; - x = 1000000000L; - break; - case 16: - x = 0x10000000L; - break; + case 2: + x = 0x80000000L; + break; + case 8: + x = 0x40000000L; + break; + default: + case 10: + base = 10; + x = 1000000000L; + break; + case 16: + x = 0x10000000L; + break; } - // add sign for numbers in base 10 + /* add sign for numbers in base 10 */ if (sign && ((int32_t) val < 0) && (base == 10)) { uval = -val; ADD_CHAR('-'); } - // remove leading zeros + /* remove leading zeros */ while ((uval / x) == 0) { x /= base; } @@ -178,29 +176,29 @@ } else { switch (base) { - case 2: - x = 0x8000000000000000ULL; - break; - case 8: - x = 0x8000000000000000ULL; - break; - default: - case 10: - x = 10000000000000000000ULL; - base = 10; - break; - case 16: - x = 0x1000000000000000ULL; - break; + case 2: + x = 0x8000000000000000ULL; + break; + case 8: + x = 0x8000000000000000ULL; + break; + default: + case 10: + x = 10000000000000000000ULL; + base = 10; + break; + case 16: + x = 0x1000000000000000ULL; + break; } - // add sign for numbers in base 10 + /* add sign for numbers in base 10 */ if (sign && ((int64_t) val < 0) && (base == 10)) { uval = -val; ADD_CHAR('-'); } - // remove leading zeros + /* remove leading zeros */ while ((uval / x) == 0) { x /= base; } @@ -249,7 +247,8 @@ * @return number of bytes written to str (without '\0') */ size_t SCPI_FloatToStr(float val, char * str, size_t len) { - return SCPIDEFINE_floatToStr(val, str, len); + SCPIDEFINE_floatToStr(val, str, len); + return strlen(str); } /** @@ -260,7 +259,8 @@ * @return number of bytes written to str (without '\0') */ size_t SCPI_DoubleToStr(double val, char * str, size_t len) { - return SCPIDEFINE_doubleToStr(val, str, len); + SCPIDEFINE_doubleToStr(val, str, len); + return strlen(str); } /** @@ -295,7 +295,7 @@ */ size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) { char * endptr; - *val = strtoll(str, &endptr, base); + *val = SCPIDEFINE_strtoll(str, &endptr, base); return endptr - str; } @@ -307,7 +307,7 @@ */ size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) { char * endptr; - *val = strtoull(str, &endptr, base); + *val = SCPIDEFINE_strtoull(str, &endptr, base); return endptr - str; } @@ -319,7 +319,7 @@ */ size_t strToFloat(const char * str, float * val) { char * endptr; - *val = strtof(str, &endptr); + *val = SCPIDEFINE_strtof(str, &endptr); return endptr - str; } @@ -376,7 +376,7 @@ if (num) { if (len1 == len2) { - //*num = 1; + /* *num = 1; */ } else { int32_t tmpNum; i = len1 + strBaseToInt32(str2 + len1, &tmpNum, 10); @@ -483,13 +483,13 @@ pattern_sep_pos_short = patternSeparatorShortPos(pattern, new_pattern_len); return compareStrAndNum(pattern, new_pattern_len, str, str_len, num) || - compareStrAndNum(pattern, pattern_sep_pos_short, str, str_len, num); + compareStrAndNum(pattern, pattern_sep_pos_short, str, str_len, num); } else { pattern_sep_pos_short = patternSeparatorShortPos(pattern, pattern_len); return compareStr(pattern, pattern_len, str, str_len) || - compareStr(pattern, pattern_sep_pos_short, str, str_len); + compareStr(pattern, pattern_sep_pos_short, str, str_len); } } @@ -528,11 +528,11 @@ } /* now support optional keywords in pattern style, e.g. [:MEASure]:VOLTage:DC? */ - if (pattern_ptr[0] == '[') { // skip first '[' + if (pattern_ptr[0] == '[') { /* skip first '[' */ SKIP_PATTERN(1); brackets++; } - if (pattern_ptr[0] == ':') { // skip first ':' + if (pattern_ptr[0] == ':') { /* skip first ':' */ SKIP_PATTERN(1); } @@ -555,7 +555,7 @@ if ((pattern_sep_pos > 0) && pattern_ptr[pattern_sep_pos - 1] == '#') { if (numbers && (numbers_idx < numbers_len)) { number_ptr = numbers + numbers_idx; - *number_ptr = default_value; // default value + *number_ptr = default_value; /* default value */ } else { number_ptr = NULL; } @@ -582,18 +582,18 @@ /* command complete, but pattern not */ if (cmd_len == 0) { - // verify all subsequent pattern parts are also optional + /* verify all subsequent pattern parts are also optional */ while (pattern_len) { pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_len); switch (pattern_ptr[pattern_sep_pos]) { - case '[': - brackets++; - break; - case ']': - brackets--; - break; - default: - break; + case '[': + brackets++; + break; + case ']': + brackets--; + break; + default: + break; } SKIP_PATTERN(pattern_sep_pos + 1); if (brackets == 0) { @@ -612,33 +612,33 @@ /* both command and patter contains command separator at this position */ if ((pattern_len > 0) - && ((pattern_ptr[0] == cmd_ptr[0]) + && ((pattern_ptr[0] == cmd_ptr[0]) && (pattern_ptr[0] == ':'))) { SKIP_PATTERN(1); SKIP_CMD(1); } else if ((pattern_len > 1) - && (pattern_ptr[1] == cmd_ptr[0]) - && (pattern_ptr[0] == '[') - && (pattern_ptr[1] == ':')) { - SKIP_PATTERN(2); // for skip '[' in "[:" + && (pattern_ptr[1] == cmd_ptr[0]) + && (pattern_ptr[0] == '[') + && (pattern_ptr[1] == ':')) { + SKIP_PATTERN(2); /* for skip '[' in "[:" */ SKIP_CMD(1); brackets++; } else if ((pattern_len > 1) - && (pattern_ptr[1] == cmd_ptr[0]) - && (pattern_ptr[0] == ']') - && (pattern_ptr[1] == ':')) { - SKIP_PATTERN(2); // for skip ']' in "]:" + && (pattern_ptr[1] == cmd_ptr[0]) + && (pattern_ptr[0] == ']') + && (pattern_ptr[1] == ':')) { + SKIP_PATTERN(2); /* for skip ']' in "]:" */ SKIP_CMD(1); brackets--; } else if ((pattern_len > 2) - && (pattern_ptr[2] == cmd_ptr[0]) - && (pattern_ptr[0] == ']') - && (pattern_ptr[1] == '[') - && (pattern_ptr[2] == ':')) { - SKIP_PATTERN(3); // for skip '][' in "][:" + && (pattern_ptr[2] == cmd_ptr[0]) + && (pattern_ptr[0] == ']') + && (pattern_ptr[1] == '[') + && (pattern_ptr[2] == ':')) { + SKIP_PATTERN(3); /* for skip '][' in "][:" */ SKIP_CMD(1); - //brackets++; - //brackets--; + /* brackets++; */ + /* brackets--; */ } else { result = FALSE; break; @@ -646,14 +646,14 @@ } else { SKIP_PATTERN(pattern_sep_pos); if ((pattern_ptr[0] == ']') && (pattern_ptr[1] == ':')) { - SKIP_PATTERN(2); // for skip ']' in "]:" , pattern_ptr continue, while cmd_ptr remain unchanged + SKIP_PATTERN(2); /* for skip ']' in "]:" , pattern_ptr continue, while cmd_ptr remain unchanged */ brackets--; } else if ((pattern_len > 2) && (pattern_ptr[0] == ']') - && (pattern_ptr[1] == '[') - && (pattern_ptr[2] == ':')) { - SKIP_PATTERN(3); // for skip ']' in "][:" , pattern_ptr continue, while cmd_ptr remain unchanged - //brackets++; - //brackets--; + && (pattern_ptr[1] == '[') + && (pattern_ptr[2] == ':')) { + SKIP_PATTERN(3); /* for skip ']' in "][:" , pattern_ptr continue, while cmd_ptr remain unchanged */ + /* brackets++; */ + /* brackets--; */ } else { result = FALSE; break; @@ -674,6 +674,8 @@ * * prev and current should be in the same memory buffer */ + +//缁勫悎澶嶅悎SCPI鍛戒护 scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) { size_t i; @@ -686,6 +688,7 @@ return TRUE; /* Common command or command root - nothing to do */ + // 褰撳墠鍛戒护鏄叕鍏卞懡浠�(*)鎴栨牴鍛戒护(:) if (current->ptr[0] == '*' || current->ptr[0] == ':') return TRUE; @@ -706,6 +709,7 @@ current->ptr -= i; current->len += i; + //澶嶅悎鍛戒护缁勫悎 memmove(current->ptr, prev->ptr, i); return TRUE; } @@ -750,6 +754,20 @@ } #endif +#if USE_MEMORY_ALLOCATION_FREE && !HAVE_STRNDUP +char *OUR_strndup(const char *s, size_t n) { + size_t len = SCPIDEFINE_strnlen(s, n); + //msvc涓嬮渶瑕佸己杞� + char * result =(char*) malloc(len + 1); + if (!result) { + return NULL; + } + memcpy(result, s, len); + result[len] = '\0'; + return result; +} +#endif + #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE /** @@ -788,7 +806,7 @@ return NULL; } - size_t len = SCPIDEFINE_strnlen(s, n) + 1; // additional '\0' at end + size_t len = SCPIDEFINE_strnlen(s, n) + 1; /* additional '\0' at end */ if (len > heap->count) { return NULL; } @@ -808,7 +826,7 @@ heap->wr += len; heap->count -= len; - // ensure '\0' a the end + /* ensure '\0' a the end */ if (heap->wr > 0) { heap->data[heap->wr - 1] = '\0'; } else { @@ -889,34 +907,36 @@ #endif -// Floating point to string conversion routines -// -// Copyright (C) 2002 Michael Ringgaard. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. Neither the name of the project nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. +/* + * Floating point to string conversion routines + * + * Copyright (C) 2002 Michael Ringgaard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ static char *scpi_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf, size_t bufsize) { int r1, r2; @@ -991,14 +1011,14 @@ char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags) { char buffer[SCPI_DTOSTRE_BUFFER_SIZE]; - int sign = signbit(__val); + int sign = SCPIDEFINE_signbit(__val); char * s = buffer; int decpt; if (sign) { __val = -__val; s[0] = '-'; s++; - } else if (!isnan(__val)) { + } else if (!SCPIDEFINE_isnan(__val)) { if (SCPI_DTOSTRE_PLUS_SIGN & __flags) { s[0] = '+'; s++; @@ -1008,13 +1028,14 @@ } } - if (!isfinite(__val)) { - if (isnan(__val)) { + if (!SCPIDEFINE_isfinite(__val)) { + if (SCPIDEFINE_isnan(__val)) { strcpy(s, (__flags & SCPI_DTOSTRE_UPPERCASE) ? "NAN" : "nan"); } else { strcpy(s, (__flags & SCPI_DTOSTRE_UPPERCASE) ? "INF" : "inf"); } strncpy(__s, buffer, __ssize); + __s[__ssize - 1] = '\0'; return __s; } @@ -1068,6 +1089,7 @@ } strncpy(__s, buffer, __ssize); + __s[__ssize - 1] = '\0'; return __s; } @@ -1092,7 +1114,7 @@ */ uint16_t SCPI_Swap16(uint16_t val) { return ((val & 0x00FF) << 8) | - ((val & 0xFF00) >> 8); + ((val & 0xFF00) >> 8); } /** @@ -1101,10 +1123,10 @@ * @return */ uint32_t SCPI_Swap32(uint32_t val) { - return ((val & 0x000000FF) << 24) | - ((val & 0x0000FF00) << 8) | - ((val & 0x00FF0000) >> 8) | - ((val & 0xFF000000) >> 24); + return ((val & 0x000000FFul) << 24) | + ((val & 0x0000FF00ul) << 8) | + ((val & 0x00FF0000ul) >> 8) | + ((val & 0xFF000000ul) >> 24); } /** @@ -1113,12 +1135,12 @@ * @return */ uint64_t SCPI_Swap64(uint64_t val) { - return ((val & 0x00000000000000FFul) << 56) | - ((val & 0x000000000000FF00ul) << 40) | - ((val & 0x0000000000FF0000ul) << 24) | - ((val & 0x00000000FF000000ul) << 8) | - ((val & 0x000000FF00000000ul) >> 8) | - ((val & 0x0000FF0000000000ul) >> 24) | - ((val & 0x00FF000000000000ul) >> 40) | - ((val & 0xFF00000000000000ul) >> 56); + return ((val & 0x00000000000000FFull) << 56) | + ((val & 0x000000000000FF00ull) << 40) | + ((val & 0x0000000000FF0000ull) << 24) | + ((val & 0x00000000FF000000ull) << 8) | + ((val & 0x000000FF00000000ull) >> 8) | + ((val & 0x0000FF0000000000ull) >> 24) | + ((val & 0x00FF000000000000ull) >> 40) | + ((val & 0xFF00000000000000ull) >> 56); } -- Gitblit v1.9.1