• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SRI-CSL / yices2 / 12806881170

16 Jan 2025 10:25AM UTC coverage: 65.284%. Remained the same
12806881170

Pull #550

github

web-flow
Merge 2bec93334 into fda0a325e
Pull Request #550: Fix binary_search_string and assert in test_api8

4 of 5 new or added lines in 1 file covered. (80.0%)

23 existing lines in 1 file now uncovered.

81021 of 124106 relevant lines covered (65.28%)

1509942.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

31.82
/src/utils/string_utils.c
1
/*
2
 * This file is part of the Yices SMT Solver.
3
 * Copyright (C) 2017 SRI International.
4
 *
5
 * Yices is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * Yices is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with Yices.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
/*
20
 * UTILITIES TO PARSE STRINGS
21
 */
22

23
#include <stdlib.h>
24
#include <string.h>
25
#include <ctype.h>
26
#include <errno.h>
27
#include <assert.h>
28

29
#include "utils/string_utils.h"
30

31

32
/*
33
 * Binary search in a sorted array of strings.
34
 * - a must be sorted in lexicographic order (i.e.,
35
 *   strcmp(a[i], a[i+1]) must be non-negative).
36
 * - n = size of the array. n must be > 0
37
 * - s = string to search for
38
 *
39
 * Return the index i such that a[i] = s if s is in the array.
40
 * Return -1 otherwise.
41
 */
42
int32_t binary_search_string(const char *s, const char * const *a, int32_t n) {
35✔
43
  int32_t l, h, k;
44
  int cmp;
45

46
  l = 0;
35✔
47
  h = n - 1;
35✔
48
  while (l <= h) {
165✔
49
    k = (l + h)/2;
165✔
50
    assert(l <= k && k <= h);
51
    cmp = strcmp(s, a[k]);
165✔
52
    if (cmp == 0) return k;
165✔
53
    if (cmp < 0) {
130✔
54
      h = k - 1;
69✔
55
    } else {
56
      assert(cmp > 0);
57
      l = k + 1;
61✔
58
    }
59
  }
NEW
UNCOV
60
  return -1;
×
61
}
62

63

64
/*
65
 * Parse s as a keyword:
66
 * - a must be an array of strings sorted in lexicographic order
67
 * - b must be an array of integer codes of same size as a
68
 * - n = size of a and b (n must be positive)
69
 * - s = string to search for
70
 * If s is equal to a[i] for some i in 0 .. n-1, then
71
 * the function returns b[i].
72
 *
73
 * Otherwise, return -1.
74
 */
UNCOV
75
int32_t parse_as_keyword(const char *s, const char * const *a, const int32_t *b, int32_t n) {
×
76
  int32_t i;
77

UNCOV
78
  i = binary_search_string(s, a, n);
×
79
  if (i >= 0) {
×
80
    i = b[i];
×
81
  }
82

UNCOV
83
  return i;
×
84
}
85

86

87
/*
88
 * Parse s as a boolean: "true" or "TRUE" or "false" or "FALSE"
89
 * - store the result in *val
90
 * Return code:
91
 * - valid_boolean means correct
92
 * - invalid_boolean means wrong format
93
 */
UNCOV
94
boolean_parse_code_t parse_as_boolean(const char *s, bool *val) {
×
95
  boolean_parse_code_t r;
96

UNCOV
97
  r = invalid_boolean;
×
98
  if ((strcmp(s, "true") == 0) || (strcmp(s, "TRUE") == 0)) {
×
99
    *val = true;
×
100
    r = valid_boolean;
×
101
  } else if ((strcmp(s, "false") == 0) || (strcmp(s, "FALSE") == 0)) {
×
102
    *val = false;
×
103
    r = valid_boolean;
×
104
  }
105

UNCOV
106
  return r;
×
107
}
108

109

110

111
/*
112
 * Parse s as a decimal number in the format
113
 *  <optional_signs><digits>
114
 * and store the corresponding number into val
115
 *
116
 * Return code:
117
 * - valid_integer means correct format, no overflow
118
 * - integer_overflow means correct format but overflow
119
 * - invalid_integer means wrong format
120
 */
121
integer_parse_code_t parse_as_integer(const char *s, int32_t *val) {
1✔
122
  long aux;
123
  char *b;
124

125
  while (isspace((int) *s)) s ++;
1✔
126
  errno = 0;
1✔
127
  aux = strtol(s, &b, 10);
1✔
128
  if (errno == ERANGE) {
1✔
UNCOV
129
    return integer_overflow;  //overflow or underflow
×
130
  }
131
  if (errno == EINVAL) {
1✔
UNCOV
132
    return invalid_integer;
×
133
  }
134

135
  if (aux > (long) INT32_MAX || aux < (long) INT32_MIN) {
1✔
UNCOV
136
    return integer_overflow;
×
137
  }
138

139
  while (isspace((int) *b)) b++;
1✔
140

141
  if (*b == '\0' && b != s) {
1✔
142
    *val = (int32_t) aux;
1✔
143
    return valid_integer;
1✔
144
  }
145

UNCOV
146
  return invalid_integer;
×
147
}
148

149

150
/*
151
 * Variant: parse s as an unsigned integer
152
 */
UNCOV
153
integer_parse_code_t parse_as_uint(const char *s, uint32_t *val) {
×
154
  unsigned long aux;
155
  char *b;
156

UNCOV
157
  while (isspace((int) *s)) s ++;
×
158
  errno = 0;
×
159
  aux = strtoul(s, &b, 0);
×
160
  if (errno == ERANGE) {
×
161
    return integer_overflow;
×
162
  }
UNCOV
163
  if (errno == EINVAL) {
×
164
    return invalid_integer;
×
165
  }
166

UNCOV
167
  if (aux > (unsigned long) UINT32_MAX) {
×
168
    return integer_overflow;
×
169
  }
170

UNCOV
171
  while (isspace((int) *b)) b++;
×
172

UNCOV
173
  if (*b == '\0' && b != s) {
×
174
    *val = (uint32_t) aux;
×
175
    return valid_integer;
×
176
  }
177

UNCOV
178
  return invalid_integer;
×
179
}
180

181

182
/*
183
 * Parse s as a floating point number in the format recognized by
184
 * strtod, and store the corresponding number into val
185
 *
186
 * Return code:
187
 * - valid_double means correct format, no overflow
188
 * - double_overflow means correct format but overflow
189
 * - invalid_double means wrong format
190
 */
UNCOV
191
double_parse_code_t parse_as_double(const char *s, double *val) {
×
192
  double aux;
193
  char *b;
194

UNCOV
195
  while (isspace((int) *s)) s ++;
×
196
  errno = 0;
×
197
  aux = strtod(s, &b);
×
198
  if (errno == ERANGE) {
×
199
    return double_overflow;  //overflow or underflow
×
200
  }
201

UNCOV
202
  while (isspace((int) *b)) b++;
×
203

UNCOV
204
  if (*b == '\0' && b != s) {
×
205
    *val = aux;
×
206
    return valid_double;
×
207
  }
208

UNCOV
209
  return invalid_double;
×
210
}
211

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc