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

SRI-CSL / yices2 / 16032530443

02 Jul 2025 06:08PM UTC coverage: 60.349% (-5.0%) from 65.357%
16032530443

Pull #582

github

web-flow
Merge b7e09d316 into b3af64ab1
Pull Request #582: Update ci

63716 of 105580 relevant lines covered (60.35%)

1127640.75 hits per line

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

35.29
/src/io/reader.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
 * File reader: keeps track of filename, position, current character.
21
 * String reader: same thing but reads from a null-terminated string.
22
 */
23

24
#if 0
25
#define _GNU_SOURCE
26
#include <wchar.h>
27
#endif
28

29
#include <stdbool.h>
30
#include <assert.h>
31

32
#include "io/reader.h"
33

34

35

36
/*
37
 * It seems that we need an explicit declaration of getc_unlocked on
38
 * Solaris (to avoid a compilation warning). Not sure whether this
39
 * is required on all Solaris versions?
40
 */
41
#if defined(SOLARIS)
42
extern int getc_unlocked(FILE *);
43
#endif
44

45

46
/*
47
 * Read and return the next char from a stream reader
48
 * - update pos, line, column
49
 */
50
static int file_reader_next_char(reader_t *reader) {
14,486,884✔
51
  assert(reader->is_stream);
52

53
  if (reader->current == EOF) {
14,486,884✔
54
    return EOF;
×
55
  }
56

57
  if (reader->current == '\n') {
14,486,884✔
58
    reader->line ++;
244,254✔
59
    reader->column = 0;
244,254✔
60
  }
61

62
  // getc_unlocked is unsafe in multithreading applications
63
  // but it's much faster.
64
#if defined(MINGW)
65
  reader->current = getc(reader->input.stream);
66
#else
67
  reader->current = getc_unlocked(reader->input.stream);
14,486,884✔
68
#endif
69
  reader->pos ++;
14,486,884✔
70
  reader->column ++;
14,486,884✔
71

72
  return reader->current;
14,486,884✔
73
}
74

75

76

77
/*
78
 * Read and return the next char from a string reader
79
 * - update pos, line, column
80
 */
81
static int string_reader_next_char(reader_t *reader) {
×
82
  char c;
83

84
  assert(! reader->is_stream);
85

86
  if (reader->current == EOF) {
×
87
    return EOF;
×
88
  }
89

90
  if (reader->current == '\n') {
×
91
    reader->line ++;
×
92
    reader->column = 0;
×
93
  }
94

95
  c = reader->input.data[reader->pos];
×
96
  reader->current = c;
×
97
  if (c == '\0') {
×
98
    reader->current = EOF;
×
99
  }
100
  reader->pos ++;
×
101
  reader->column ++;
×
102

103
  return reader->current;
×
104
}
105

106

107

108

109

110
/*
111
 * Initialize reader for file of the given name
112
 * - return -1 if the file could not be open
113
 *   or 0 otherwise
114
 * - if the file can't be opened, current is set to EOF,
115
 *   any subsequent attempt to read will return EOF
116
 * - if the file can be opened, current is set to '\n'
117
 */
118
int32_t init_file_reader(reader_t *reader, const char *filename) {
1,010✔
119
  FILE *f;
120

121
  f = fopen(filename, "r");
1,010✔
122
  reader->input.stream = f; // keep it NULL if there's an error
1,010✔
123
  reader->pos = 0;
1,010✔
124
  reader->line = 0;
1,010✔
125
  reader->column = 1;
1,010✔
126
  reader->is_stream = true;
1,010✔
127
  reader->read = file_reader_next_char;
1,010✔
128
  reader->name = filename;
1,010✔
129

130
  if (f == NULL) {
1,010✔
131
    reader->current = EOF;
×
132
    return -1;
×
133
  }
134

135
  reader->current = '\n';
1,010✔
136
  return 0;
1,010✔
137
}
138

