]> pd.if.org Git - pdclib/blob - functions/stdio/vsscanf.c
First work towards scanf().
[pdclib] / functions / stdio / vsscanf.c
1 /* $Id$ */
2
3 /* vsscanf( const char *, const char *, va_list arg )
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
12 #ifndef REGTEST
13
14 int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, va_list arg )
15 {
16     struct _PDCLIB_status_t status;
17     status.base = 0;
18     status.flags = 0;
19     /* In _PDCLIB_print, status.n holds the maximum number of characters to be
20        written. As we don't need that for the scanf() functions, we (ab)use
21        this field to hold the number of matching conversion specifiers.
22     */
23     status.n = 0; 
24     status.i = 0;
25     status.this = 0;
26     /* In _PDCLIB_print, status.s is the string *printed to*. In the scanf()
27        functions, we (ab)use this field to hold the string *scanned from*.
28     */
29     status.s = (char *)s;
30     status.width = 0;
31     status.prec = 0;
32     status.stream = NULL;
33     va_copy( status.arg, arg );
34     while ( *format != '\0' )
35     {
36         const char * rc;
37         if ( ( *format != '%' ) || ( ( rc = _PDCLIB_scan( format, &status ) ) == format ) )
38         {
39             /* No conversion specifier, match verbatim */
40             if ( isspace( *format ) )
41             {
42                 /* Whitespace char in format string: Skip all whitespaces */
43                 /* No whitespaces in input do not result in matching error */
44                 while ( isspace( *status.s ) )
45                 {
46                     ++status.s;
47                     ++status.i;
48                 }
49             }
50             else
51             {
52                 /* Non-whitespace char in format string: Match verbatim */
53                 if ( *status.s != *format )
54                 {
55                     /* Matching error */
56                     return status.n;
57                 }
58                 else
59                 {
60                     ++status.s;
61                     ++status.i;
62                 }
63             }
64             ++format;
65         }
66         else
67         {
68             /* Continue parsing after conversion specifier */
69             format = rc;
70         }
71     }
72     va_end( status.arg );
73     return status.n;
74 }
75
76 #endif
77
78 #ifdef TEST
79 #include <_PDCLIB_test.h>
80
81 int main( void )
82 {
83     char const * teststring1 = "abc  def";
84     char const * teststring2 = "abcdef";
85     char const * teststring3 = "abc%def";
86     int x;
87     TESTCASE( sscanf( teststring2, "abcdef%n", &x ) == 0 );
88     TESTCASE( x == 6 );
89     TESTCASE( sscanf( teststring1, "abc def%n", &x ) == 0 );
90     TESTCASE( x == 8 );
91     TESTCASE( sscanf( teststring2, "abc def%n", &x ) == 0 );
92     TESTCASE( x == 6 );
93     TESTCASE( sscanf( teststring3, "abc%%def%n", &x ) == 0 );
94     TESTCASE( x == 7 );
95     return TEST_RESULTS;
96 }
97
98 #endif