Deleted Added
sdiff udiff text old ( 234587 ) new ( 234799 )
full compact
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Copyright (c) 2011 The FreeBSD Foundation
6 * All rights reserved.
7 * Portions of this software were developed by David Chisnall
8 * under sponsorship from the FreeBSD Foundation.

--- 25 unchanged lines hidden (view full) ---

34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38#if defined(LIBC_SCCS) && !defined(lint)
39static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
40#endif /* LIBC_SCCS and not lint */
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: head/lib/libc/stdio/vfscanf.c 234587 2012-04-22 21:28:14Z das $");
43
44#include "namespace.h"
45#include <ctype.h>
46#include <inttypes.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <stddef.h>
50#include <stdarg.h>

--- 71 unchanged lines hidden (view full) ---

122 * The following conversion functions return the number of characters consumed,
123 * or -1 on input failure. Character class conversion returns 0 on match
124 * failure.
125 */
126
127static __inline int
128convert_char(FILE *fp, char * __restrict p, int width)
129{
130 int n, nread;
131
132 nread = 0;
133 if (p == SUPPRESS_PTR) {
134 size_t sum = 0;
135 for (;;) {
136 if ((n = fp->_r) < width) {
137 sum += n;
138 width -= n;
139 fp->_p += n;
140 if (__srefill(fp)) {
141 if (sum == 0)
142 return (-1);
143 break;
144 }
145 } else {
146 sum += width;
147 fp->_r -= width;
148 fp->_p += width;
149 break;
150 }
151 }
152 nread += sum;
153 } else {
154 size_t r = __fread(p, 1, width, fp);
155
156 if (r == 0)
157 return (-1);
158 nread += r;
159 }
160 return (nread);
161}
162
163static __inline int
164convert_wchar(FILE *fp, wchar_t *wcp, int width)
165{
166 mbstate_t mbs;
167 size_t nconv;
168 int n, nread;
169 char buf[MB_CUR_MAX];
170
171 nread = 0;
172 n = 0;
173 while (width != 0) {
174 if (n == MB_CUR_MAX) {
175 fp->_flags |= __SERR;
176 return (-1);
177 }
178 buf[n++] = *fp->_p;
179 fp->_p++;
180 fp->_r--;
181 mbs = initial_mbs;
182 nconv = mbrtowc(wcp, buf, n, &mbs);
183 if (nconv == (size_t)-1) {
184 fp->_flags |= __SERR;
185 return (-1);
186 }
187 if (nconv == 0 && wcp != SUPPRESS_PTR)
188 *wcp = L'\0';
189 if (nconv != (size_t)-2) {
190 nread += n;
191 width--;
192 if (wcp != SUPPRESS_PTR)
193 wcp++;
194 n = 0;
195 }
196 if (fp->_r <= 0 && __srefill(fp)) {
197 if (n != 0) {
198 fp->_flags |= __SERR;
199 return (-1);
200 }
201 break;
202 }
203 }
204 return (nread);
205}
206
207static __inline int
208convert_ccl(FILE *fp, char * __restrict p, int width, const char *ccltab)
209{
210 char *p0;
211 int n;
212

--- 26 unchanged lines hidden (view full) ---

239 if (n == 0)
240 return (0);
241 *p = 0;
242 }
243 return (n);
244}
245
246static __inline int
247convert_wccl(FILE *fp, wchar_t *wcp, int width, const char *ccltab)
248{
249 mbstate_t mbs;
250 wchar_t twc;
251 int n, nchars, nconv;
252 char buf[MB_CUR_MAX];
253
254 if (wcp == SUPPRESS_PTR)
255 wcp = &twc;
256 n = 0;
257 nchars = 0;
258 while (width != 0) {
259 if (n == MB_CUR_MAX) {
260 fp->_flags |= __SERR;
261 return (-1);
262 }
263 buf[n++] = *fp->_p;
264 fp->_p++;
265 fp->_r--;
266 mbs = initial_mbs;
267 nconv = mbrtowc(wcp, buf, n, &mbs);
268 if (nconv == (size_t)-1) {
269 fp->_flags |= __SERR;
270 return (-1);
271 }
272 if (nconv == 0)
273 *wcp = L'\0';
274 if (nconv != (size_t)-2) {
275 if (wctob(*wcp) != EOF && !ccltab[wctob(*wcp)]) {
276 while (n != 0) {
277 n--;
278 __ungetc(buf[n], fp);
279 }
280 break;
281 }
282 width--;
283 if (wcp != &twc)
284 wcp++;
285 nchars++;
286 n = 0;
287 }
288 if (fp->_r <= 0 && __srefill(fp)) {
289 if (n != 0) {
290 fp->_flags |= __SERR;
291 return (-1);
292 }
293 break;
294 }
295 }
296 if (n != 0) {
297 fp->_flags |= __SERR;
298 return (-1);
299 }
300 if (nchars == 0)
301 return (0);
302 *wcp = L'\0';
303 return (nchars);
304}
305
306static __inline int
307convert_string(FILE *fp, char * __restrict p, int width)
308{
309 char *p0;
310 int n;
311

--- 18 unchanged lines hidden (view full) ---

330 }
331 *p = 0;
332 n = p - p0;
333 }
334 return (n);
335}
336
337static __inline int
338convert_wstring(FILE *fp, wchar_t *wcp, int width)
339{
340 mbstate_t mbs;
341 wchar_t twc;
342 int n, nconv, nread;
343 char buf[MB_CUR_MAX];
344
345 if (wcp == SUPPRESS_PTR)
346 wcp = &twc;
347 n = nread = 0;
348 while (!isspace(*fp->_p) && width != 0) {
349 if (n == MB_CUR_MAX) {
350 fp->_flags |= __SERR;
351 return (-1);
352 }
353 buf[n++] = *fp->_p;
354 fp->_p++;
355 fp->_r--;
356 mbs = initial_mbs;
357 nconv = mbrtowc(wcp, buf, n, &mbs);
358 if (nconv == (size_t)-1) {
359 fp->_flags |= __SERR;
360 return (-1);
361 }
362 if (nconv == 0)
363 *wcp = L'\0';
364 if (nconv != (size_t)-2) {
365 if (iswspace(*wcp)) {
366 while (n != 0) {
367 n--;
368 __ungetc(buf[n], fp);
369 }
370 break;
371 }
372 nread += n;
373 width--;
374 if (wcp != &twc)
375 wcp++;
376 n = 0;
377 }
378 if (fp->_r <= 0 && __srefill(fp)) {
379 if (n != 0) {
380 fp->_flags |= __SERR;
381 return (-1);
382 }
383 break;
384 }
385 }
386 *wcp = L'\0';
387 return (nread);
388}
389
390/*
391 * Read an integer, storing it in buf. The only relevant bit in the
392 * flags argument is PFXOK.
393 *
394 * Return 0 on a match failure, and the number of characters read
395 * otherwise.

--- 365 unchanged lines hidden (view full) ---

761 switch (c) {
762
763 case CT_CHAR:
764 /* scan arbitrary characters (sets NOSKIP) */
765 if (width == 0)
766 width = 1;
767 if (flags & LONG) {
768 nr = convert_wchar(fp, GETARG(wchar_t *),
769 width);
770 } else {
771 nr = convert_char(fp, GETARG(char *), width);
772 }
773 if (nr < 0)
774 goto input_failure;
775 break;
776
777 case CT_CCL:
778 /* scan a (nonempty) character class (sets NOSKIP) */
779 if (width == 0)
780 width = (size_t)~0; /* `infinity' */
781 if (flags & LONG) {
782 nr = convert_wccl(fp, GETARG(wchar_t *), width,
783 ccltab);
784 } else {
785 nr = convert_ccl(fp, GETARG(char *), width,
786 ccltab);
787 }
788 if (nr <= 0) {
789 if (nr < 0)
790 goto input_failure;
791 else /* nr == 0 */
792 goto match_failure;
793 }
794 break;
795
796 case CT_STRING:
797 /* like CCL, but zero-length string OK, & no NOSKIP */
798 if (width == 0)
799 width = (size_t)~0;
800 if (flags & LONG) {
801 nr = convert_wstring(fp, GETARG(wchar_t *),
802 width);
803 } else {
804 nr = convert_string(fp, GETARG(char *), width);
805 }
806 if (nr < 0)
807 goto input_failure;
808 break;
809
810 case CT_INT:

--- 364 unchanged lines hidden ---