139
/*
140
 * Initialize reader for an already opened stream
141
 * - set filename to name
142
 */
143
void init_stream_reader(reader_t *reader, FILE *f, const char *name) {
×
144
  reader->current = '\n';
×
145
  reader->input.stream = f;
×
146
  reader->pos = 0;
×
147
  reader->line = 0;
×
148
  reader->column = 1;
×
149
  reader->is_stream = true;
×
150
  reader->read = file_reader_next_char;
×
151
  reader->name = name;
×
152
}
×
153

154

155
/*
156
 * Initialize reader for string data
157
 */
158
void init_string_reader(reader_t *reader, const char *data, const char *name) {
×
159
  reader->current = '\n';
×
160
  reader->input.data = data;
×
161
  reader->pos = 0;
×
162
  reader->line = 0;
×
163
  reader->column = 1;
×
164
  reader->is_stream = false;
×
165
  reader->read = string_reader_next_char;
×
166
  reader->name = name;
×
167
}
×
168

169

170
/*
171
 * Reset: change the input string
172
 */
173
void reset_string_reader(reader_t *reader, const char *data) {
×
174
  assert(! reader->is_stream);
175
  assert(reader->read == string_reader_next_char);
176

177
  reader->current = '\n';
×
178
  reader->input.data = data;
×
179
  reader->pos = 0;
×
180
  reader->line = 0;
×
181
  reader->column = 1;
×
182
}
×
183

184

185

186
/*
187
 * Close reader: return EOF on error, 0 otherwise
188
 */
189
int close_reader(reader_t *reader) {
1,010✔
190
  if (reader->is_stream) {
1,010✔
191
    return fclose(reader->input.stream);
1,010✔
192
  } else {
193
    return 0;
×
194
  }
195
}
196

197

198
#if 0
199
/*
200
 * Experimental variant: use wide characters
201
 * (we assume UTF-8 encoding)
202
 *
203
 * We assume that int is large enough to store any character.
204
 * To do this properly, we should use wint_t.
205
 */
206
static int file_reader_next_wchar(reader_t *reader) {
207
  wint_t c;
208

209
  assert(reader->is_stream);
210

211
  if (reader->current == EOF) {
212
    return EOF;
213
  }
214

215
  if (reader->current == '\n') { // this should works in UTF-8?
216
    reader->line ++;
217
    reader->column ++;
218
  }
219

220
#if defined(LINUX)
221
  c = fgetwc_unlocked(reader->input.stream);
222
#else
223
  c = fgetwc(reader->input.stream);
224
#endif
225

226
  if (c == WEOF) {
227
    reader->current = EOF;
228
  } else {
229
    reader->current = c;
230
    reader->pos ++;
231
    reader->column += wcwidth(c);
232
  }
233

234
  return c;
235
}
236

237

238
/*
239
 * Experimental: try to support wide characters (UTF-8)
240
 */
241
int32_t init_wide_file_reader(reader_t *reader, const char *filename) {
242
    FILE *f;
243

244
  f = fopen(filename, "r");
245
  reader->input.stream = f; // keep it NULL if there's an error
246
  reader->pos = 0;
247
  reader->line = 0;
248
  reader->column = 1;
249
  reader->is_stream = true;
250
  reader->read = file_reader_next_wchar;
251
  reader->name = filename;
252

253
  if (f == NULL) {
254
    reader->current = EOF;
255
    return -1;
256
  }
257

258
  reader->current = '\n';
259
  return 0;
260
}
261

262
void init_wide_stream_reader(reader_t *reader, FILE *f, const char *name) {
263
  reader->current = '\n';
264
  reader->input.stream = f;
265
  reader->pos = 0;
266
  reader->line = 0;
267
  reader->column = 1;
268
  reader->is_stream = true;
269
  reader->read = file_reader_next_wchar;
270
  reader->name = name;
271
}
272

273
#endif
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