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