59char *
strnpbrk(
const char *str,
size_t size,
const char *set) {
62 const char * strend = str + size;
64 while ((strend != str) && ((c = *str++) != 0)) {
65 for (scanp = set; (sc = *scanp++) !=
'\0';)
67 return ((
char *) (str - 1));
82 const char digits[] =
"0123456789ABCDEF";
84#define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
112 if (sign && ((int32_t) val < 0) && (base == 10)) {
118 while ((uval / x) == 0) {
123 digit = (uint8_t) (uval / x);
127 }
while (x && (pos < len));
130 if (pos < len) str[pos] = 0;
168 const char digits[] =
"0123456789ABCDEF";
170#define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
182 x = 0x8000000000000000ULL;
185 x = 0x8000000000000000ULL;
189 x = 10000000000000000000ULL;
193 x = 0x1000000000000000ULL;
198 if (sign && ((int64_t) val < 0) && (base == 10)) {
204 while ((uval / x) == 0) {
209 digit = (uint8_t) (uval / x);
213 }
while (x && (pos < len));
216 if (pos < len) str[pos] = 0;
276 *val = strtol(str, &endptr, base);
288 *val = strtoul(str, &endptr, base);
336 *val = strtod(str, &endptr);
392 for (i = len1; i < len2; i++) {
393 if (!isdigit((
int) str2[i])) {
412 for (i = 0; i < len; i++) {
413 if (!isspace((
unsigned char) cmd[i])) {
429 for (i = 0; (i < len) && pattern[i]; i++) {
430 if (islower((
unsigned char) pattern[i])) {
445 char * separator =
strnpbrk(pattern, len,
"?:[]");
446 if (separator == NULL) {
449 return separator - pattern;
460 char * separator =
strnpbrk(cmd, len,
":?");
462 if (separator == NULL) {
465 result = separator - cmd;
480 int pattern_sep_pos_short;
482 if ((pattern_len > 0) && pattern[pattern_len - 1] ==
'#') {
483 size_t new_pattern_len = pattern_len - 1;
493 return compareStr(pattern, pattern_len, str, str_len) ||
494 compareStr(pattern, pattern_sep_pos_short, str, str_len);
505scpi_bool_t matchCommand(
const char * pattern,
const char * cmd,
size_t len, int32_t *numbers,
size_t numbers_len, int32_t default_value,
bool *query) {
506#define SKIP_PATTERN(n) do {pattern_ptr += (n); pattern_len -= (n);} while(0)
507#define SKIP_CMD(n) do {cmd_ptr += (n); cmd_len -= (n);} while(0)
513 size_t numbers_idx = 0;
514 int32_t *number_ptr = NULL;
516 const char * pattern_ptr = pattern;
517 int pattern_len = strlen(pattern);
519 const char * cmd_ptr = cmd;
523 if (pattern_ptr[pattern_len - 1] ==
'?') {
524 if (cmd_ptr[cmd_len - 1] ==
'?') {
534 if (pattern_ptr[0] ==
'[') {
538 if (pattern_ptr[0] ==
':') {
542 if (cmd_ptr[0] ==
':') {
545 if (cmd_ptr[1] !=
'*') {
558 if ((pattern_sep_pos > 0) && pattern_ptr[pattern_sep_pos - 1] ==
'#') {
559 if (numbers && (numbers_idx < numbers_len)) {
560 number_ptr = numbers + numbers_idx;
561 *number_ptr = default_value;
570 if (
matchPattern(pattern_ptr, pattern_sep_pos, cmd_ptr, cmd_sep_pos, number_ptr)) {
576 if ((pattern_len == 0) && (cmd_len == 0)) {
581 if ((pattern_len == 0) && (cmd_len > 0)) {
589 while (pattern_len) {
591 switch (pattern_ptr[pattern_sep_pos]) {
603 if ((pattern_len > 0) && (pattern_ptr[0] ==
'[')) {
610 if (pattern_len != 0) {
617 if ((pattern_len > 0)
618 && ((pattern_ptr[0] == cmd_ptr[0])
619 && (pattern_ptr[0] ==
':'))) {
622 }
else if ((pattern_len > 1)
623 && (pattern_ptr[1] == cmd_ptr[0])
624 && (pattern_ptr[0] ==
'[')
625 && (pattern_ptr[1] ==
':')) {
629 }
else if ((pattern_len > 1)
630 && (pattern_ptr[1] == cmd_ptr[0])
631 && (pattern_ptr[0] ==
']')
632 && (pattern_ptr[1] ==
':')) {
636 }
else if ((pattern_len > 2)
637 && (pattern_ptr[2] == cmd_ptr[0])
638 && (pattern_ptr[0] ==
']')
639 && (pattern_ptr[1] ==
'[')
640 && (pattern_ptr[2] ==
':')) {
645 }
else if ((pattern_len > 2)
646 && (pattern_ptr[1] == cmd_ptr[0])
647 && (pattern_ptr[0] ==
'[')
648 && (pattern_ptr[1] ==
'?')
649 && (pattern_ptr[2] ==
']')) {
659 if ((pattern_ptr[0] ==
']') && (pattern_ptr[1] ==
':')) {
662 }
else if ((pattern_len > 2) && (pattern_ptr[0] ==
']')
663 && (pattern_ptr[1] ==
'[')
664 && (pattern_ptr[2] ==
':')) {
692 if (current == NULL || current->ptr == NULL || current->len == 0)
696 if (prev->ptr == NULL || prev->len == 0)
700 if (current->ptr[0] ==
'*' || current->ptr[0] ==
':')
704 if (prev->ptr[0] ==
'*')
708 for (i = prev->len; i > 0; i--) {
709 if (prev->ptr[i - 1] ==
':') {
720 memmove(current->ptr, prev->ptr, i);
737 for (len = 0; len < maxlen; len++, s++) {
745#if !HAVE_STRNCASECMP && !HAVE_STRNICMP
748 unsigned char c1, c2;
750 for (; n != 0; n--) {
751 c1 = tolower((
unsigned char) *s1++);
752 c2 = tolower((
unsigned char) *s2++);
764#if USE_MEMORY_ALLOCATION_FREE && !HAVE_STRNDUP
767 char * result = malloc(len + 1);
771 memcpy(result, s, len);
777#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE
785void scpiheap_init(scpi_error_info_heap_t * heap,
char * error_info_heap,
size_t error_info_heap_length)
787 heap->data = error_info_heap;
789 heap->size = error_info_heap_length;
790 heap->count = heap->size;
791 memset(heap->data, 0, heap->size);
802char * scpiheap_strndup(scpi_error_info_heap_t * heap,
const char *s,
size_t n) {
803 if (!s || !heap || !heap->size) {
807 if (heap->data[heap->wr] !=
'\0') {
816 if (len > heap->count) {
819 const char * ptrs = s;
820 char * head = &heap->data[heap->wr];
821 size_t rem = heap->size - (&heap->data[heap->wr] - heap->data);
824 memcpy(&heap->data[heap->wr], s, rem);
831 memcpy(&heap->data[heap->wr], ptrs, len);
837 heap->data[heap->wr - 1] =
'\0';
839 heap->data[heap->size - 1] =
'\0';
853scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap,
const char * s,
size_t * len1,
const char ** s2,
size_t * len2) {
854 if (!heap || !s || !len1 || !s2 || !len2) {
863 size_t rem = heap->size - (s - heap->data);
864 *len1 = strnlen(s, rem);
866 if (&s[*len1 - 1] == &heap->data[heap->size - 1]) {
868 *len2 = strnlen(*s2, heap->size);
883void scpiheap_free(scpi_error_info_heap_t * heap,
char * s,
scpi_bool_t rollback) {
890 if (!scpiheap_get_parts(heap, s, &len[0], (
const char **)&data_add, &len[1]))
return;
894 memset(data_add, 0, len[1]);
895 heap->count += len[1];
899 memset(s, 0, len[0]);
900 heap->count += len[0];
901 if (heap->count == heap->size) {
906 size_t rb = len[0] + len[1];
908 heap->wr += heap->size;
947static char *
scpi_ecvt(
double arg,
int ndigits,
int *decpt,
int *sign,
char *buf,
size_t bufsize) {
952 if (ndigits < 0) ndigits = 0;
953 if (ndigits >= (
int) (bufsize - 1)) ndigits = bufsize - 2;
963 arg = modf(arg, &fi);
966 r1 = r1 * 308 / 1024 - ndigits;
969 fj = modf(fi / 10, &fi);
974 fj = modf(fi / 10, &fi);
975 buf[--w2] = (int) ((fj + .03) * 10) +
'0';
978 while (w2 < (
int) bufsize) buf[w1++] = buf[w2++];
979 }
else if (arg > 0) {
980 while ((fj = arg * 10) < 1) {
991 while (w1 <= w2 && w1 < (
int) bufsize) {
993 arg = modf(arg, &fj);
994 buf[w1++] = (int) fj +
'0';
996 if (w2 >= (
int) bufsize) {
997 buf[bufsize - 1] =
'\0';
1002 while (buf[w2] >
'9') {
1015#define SCPI_DTOSTRE_BUFFER_SIZE 32
1017char *
SCPI_dtostre(
double __val,
char * __s,
size_t __ssize,
unsigned char __prec,
unsigned char __flags) {
1043 strncpy(__s, buffer, __ssize);
1044 __s[__ssize - 1] =
'\0';
1049 if (decpt > 1 && decpt <= __prec) {
1050 memmove(s + decpt + 1, s + decpt, __prec + 1 - decpt);
1053 }
else if (decpt > -4 && decpt <= 0) {
1055 memmove(s + decpt + 1, s, __prec + 1);
1056 memset(s,
'0', decpt + 1);
1060 memmove(s + 2, s + 1, __prec + 1);
1066 while (s[0] ==
'0') {
1097 strncpy(__s, buffer, __ssize);
1098 __s[__ssize - 1] =
'\0';
1111 } bint = {0x01020304};
1122 return ((val & 0x00FF) << 8) |
1123 ((val & 0xFF00) >> 8);
1132 return ((val & 0x000000FFul) << 24) |
1133 ((val & 0x0000FF00ul) << 8) |
1134 ((val & 0x00FF0000ul) >> 8) |
1135 ((val & 0xFF000000ul) >> 24);
1144 return ((val & 0x00000000000000FFull) << 56) |
1145 ((val & 0x000000000000FF00ull) << 40) |
1146 ((val & 0x0000000000FF0000ull) << 24) |
1147 ((val & 0x00000000FF000000ull) << 8) |
1148 ((val & 0x000000FF00000000ull) >> 8) |
1149 ((val & 0x0000FF0000000000ull) >> 24) |
1150 ((val & 0x00FF000000000000ull) >> 40) |
1151 ((val & 0xFF00000000000000ull) >> 56);
#define SCPIDEFINE_isfinite(n)
#define SCPIDEFINE_strtof(n, p)
#define SCPIDEFINE_strtoull(n, p, b)
#define SCPIDEFINE_floatToStr(v, s, l)
#define SCPIDEFINE_strnlen(s, l)
#define SCPIDEFINE_signbit(n)
#define SCPIDEFINE_strncasecmp(s1, s2, l)
#define SCPIDEFINE_doubleToStr(v, s, l)
#define SCPIDEFINE_isnan(n)
#define SCPIDEFINE_strtoll(n, p, b)
enum _scpi_array_format_t scpi_array_format_t
@ SCPI_FORMAT_LITTLEENDIAN
uint64_t SCPI_Swap64(uint64_t val)
char * SCPI_dtostre(double __val, char *__s, size_t __ssize, unsigned char __prec, unsigned char __flags)
char * strnpbrk(const char *str, size_t size, const char *set)
size_t SCPI_Int64ToStr(int64_t val, char *str, size_t len)
size_t skipWhitespace(const char *cmd, size_t len)
size_t SCPI_FloatToStr(float val, char *str, size_t len)
scpi_bool_t compareStrAndNum(const char *str1, size_t len1, const char *str2, size_t len2, int32_t *num)
size_t SCPI_UInt32ToStrBase(uint32_t val, char *str, size_t len, int8_t base)
size_t SCPI_UInt64ToStrBase(uint64_t val, char *str, size_t len, int8_t base)
scpi_bool_t matchPattern(const char *pattern, size_t pattern_len, const char *str, size_t str_len, int32_t *num)
size_t UInt64ToStrBaseSign(uint64_t val, char *str, size_t len, int8_t base, scpi_bool_t sign)
size_t SCPI_Int32ToStr(int32_t val, char *str, size_t len)
uint32_t SCPI_Swap32(uint32_t val)
size_t strToDouble(const char *str, double *val)
size_t strBaseToUInt64(const char *str, uint64_t *val, int8_t base)
#define SCPI_DTOSTRE_BUFFER_SIZE
static size_t patternSeparatorPos(const char *pattern, size_t len)
static char * scpi_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf, size_t bufsize)
static size_t cmdSeparatorPos(const char *cmd, size_t len)
scpi_bool_t matchCommand(const char *pattern, const char *cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value, bool *query)
size_t strBaseToUInt32(const char *str, uint32_t *val, int8_t base)
scpi_bool_t composeCompoundCommand(const scpi_token_t *prev, scpi_token_t *current)
scpi_array_format_t SCPI_GetNativeFormat(void)
size_t SCPI_DoubleToStr(double val, char *str, size_t len)
size_t strBaseToInt64(const char *str, int64_t *val, int8_t base)
scpi_bool_t compareStr(const char *str1, size_t len1, const char *str2, size_t len2)
size_t strBaseToInt32(const char *str, int32_t *val, int8_t base)
size_t BSD_strnlen(const char *s, size_t maxlen)
int OUR_strncasecmp(const char *s1, const char *s2, size_t n)
size_t strToFloat(const char *str, float *val)
static size_t patternSeparatorShortPos(const char *pattern, size_t len)
uint16_t SCPI_Swap16(uint16_t val)
size_t UInt32ToStrBaseSign(uint32_t val, char *str, size_t len, int8_t base, scpi_bool_t sign)
Conversion routines and string manipulation routines.
#define SCPI_DTOSTRE_PLUS_SIGN
#define SCPI_DTOSTRE_UPPERCASE
#define SCPI_DTOSTRE_ALWAYS_SIGN
char * OUR_strndup(const char *s, size_t n)