/* Copyright 2013-2015 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define BUFSZ 50 #include #include #include #include int test1(void); int skiboot_snprintf(char *buf, size_t bufsz, size_t l, const char* format, ...); static void test_printf_0u(int n) { char *buf, *buf2; int blen; unsigned int i; for(i=1; i<10; i++) { blen = i+1; if (n<0) blen++; buf = (char*)malloc(blen); buf2 = (char*)malloc(blen); skiboot_snprintf(buf, blen, blen, "%08u", n); snprintf(buf2, blen, "%08u", n); n = n * 10; assert(0 == strncmp(buf, buf2, blen)); free(buf); free(buf2); } } static void test_printf_u(int n) { char *buf, *buf2; int blen; unsigned int r; unsigned int i; for(i=1; i<10; i++) { blen = i+1; if (n<0) blen++; buf = (char*)malloc(blen); buf2 = (char*)malloc(blen); r = skiboot_snprintf(buf, blen, blen, "%u", n); snprintf(buf2, blen, "%u", n); n = n * 10; if (n<0) assert(i+1 == r); else assert(i == r); assert(0 == strncmp(buf, buf2, blen)); free(buf); free(buf2); } } static void test_printf_d(int n) { char *buf, *buf2; int blen; int r; int i; for(i=1; i<10; i++) { blen = i+1; if (n<0) blen++; buf = (char*)malloc(blen); buf2 = (char*)malloc(blen); r = skiboot_snprintf(buf, blen, blen, "%d", n); snprintf(buf2, blen, "%d", n); n = n * 10; if (n<0) assert(i+1 == r); else assert(i == r); assert(0 == strncmp(buf, buf2, blen)); free(buf); free(buf2); } } static void test_printf_x(const char* f) { char *buf, *buf2; int blen; int i, r; unsigned int n=0x1; for (i=0; i<8; i++) { blen = i+2; buf = (char*)malloc(blen); buf2 = (char*)malloc(blen); r = skiboot_snprintf(buf, blen, blen, f, n); snprintf(buf2, blen, f, n); assert(i+1 == r); assert(0 == strncmp(buf, buf2, blen)); free(buf); free(buf2); n = n << 4; } } static void test_printf_c(void) { char *buf= (char*)malloc(2); char buf2[2]; unsigned char i= 0xff; int r; while(i) { r = skiboot_snprintf(buf, 2, 2, "%c", i); snprintf(buf2, 2, "%c", i); assert(r==1); assert(0 == strncmp(buf, buf2, 2)); i--; } free(buf); } static void test_printf_p(void) { char *buf= (char*)malloc(32); char buf2[32]; skiboot_snprintf(buf, 32, 32, "%p", buf); snprintf(buf2, 32, "%p", buf); assert(0 == strncmp(buf, buf2, 32)); free(buf); } static void test_printf_o(void) { char *buf= (char*)malloc(32); char buf2[32]; skiboot_snprintf(buf, 32, 32, "%o", 0x12345678); snprintf(buf2, 32, "%o", 0x12345678); assert(0 == strncmp(buf, buf2, 32)); free(buf); } static void test_printf_h(short i) { char *buf= (char*)malloc(32); char buf2[32]; skiboot_snprintf(buf, 32, 32, "%hd", i); snprintf(buf2, 32, "%hd", i); assert(0 == strncmp(buf, buf2, 32)); free(buf); } static void test_printf_z(size_t i) { char *buf= (char*)malloc(32); char buf2[32]; skiboot_snprintf(buf, 32, 32, "%zu", i); snprintf(buf2, 32, "%zu", i); assert(0 == strncmp(buf, buf2, 32)); free(buf); } int main(void) { char *buf; int r; buf = (char*)malloc(BUFSZ); memset(buf, 0, BUFSZ); assert(-1 == test1()); r = skiboot_snprintf(buf, BUFSZ, 2, "%%"); assert(r==1); assert(buf[0] == '%' && buf[1] == 0); r = skiboot_snprintf(buf, BUFSZ, 2, "%d", 137); /* BUG/FIXME: * skiboot libc does NOT return the length of the buffer you'd need * Instead, it'll return something random, possibly zero (as here) * but as you'll see in test_in_buf_len2, sometimes not. * * Basically, we're not POSIX printf and this is some day going to * cause things to be awful. */ assert(0 == r); // BUG, should be 3 assert(0 == strncmp(buf, "", 3)); r = skiboot_snprintf(buf, BUFSZ, 4, "%d", 137); assert(3 == r); assert(0 == strncmp(buf, "137", 3)); assert(buf[3] == 0); /* Now we test the strange behaviour of our printf. * For strings, we get partial prints going, but if we whack an * integer on the end, we may or may not get that integer, depending * on if we have enough size. We should test that though */ r = skiboot_snprintf(buf, BUFSZ, 4, "Hello %d", 137); assert(3 == r); assert(0 == strncmp(buf, "Hel", 3)); assert(buf[3] == 0); r = skiboot_snprintf(buf, BUFSZ, 7, "Hello %d", 137); assert(6 == r); assert(0 == strncmp(buf, "Hello ", 6)); assert(buf[6] == 0); r = skiboot_snprintf(buf, BUFSZ, 10, "Hello %d", 137); assert(9 == r); assert(0 == strncmp(buf, "Hello 137", 10)); assert(buf[9] == 0); free(buf); test_printf_u(1); test_printf_0u(1); test_printf_d(1); test_printf_d(-1); test_printf_x("%x"); test_printf_x("%X"); test_printf_c(); test_printf_p(); test_printf_o(); test_printf_h(0); test_printf_h(128); test_printf_h(256); test_printf_h(-1); test_printf_h(32767); test_printf_h(32768); test_printf_h(65535); test_printf_z(0); test_printf_z(-1); test_printf_z(12345); test_printf_z(128000000); return 0; }