]> pd.if.org Git - pdclib/blob - functions/stdio/vfscanf.c
8f121e95e4a73cac03d000cf6a96132e2163e5ab
[pdclib] / functions / stdio / vfscanf.c
1 /* $Id$ */
2
3 /* vfscanf( FILE *, const char *, va_list )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <ctype.h>
12
13 #ifndef REGTEST
14
15 int vfscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, va_list arg )
16 {
17     /* TODO: This function should interpret format as multibyte characters.  */
18     struct _PDCLIB_status_t status;
19     status.base = 0;
20     status.flags = 0;
21     status.n = 0;
22     status.i = 0;
23     status.current = 0;
24     status.s = NULL;
25     status.width = 0;
26     status.prec = 0;
27     status.stream = stream;
28     va_copy( status.arg, arg );
29
30     while ( *format != '\0' )
31     {
32         const char * rc;
33         if ( ( *format != '%' ) || ( ( rc = _PDCLIB_scan( format, &status ) ) == format ) )
34         {
35             int c;
36             /* No conversion specifier, match verbatim */
37             if ( isspace( *format ) )
38             {
39                 /* Whitespace char in format string: Skip all whitespaces */
40                 /* No whitespaces in input does not result in matching error */
41                 while ( isspace( c = getc( stream ) ) )
42                 {
43                     ++status.i;
44                 }
45                 if ( ! feof( stream ) ) /* TODO: Check EOF status directly */
46                 {
47                     ungetc( c, stream );
48                 }
49             }
50             else
51             {
52                 /* Non-whitespace char in format string: Match verbatim */
53                 if ( ( ( c = getc( stream ) ) != *format ) || feof( stream ) ) /* TODO: Check EOF status directly */
54                 {
55                     /* Matching error */
56                     if ( ! feof( stream ) ) /* TODO: Check EOF status directly */
57                     {
58                         ungetc( c, stream );
59                     }
60                     return status.n;
61                 }
62                 else
63                 {
64                     ++status.i;
65                 }
66             }
67             ++format;
68         }
69         else
70         {
71             /* NULL return code indicates matching error */
72             if ( rc == NULL )
73             {
74                 break;
75             }
76             /* Continue parsing after conversion specifier */
77             format = rc;
78         }
79     }
80     va_end( status.arg );
81     return status.n;
82 }
83
84 #endif
85
86 #ifdef TEST
87 #include <_PDCLIB_test.h>
88
89 #include "scan_test.h"
90
91 static int SCANFUNC( FILE * stream, char const * format, ... )
92 {
93     va_list ap;
94     va_start( ap, format );
95     int result = vfscanf( stream, format, ap );
96     va_end( ap );
97     return result;
98 }
99
100 int main( void )
101 {
102 #include "fscan_sources.incl"
103 #include "scanf_testcases.incl"
104     return TEST_RESULTS;
105 }
106
107 #endif
108