PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
sscanf.c
Go to the documentation of this file.
1#include <stdarg.h>
2#include <stdio.h>
3
4int sscanf(const char* _RESTRICT s, const char* _RESTRICT format, ...)
5{
6 va_list args;
7 va_start(args, format);
8 int ret = vsscanf(s, format, args);
9 va_end(args);
10 return ret;
11}
12
13#ifdef _KERNEL_
14#ifdef _TESTING_
15
16#include <kernel/log/log.h>
17#include <kernel/sched/clock.h>
18#include <kernel/utils/test.h>
19
20#include <limits.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <time.h>
26
27#define INT_MIN_DEZ_STR "2147483648"
28#define INT_MAX_DEZ_STR "2147483647"
29#define UINT_MAX_DEZ_STR "4294967295"
30#define INT_HEXDIG "fffffff"
31#define INT_OCTDIG "37777777777"
32
33#define _SCAN_TEST(rc, input, fmt, ...) \
34 do \
35 { \
36 int ret = sscanf(input, fmt, ##__VA_ARGS__); \
37 if (ret != rc) \
38 { \
39 LOG_ERR("_SCAN_TEST failed at line %d: expected %d, got %d\n", __LINE__, rc, ret); \
40 return ERR; \
41 } \
42 } while (0)
43
44static inline uint64_t _test_scan_iter(void)
45{
46 char buffer[100];
47 int i;
48 unsigned int u;
49 int* p;
50 int n;
51
52 /* basic: reading of three-char string */
53 _SCAN_TEST(1, "foo", "%3c", buffer);
54 TEST_ASSERT(memcmp(buffer, "foo", 3) == 0);
55
56 /* %% for single % */
57 _SCAN_TEST(1, "%x", "%%%c%n", buffer, &n);
58 TEST_ASSERT(n == 2);
59 TEST_ASSERT(buffer[0] == 'x');
60 /* * to skip assignment */
61 _SCAN_TEST(0, "abcdefg", "%*[cba]%n", &n);
62 TEST_ASSERT(n == 3);
63 _SCAN_TEST(0, "foo", "%*s%n", &n);
64 TEST_ASSERT(n == 3);
65 _SCAN_TEST(0, "abc", "%*c%n", &n);
66 TEST_ASSERT(n == 1);
67 _SCAN_TEST(1, "3xfoo", "%*dx%3c", buffer);
68 TEST_ASSERT(memcmp(buffer, "foo", 3) == 0);
69
70 /* domain testing on 'int' type */
71 _SCAN_TEST(1, "-" INT_MIN_DEZ_STR, "%d", &i);
72 TEST_ASSERT(i == INT_MIN);
73 _SCAN_TEST(1, INT_MAX_DEZ_STR, "%d", &i);
74 TEST_ASSERT(i == INT_MAX);
75 _SCAN_TEST(1, "-1", "%d", &i);
76 TEST_ASSERT(i == -1);
77 _SCAN_TEST(1, "0", "%d", &i);
78 TEST_ASSERT(i == 0);
79 _SCAN_TEST(1, "1", "%d", &i);
80 TEST_ASSERT(i == 1);
81 _SCAN_TEST(1, "-" INT_MIN_DEZ_STR, "%i", &i);
82 TEST_ASSERT(i == INT_MIN);
83 _SCAN_TEST(1, INT_MAX_DEZ_STR, "%i", &i);
84 TEST_ASSERT(i == INT_MAX);
85 _SCAN_TEST(1, "-1", "%i", &i);
86 TEST_ASSERT(i == -1);
87 _SCAN_TEST(1, "0", "%i", &i);
88 TEST_ASSERT(i == 0);
89 _SCAN_TEST(1, "1", "%i", &i);
90 TEST_ASSERT(i == 1);
91 _SCAN_TEST(1, "0x7" INT_HEXDIG, "%i", &i);
92 TEST_ASSERT(i == INT_MAX);
93 _SCAN_TEST(1, "0x0", "%i", &i);
94 TEST_ASSERT(i == 0);
95 _SCAN_TEST(1, "00", "%i%n", &i, &n);
96 TEST_ASSERT(i == 0);
97 TEST_ASSERT(n == 2);
98
99 /* domain testing on 'unsigned int' type */
100 _SCAN_TEST(1, UINT_MAX_DEZ_STR, "%u", &u);
101 TEST_ASSERT(u == UINT_MAX);
102 _SCAN_TEST(1, "0", "%u", &u);
103 TEST_ASSERT(u == 0);
104 _SCAN_TEST(1, "f" INT_HEXDIG, "%x", &u);
105 TEST_ASSERT(u == UINT_MAX);
106 _SCAN_TEST(1, "7" INT_HEXDIG, "%x", &u);
107 TEST_ASSERT(u == INT_MAX);
108 _SCAN_TEST(1, "0", "%o", &u);
109 TEST_ASSERT(u == 0);
110 _SCAN_TEST(1, INT_OCTDIG, "%o", &u);
111 TEST_ASSERT(u == UINT_MAX);
112 /* testing %c */
113 memset(buffer, '\0', 100);
114 _SCAN_TEST(1, "x", "%c", buffer);
115 TEST_ASSERT(memcmp(buffer, "x\0", 2) == 0);
116 /* testing %s */
117 memset(buffer, '\0', 100);
118 _SCAN_TEST(1, "foo bar", "%s%n", buffer, &n);
119 TEST_ASSERT(memcmp(buffer, "foo\0", 4) == 0);
120 TEST_ASSERT(n == 3);
121 _SCAN_TEST(2, "foo bar baz", "%s %s %n", buffer, buffer + 4, &n);
122 TEST_ASSERT(n == 9);
123 TEST_ASSERT(memcmp(buffer, "foo\0bar\0", 8) == 0);
124 /* testing %[ */
125 _SCAN_TEST(1, "abcdefg", "%[cba]", buffer);
126 TEST_ASSERT(memcmp(buffer, "abc\0", 4) == 0);
127 _SCAN_TEST(-1, "", "%[cba]", buffer);
128 _SCAN_TEST(1, "3", "%u%[cba]", &u, buffer);
129 /* testing %p */
130 p = NULL;
131 sprintf(buffer, "%p", (void*)p);
132 p = &i;
133 _SCAN_TEST(1, buffer, "%p", (void**)&p);
134 TEST_ASSERT(p == NULL);
135 p = &i;
136 sprintf(buffer, "%p", (void*)p);
137 p = NULL;
138 _SCAN_TEST(1, buffer, "%p", (void**)&p);
139 TEST_ASSERT(p == &i);
140 /* errors */
141 _SCAN_TEST(EOF, "", "%d", &i);
142 _SCAN_TEST(1, "foo", "%5c", buffer);
143 TEST_ASSERT(memcmp(buffer, "foo", 3) == 0);
144
145 return 0;
146}
147
149{
150 for (int k = 0; k < 1; ++k)
151 {
152 TEST_ASSERT(_test_scan_iter() != ERR);
153 }
154
155 return 0;
156}
157
158#endif
159#endif
#define _RESTRICT
Definition config.h:17
EFI_PHYSICAL_ADDRESS buffer
Definition main.c:237
static char format[MAX_NAME]
Definition screen.c:17
#define TEST_DEFINE(_name)
Define a test function to be run by TEST_ALL().
Definition test.h:71
#define TEST_ASSERT(cond)
Assert a condition in a test.
Definition test.h:82
uint64_t scan(fd_t fd, const char *format,...)
Wrapper for reading from a file descriptor using scan formatting.
Definition scan.c:6
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
#define INT_MIN
Definition limits.h:27
#define INT_MAX
Definition limits.h:26
#define UINT_MAX
Definition limits.h:31
int sscanf(const char *_RESTRICT s, const char *_RESTRICT format,...)
Definition sscanf.c:4
#define va_start(ap, parmN)
Definition stdarg.h:16
#define va_end(ap)
Definition stdarg.h:15
__builtin_va_list va_list
Definition stdarg.h:11
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC int vsscanf(const char *_RESTRICT s, const char *_RESTRICT format, va_list arg)
Definition vsscanf.c:27
#define EOF
Definition stdio.h:25
_PUBLIC int sprintf(char *_RESTRICT s, const char *_RESTRICT format,...)
Definition sprintf.c:5
_PUBLIC int memcmp(const void *s1, const void *s2, size_t n)
Definition memcmp.c:3
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4