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 234799 2012-04-29 16:28:39Z 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; |
131 |
132 if (p == SUPPRESS_PTR) { 133 size_t sum = 0; 134 for (;;) { 135 if ((n = fp->_r) < width) { 136 sum += n; 137 width -= n; 138 fp->_p += n; 139 if (__srefill(fp)) { 140 if (sum == 0) 141 return (-1); 142 break; 143 } 144 } else { 145 sum += width; 146 fp->_r -= width; 147 fp->_p += width; 148 break; 149 } 150 } |
151 return (sum); |
152 } else { 153 size_t r = __fread(p, 1, width, fp); 154 155 if (r == 0) 156 return (-1); |
157 return (r); |
158 } |
159} 160 161static __inline int |
162convert_wchar(FILE *fp, wchar_t *wcp, int width, locale_t locale) |
163{ 164 mbstate_t mbs; |
165 int n, nread; |
166 wint_t wi; |
167 |
168 mbs = initial_mbs; |
169 n = 0; |
170 while (width-- != 0 && 171 (wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF) { 172 if (wcp != SUPPRESS_PTR) 173 *wcp++ = (wchar_t)wi; 174 n += nread; |
175 } |
176 if (n == 0) 177 return (-1); 178 return (n); |
179} 180 181static __inline int 182convert_ccl(FILE *fp, char * __restrict p, int width, const char *ccltab) 183{ 184 char *p0; 185 int n; 186 --- 26 unchanged lines hidden (view full) --- 213 if (n == 0) 214 return (0); 215 *p = 0; 216 } 217 return (n); 218} 219 220static __inline int |
221convert_wccl(FILE *fp, wchar_t *wcp, int width, const char *ccltab, 222 locale_t locale) |
223{ 224 mbstate_t mbs; |
225 wint_t wi; 226 int n, nread; |
227 |
228 mbs = initial_mbs; |
229 n = 0; |
230 if (wcp == SUPPRESS_PTR) { 231 while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && 232 width-- != 0 && ccltab[wctob(wi)]) 233 n += nread; 234 if (wi != WEOF) 235 __ungetwc(wi, fp, __get_locale()); 236 } else { 237 while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && 238 width-- != 0 && ccltab[wctob(wi)]) { 239 *wcp++ = (wchar_t)wi; 240 n += nread; |
241 } |
242 if (wi != WEOF) 243 __ungetwc(wi, fp, __get_locale()); 244 if (n == 0) 245 return (0); 246 *wcp = 0; |
247 } |
248 return (n); |
249} 250 251static __inline int 252convert_string(FILE *fp, char * __restrict p, int width) 253{ 254 char *p0; 255 int n; 256 --- 18 unchanged lines hidden (view full) --- 275 } 276 *p = 0; 277 n = p - p0; 278 } 279 return (n); 280} 281 282static __inline int |
283convert_wstring(FILE *fp, wchar_t *wcp, int width, locale_t locale) |
284{ 285 mbstate_t mbs; |
286 wint_t wi; 287 int n, nread; |
288 |
289 mbs = initial_mbs; 290 n = 0; 291 if (wcp == SUPPRESS_PTR) { 292 while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && 293 width-- != 0 && !iswspace(wi)) 294 n += nread; 295 if (wi != WEOF) 296 __ungetwc(wi, fp, __get_locale()); 297 } else { 298 while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && 299 width-- != 0 && !iswspace(wi)) { 300 *wcp++ = (wchar_t)wi; 301 n += nread; |
302 } |
303 if (wi != WEOF) 304 __ungetwc(wi, fp, __get_locale()); 305 *wcp = '\0'; |
306 } |
307 return (n); |
308} 309 310/* 311 * Read an integer, storing it in buf. The only relevant bit in the 312 * flags argument is PFXOK. 313 * 314 * Return 0 on a match failure, and the number of characters read 315 * otherwise. --- 365 unchanged lines hidden (view full) --- 681 switch (c) { 682 683 case CT_CHAR: 684 /* scan arbitrary characters (sets NOSKIP) */ 685 if (width == 0) 686 width = 1; 687 if (flags & LONG) { 688 nr = convert_wchar(fp, GETARG(wchar_t *), |
689 width, locale); |
690 } else { 691 nr = convert_char(fp, GETARG(char *), width); 692 } 693 if (nr < 0) 694 goto input_failure; 695 break; 696 697 case CT_CCL: 698 /* scan a (nonempty) character class (sets NOSKIP) */ 699 if (width == 0) 700 width = (size_t)~0; /* `infinity' */ 701 if (flags & LONG) { 702 nr = convert_wccl(fp, GETARG(wchar_t *), width, |
703 ccltab, locale); |
704 } else { 705 nr = convert_ccl(fp, GETARG(char *), width, 706 ccltab); 707 } 708 if (nr <= 0) { 709 if (nr < 0) 710 goto input_failure; 711 else /* nr == 0 */ 712 goto match_failure; 713 } 714 break; 715 716 case CT_STRING: 717 /* like CCL, but zero-length string OK, & no NOSKIP */ 718 if (width == 0) 719 width = (size_t)~0; 720 if (flags & LONG) { 721 nr = convert_wstring(fp, GETARG(wchar_t *), |
722 width, locale); |
723 } else { 724 nr = convert_string(fp, GETARG(char *), width); 725 } 726 if (nr < 0) 727 goto input_failure; 728 break; 729 730 case CT_INT: --- 364 unchanged lines hidden --- |