1 /* Copyright 2013-2015 IBM Corp.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * 	http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define BUFSZ 50
18 
19 #include <stdlib.h>
20 #include <assert.h>
21 #include <string.h>
22 #include <stdio.h>
23 
24 int test1(void);
25 int skiboot_snprintf(char *buf, size_t bufsz, size_t l, const char* format, ...);
26 
test_printf_0u(int n)27 static void test_printf_0u(int n)
28 {
29 	char *buf, *buf2;
30 	int blen;
31 	unsigned int i;
32 
33 	for(i=1; i<10; i++)
34 	{
35 		blen = i+1;
36 		if (n<0)
37 			blen++;
38 
39 		buf = (char*)malloc(blen);
40 		buf2 = (char*)malloc(blen);
41 		skiboot_snprintf(buf, blen, blen, "%08u", n);
42 		snprintf(buf2, blen, "%08u", n);
43 		n = n * 10;
44 		assert(0 == strncmp(buf, buf2, blen));
45 		free(buf);
46 		free(buf2);
47 	}
48 }
49 
test_printf_u(int n)50 static void test_printf_u(int n)
51 {
52 	char *buf, *buf2;
53 	int blen;
54 	unsigned int r;
55 	unsigned int i;
56 
57 	for(i=1; i<10; i++)
58 	{
59 		blen = i+1;
60 		if (n<0)
61 			blen++;
62 
63 		buf = (char*)malloc(blen);
64 		buf2 = (char*)malloc(blen);
65 		r = skiboot_snprintf(buf, blen, blen, "%u", n);
66 		snprintf(buf2, blen, "%u", n);
67 		n = n * 10;
68 		if (n<0)
69 			assert(i+1 == r);
70 		else
71 			assert(i == r);
72 		assert(0 == strncmp(buf, buf2, blen));
73 		free(buf);
74 		free(buf2);
75 	}
76 }
77 
test_printf_d(int n)78 static void test_printf_d(int n)
79 {
80 	char *buf, *buf2;
81 	int blen;
82 	int r;
83 	int i;
84 
85 	for(i=1; i<10; i++)
86 	{
87 		blen = i+1;
88 		if (n<0)
89 			blen++;
90 
91 		buf = (char*)malloc(blen);
92 		buf2 = (char*)malloc(blen);
93 		r = skiboot_snprintf(buf, blen, blen, "%d", n);
94 		snprintf(buf2, blen, "%d", n);
95 		n = n * 10;
96 		if (n<0)
97 			assert(i+1 == r);
98 		else
99 			assert(i == r);
100 		assert(0 == strncmp(buf, buf2, blen));
101 		free(buf);
102 		free(buf2);
103 	}
104 }
105 
test_printf_x(const char * f)106 static void test_printf_x(const char* f)
107 {
108 	char *buf, *buf2;
109 	int blen;
110 	int i, r;
111 	unsigned int n=0x1;
112 
113 	for (i=0; i<8; i++)
114 	{
115 		blen = i+2;
116 		buf = (char*)malloc(blen);
117 		buf2 = (char*)malloc(blen);
118 		r = skiboot_snprintf(buf, blen, blen, f, n);
119 		snprintf(buf2, blen, f, n);
120 		assert(i+1 == r);
121 		assert(0 == strncmp(buf, buf2, blen));
122 		free(buf);
123 		free(buf2);
124 		n = n << 4;
125 	}
126 }
127 
test_printf_c(void)128 static void test_printf_c(void)
129 {
130 	char *buf= (char*)malloc(2);
131 	char buf2[2];
132 	unsigned char i= 0xff;
133 	int r;
134 	while(i)
135 	{
136 		r = skiboot_snprintf(buf, 2, 2, "%c", i);
137 		snprintf(buf2, 2, "%c", i);
138 		assert(r==1);
139 		assert(0 == strncmp(buf, buf2, 2));
140 		i--;
141 	}
142 	free(buf);
143 }
144 
test_printf_p(void)145 static void test_printf_p(void)
146 {
147 	char *buf= (char*)malloc(32);
148 	char buf2[32];
149 	skiboot_snprintf(buf, 32, 32, "%p", buf);
150 	snprintf(buf2, 32, "%p", buf);
151 	assert(0 == strncmp(buf, buf2, 32));
152 	free(buf);
153 }
154 
test_printf_o(void)155 static void test_printf_o(void)
156 {
157 	char *buf= (char*)malloc(32);
158 	char buf2[32];
159 	skiboot_snprintf(buf, 32, 32, "%o", 0x12345678);
160 	snprintf(buf2, 32, "%o", 0x12345678);
161 	assert(0 == strncmp(buf, buf2, 32));
162 	free(buf);
163 }
164 
test_printf_h(short i)165 static void test_printf_h(short i)
166 {
167 	char *buf= (char*)malloc(32);
168 	char buf2[32];
169 	skiboot_snprintf(buf, 32, 32, "%hd", i);
170 	snprintf(buf2, 32, "%hd", i);
171 	assert(0 == strncmp(buf, buf2, 32));
172 	free(buf);
173 }
174 
test_printf_z(size_t i)175 static void test_printf_z(size_t i)
176 {
177 	char *buf= (char*)malloc(32);
178 	char buf2[32];
179 	skiboot_snprintf(buf, 32, 32, "%zu", i);
180 	snprintf(buf2, 32, "%zu", i);
181 	assert(0 == strncmp(buf, buf2, 32));
182 	free(buf);
183 }
184 
main(void)185 int main(void)
186 {
187 	char *buf;
188 	int r;
189 
190 	buf = (char*)malloc(BUFSZ);
191 	memset(buf, 0, BUFSZ);
192 
193 	assert(-1 == test1());
194 
195 	r = skiboot_snprintf(buf, BUFSZ, 2, "%%");
196 	assert(r==1);
197 	assert(buf[0] == '%' && buf[1] == 0);
198 
199 	r = skiboot_snprintf(buf, BUFSZ, 2, "%d", 137);
200 	/* BUG/FIXME:
201 	 * skiboot libc does NOT return the length of the buffer you'd need
202 	 * Instead, it'll return something random, possibly zero (as here)
203 	 * but as you'll see in test_in_buf_len2, sometimes not.
204 	 *
205 	 * Basically, we're not POSIX printf and this is some day going to
206 	 * cause things to be awful.
207 	 */
208 	assert(0 == r); // BUG, should be 3
209 	assert(0 == strncmp(buf, "", 3));
210 
211 	r = skiboot_snprintf(buf, BUFSZ, 4, "%d", 137);
212 	assert(3 == r);
213 	assert(0 == strncmp(buf, "137", 3));
214 	assert(buf[3] == 0);
215 
216 	/* Now we test the strange behaviour of our printf.
217 	 * For strings, we get partial prints going, but if we whack an
218 	 * integer on the end, we may or may not get that integer, depending
219 	 * on if we have enough size. We should test that though */
220 
221 	r = skiboot_snprintf(buf, BUFSZ, 4, "Hello %d", 137);
222 	assert(3 == r);
223 	assert(0 == strncmp(buf, "Hel", 3));
224 	assert(buf[3] == 0);
225 	r = skiboot_snprintf(buf, BUFSZ, 7, "Hello %d", 137);
226 	assert(6 == r);
227 	assert(0 == strncmp(buf, "Hello ", 6));
228 	assert(buf[6] == 0);
229 	r = skiboot_snprintf(buf, BUFSZ, 10, "Hello %d", 137);
230 	assert(9 == r);
231 	assert(0 == strncmp(buf, "Hello 137", 10));
232 	assert(buf[9] == 0);
233 	free(buf);
234 
235 	test_printf_u(1);
236 	test_printf_0u(1);
237 	test_printf_d(1);
238 	test_printf_d(-1);
239 	test_printf_x("%x");
240 	test_printf_x("%X");
241 	test_printf_c();
242 	test_printf_p();
243 	test_printf_o();
244 	test_printf_h(0);
245 	test_printf_h(128);
246 	test_printf_h(256);
247 	test_printf_h(-1);
248 	test_printf_h(32767);
249 	test_printf_h(32768);
250 	test_printf_h(65535);
251 	test_printf_z(0);
252 	test_printf_z(-1);
253 	test_printf_z(12345);
254 	test_printf_z(128000000);
255 
256 	return 0;
257 }
258