PatchworkOS
Loading...
Searching...
No Matches
vfscanf.c
Go to the documentation of this file.
1#include <ctype.h>
2#include <stdarg.h>
3#include <stdio.h>
4
5#include "common/scan.h"
6#include "user/common/file.h"
7
8int vfscanf(FILE* _RESTRICT stream, const char* _RESTRICT format, va_list arg)
9{
10 /* TODO: This function should interpret format as multibyte characters. */
11 _format_ctx_t ctx;
12 ctx.base = 0;
13 ctx.flags = 0;
14 ctx.maxChars = 0;
15 ctx.totalChars = 0;
16 ctx.currentChars = 0;
17 ctx.buffer = NULL;
18 ctx.width = 0;
19 ctx.precision = EOF;
20 ctx.stream = stream;
21
22 mtx_lock(&stream->mtx);
23
24 if (_file_prepare_read(stream) == ERR || _FILE_CHECK_AVAIL(stream) == ERR)
25 {
26 mtx_unlock(&stream->mtx);
27 return EOF;
28 }
29
30 va_copy(ctx.arg, arg);
31
32 while (*format != '\0')
33 {
34 const char* rc;
35
36 if ((*format != '%') || ((rc = _scan(format, &ctx)) == format))
37 {
38 int c;
39
40 /* No conversion specifier, match verbatim */
41 if (isspace((unsigned char)*format))
42 {
43 /* Whitespace char in format string: Skip all whitespaces */
44 /* No whitespaces in input does not result in matching error */
45 while (isspace((unsigned char)(c = getc(stream))))
46 {
47 ++ctx.totalChars;
48 }
49
50 if (!feof(stream))
51 {
52 ungetc(c, stream);
53 }
54 }
55 else
56 {
57 /* Non-whitespace char in format string: Match verbatim */
58 if (((c = getc(stream)) != *format) || feof(stream))
59 {
60 /* Matching error */
61 if (!feof(stream) && !ferror(stream))
62 {
63 ungetc(c, stream);
64 }
65 else if (ctx.maxChars == 0)
66 {
67 mtx_unlock(&stream->mtx);
68 return EOF;
69 }
70
71 mtx_unlock(&stream->mtx);
72 return ctx.maxChars;
73 }
74 else
75 {
76 ++ctx.totalChars;
77 }
78 }
79
80 ++format;
81 }
82 else
83 {
84 /* NULL return code indicates matching error */
85 if (rc == NULL)
86 {
87 break;
88 }
89
90 /* Continue parsing after conversion specifier */
91 format = rc;
92 }
93 }
94
95 va_end(ctx.arg);
96 mtx_unlock(&stream->mtx);
97 return ctx.maxChars;
98}
_PUBLIC int isspace(int c)
Definition isspace.c:5
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
#define _RESTRICT
Definition config.h:17
uint64_t _file_prepare_read(FILE *stream)
Definition file.c:224
const char * _scan(const char *spec, _format_ctx_t *ctx)
Definition scan.c:117
#define _FILE_CHECK_AVAIL(fh)
Definition file.h:53
#define va_copy(dest, src)
Definition stdarg.h:12
#define va_end(ap)
Definition stdarg.h:13
__builtin_va_list va_list
Definition stdarg.h:9
_PUBLIC int getc(FILE *stream)
Definition getc.c:7
_PUBLIC int ferror(FILE *stream)
Definition ferror.c:5
_PUBLIC int feof(FILE *stream)
Definition feof.c:5
#define EOF
Definition stdio.h:25
_PUBLIC int ungetc(int c, FILE *stream)
Definition ungetc.c:5
Definition file.h:34
va_list arg
Definition format.h:45
int64_t precision
Definition format.h:43
FILE * stream
Definition format.h:44
uint64_t maxChars
Definition format.h:38
uint64_t width
Definition format.h:42
_format_flags_t flags
Definition format.h:37
int32_t base
Definition format.h:36
uint64_t currentChars
Definition format.h:40
char * buffer
Definition format.h:41
uint64_t totalChars
Definition format.h:39
_PUBLIC int mtx_lock(mtx_t *mtx)
Definition mtx_lock.c:11
_PUBLIC int mtx_unlock(mtx_t *mtx)
Definition mtx_unlock.c:10
int vfscanf(FILE *_RESTRICT stream, const char *_RESTRICT format, va_list arg)
Definition vfscanf.c:8