Skip to content

Commit bcdec21

Browse files
committed
Added tests for asprintf, fprintf, stpcpy, memccpy, and <ti_sprintf.h>
1 parent 90953eb commit bcdec21

File tree

4 files changed

+335
-2
lines changed

4 files changed

+335
-2
lines changed

src/libc/include/stdio.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ int vfprintf(FILE* __restrict stream, const char* __restrict format, va_list va)
108108
__attribute__((format(__printf__, 2, 0)));
109109

110110
int asprintf(char **__restrict p_buffer, const char *__restrict format, ...)
111-
__attribute__((format (__printf__, 2, 3)));
111+
__attribute__((format (__printf__, 2, 3))) __attribute__((nonnull(1)));
112112

113113
int vasprintf(char **__restrict p_buffer, const char *__restrict format, va_list va)
114-
__attribute__((format(__printf__, 2, 0)));
114+
__attribute__((format(__printf__, 2, 0))) __attribute__((nonnull(1)));
115115

116116
void perror(const char* str);
117117

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"transfer_files": [
3+
"bin/DEMO.8xp"
4+
],
5+
"target": {
6+
"name": "DEMO",
7+
"isASM": true
8+
},
9+
"sequence": [
10+
"action|launch",
11+
"delay|1500",
12+
"hashWait|1",
13+
"key|enter",
14+
"delay|300",
15+
"hashWait|2"
16+
],
17+
"hashes": {
18+
"1": {
19+
"description": "All tests passed",
20+
"timeout": 5000,
21+
"start": "vram_start",
22+
"size": "vram_16_size",
23+
"expected_CRCs": [
24+
"38E2AD5A"
25+
]
26+
},
27+
"2": {
28+
"description": "Exit",
29+
"start": "vram_start",
30+
"size": "vram_16_size",
31+
"expected_CRCs": [
32+
"FFAF89BA",
33+
"101734A5",
34+
"9DA19F44",
35+
"A32840C8",
36+
"349F4775"
37+
]
38+
}
39+
}
40+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# ----------------------------
2+
# Makefile Options
3+
# ----------------------------
4+
5+
NAME = DEMO
6+
ICON = icon.png
7+
DESCRIPTION = "CE C Toolchain Demo"
8+
COMPRESSED = NO
9+
ARCHIVED = NO
10+
11+
CFLAGS = -Wall -Wextra -Oz
12+
CXXFLAGS = -Wall -Wextra -Oz
13+
14+
PREFER_OS_LIBC = NO
15+
16+
# ----------------------------
17+
18+
include $(shell cedev-config --makefile)
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
#include <stdbool.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
#include <stdlib.h>
5+
#include <ti/screen.h>
6+
#include <ti/getcsc.h>
7+
#include <sys/util.h>
8+
#include <ti_sprintf.h>
9+
#include <ctype.h>
10+
11+
/**
12+
* @brief Tests the following functions/macros:
13+
* ti_sprintf
14+
* ti_snprintf
15+
* ti_asprintf
16+
* asprintf
17+
* fprintf
18+
* stpcpy
19+
* memccpy
20+
*/
21+
22+
static char const * const test_1 =
23+
"+123 asprintf% 076543 0x9abcd 0XFE1 0\n";
24+
static char const * const test_2 =
25+
"+123 asprintf% 076543 0x9abcd 0XFE1 0\nfoo";
26+
static const int pos_1 = 30;
27+
static const int pos_2 = 42;
28+
29+
static char* buf = NULL;
30+
static FILE* file = NULL;
31+
32+
int ti_tests(void) {
33+
int pos;
34+
int len = ti_asprintf(
35+
&buf, "%+d %s%% %#o %#x %n %#X %i\n",
36+
123, "asprintf", 076543, 0x9abcd, &pos, 0xFE1, 0
37+
);
38+
if (buf == NULL || len <= 0) {
39+
printf("buf %p len %d\n", buf, len);
40+
return __LINE__;
41+
}
42+
if (buf[len] != '\0') {
43+
return __LINE__;
44+
}
45+
size_t buf_len = strlen(buf);
46+
if (buf_len != strlen(test_1) || buf_len != (size_t)len) {
47+
printf("E: %zu != %zu != %d\n", strlen(test_1), buf_len, len);
48+
return __LINE__;
49+
}
50+
if (pos != pos_1) {
51+
printf("E: %d != %d\n", pos, pos_1);
52+
return __LINE__;
53+
}
54+
int cmp = strcmp(buf, test_1);
55+
if (cmp != 0) {
56+
printf("cmp: %d\n", cmp);
57+
return __LINE__;
58+
}
59+
char append[128];
60+
int snprintf_test = ti_snprintf(append, 20, "%s", test_1);
61+
if (snprintf_test >= 0) {
62+
printf("sprintf_test: %d\n", snprintf_test);
63+
return __LINE__;
64+
}
65+
int len_2 = ti_snprintf(append, sizeof(append), "%s", test_1);
66+
if (len_2 != strlen(test_1)) {
67+
printf("E: %d != %zu\n", len_2, strlen(test_1));
68+
return __LINE__;
69+
}
70+
char str2[128];
71+
char* end;
72+
end = stpcpy(str2, append);
73+
end = stpcpy(end, "");
74+
end = stpcpy(end, "foo");
75+
if (*end != '\0') {
76+
return __LINE__;
77+
}
78+
if (end != &str2[pos_2]) {
79+
printf("diff %p - %p = %td\n", end, str2, (ptrdiff_t)(end - str2));
80+
return __LINE__;
81+
}
82+
int cmp2 = strcmp(str2, test_2);
83+
if (cmp2 != 0) {
84+
printf("cmp: %d\n", cmp2);
85+
return __LINE__;
86+
}
87+
return 0;
88+
}
89+
90+
int nano_tests(void) {
91+
int pos;
92+
int len = asprintf(
93+
&buf, "%+d %s%% %#o %#x %n %#X %i\n",
94+
123, "asprintf", 076543, 0x9abcd, &pos, 0xFE1, 0
95+
);
96+
if (buf == NULL || len <= 0) {
97+
printf("buf %p len %d\n", buf, len);
98+
return __LINE__;
99+
}
100+
if (buf[len] != '\0') {
101+
return __LINE__;
102+
}
103+
size_t buf_len = strlen(buf);
104+
if (buf_len != strlen(test_1) || buf_len != (size_t)len) {
105+
printf("E: %zu != %zu != %d\n", strlen(test_1), buf_len, len);
106+
return __LINE__;
107+
}
108+
if (pos != pos_1) {
109+
printf("E: %d != %d\n", pos, pos_1);
110+
return __LINE__;
111+
}
112+
int cmp = strcmp(buf, test_1);
113+
if (cmp != 0) {
114+
printf("cmp: %d\n", cmp);
115+
return __LINE__;
116+
}
117+
return 0;
118+
}
119+
120+
static char const * const fprintf_test =
121+
"Terminal ':' (found):\t\"Stars:\"\n"
122+
"Terminal ' ' (found):\t\"Stars: \"\n"
123+
"Terminal ',' (found):\t\"Stars: Altair,\"\n"
124+
"Terminal '.' (found):\t\"Stars: Altair, Sun, Vega.\"\n"
125+
"Terminal '!' (absent):\t\"Stars: Altair, Sun, Vega.@\"\n"
126+
"\n"
127+
"Separate star names from distances (ly):\n"
128+
"Arcturus Vega Capella Rigel Procyon \n"
129+
/* fprintf_test */;
130+
131+
static char const * const file_name = "FPRINTST";
132+
133+
static void get_diff_char(const char* buf, const char* test) {
134+
size_t char_pos = 0;
135+
char prev = '\0';
136+
while (*buf != '\0' && *test != '\0') {
137+
if (*buf != *test) {
138+
printf("prev %02X: %02X != %02X at %zu\n", prev, *buf, *test, char_pos);
139+
break;
140+
}
141+
prev = *buf;
142+
buf++;
143+
test++;
144+
char_pos++;
145+
}
146+
}
147+
148+
int memccpy_tests(void) {
149+
file = fopen(file_name, "wb");
150+
151+
// Check if the file was opened successfully
152+
if (file == NULL) {
153+
perror("Error opening file");
154+
return __LINE__;
155+
}
156+
// https://en.cppreference.com/w/c/string/byte/memccpy
157+
const char src[] = "Stars: Altair, Sun, Vega.";
158+
const char terminal[] = {':', ' ', ',', '.', '!'};
159+
char dest[sizeof src];
160+
const char alt = '@';
161+
162+
for (size_t i = 0; i != sizeof terminal; ++i)
163+
{
164+
void* to = memccpy(dest, src, terminal[i], sizeof dest);
165+
166+
fprintf(file,"Terminal '%c' (%s):\t\"", terminal[i], to ? "found" : "absent");
167+
168+
// if `terminal` character was not found - print the whole `dest`
169+
to = to ? to : dest + sizeof dest;
170+
171+
for (char* from = dest; from != to; ++from) {
172+
fputc(isprint(*from) ? *from : alt, file);
173+
}
174+
175+
fputs("\"\n", file);
176+
}
177+
178+
179+
fprintf(file, "%c%s", '\n', "Separate star names from distances (ly):\n");
180+
const char *star_distance[] = {
181+
"Arcturus : 37", "Vega : 25", "Capella : 43", "Rigel : 860", "Procyon : 11"
182+
};
183+
char names_only[64];
184+
char *first = names_only;
185+
char *last = names_only + sizeof names_only;
186+
187+
for (size_t t = 0; t != (sizeof star_distance) / (sizeof star_distance[0]); ++t)
188+
{
189+
if (first) {
190+
first = memccpy(first, star_distance[t], ' ', last - first);
191+
} else {
192+
break;
193+
}
194+
}
195+
196+
if (first) {
197+
*first = '\0';
198+
fprintf(file, "%s%c", names_only, '\n');
199+
} else {
200+
printf("Error Buffer is too small.\n");
201+
}
202+
203+
fseek(file, 0, SEEK_END);
204+
int file_size = ftell(file);
205+
fseek(file, 0, SEEK_SET);
206+
207+
if (file_size <= 0) {
208+
perror("file_size <= 0");
209+
return __LINE__;
210+
}
211+
212+
int alloc_size = (int)ftell(file);
213+
buf = (char*)calloc(alloc_size + 2, sizeof(char));
214+
if (buf == NULL) {
215+
perror("calloc failure");
216+
return __LINE__;
217+
}
218+
219+
size_t bytes_read = fread(buf, 1, file_size, file);
220+
if (bytes_read != (size_t)file_size) {
221+
perror("Error reading from file");
222+
return __LINE__;
223+
}
224+
if (strlen(buf) != strlen(fprintf_test)) {
225+
printf("E: %zu != %zu\n", strlen(buf), strlen(fprintf_test));
226+
get_diff_char(buf, fprintf_test);
227+
return __LINE__;
228+
}
229+
int cmp = strcmp(buf, fprintf_test);
230+
if (cmp != 0) {
231+
printf("fprintf_cmp: %d\n", cmp);
232+
get_diff_char(buf, fprintf_test);
233+
return __LINE__;
234+
}
235+
return 0;
236+
}
237+
238+
int run_tests(void) {
239+
int ret = 0;
240+
/* ti_asprintf */
241+
ret = ti_tests();
242+
free(buf); buf = NULL;
243+
if (ret != 0) { return ret; }
244+
245+
/* nano_asprintf */
246+
ret = nano_tests();
247+
free(buf); buf = NULL;
248+
if (ret != 0) { return ret; }
249+
250+
/* nano_fprintf */
251+
ret = memccpy_tests();
252+
free(buf); buf = NULL;
253+
fclose(file);
254+
if (remove(file_name) != 0) {
255+
perror("Couldn't delete file");
256+
}
257+
if (ret != 0) { return ret; }
258+
259+
return 0;
260+
}
261+
262+
int main(void)
263+
{
264+
os_ClrHome();
265+
int ret = run_tests();
266+
if (ret != 0) {
267+
printf("Failed test L%d\n", ret);
268+
} else {
269+
fprintf(stdout, "All tests %s", "passed");
270+
}
271+
272+
while (!os_GetCSC());
273+
274+
return 0;
275+
}

0 commit comments

Comments
 (0)