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