Wed, 14 Aug 2013 15:22:35 +0200
added printf functions
test/Makefile | file | annotate | diff | comparison | revisions | |
test/main.c | file | annotate | diff | comparison | revisions | |
test/utils_tests.c | file | annotate | diff | comparison | revisions | |
test/utils_tests.h | file | annotate | diff | comparison | revisions | |
ucx/utils.c | file | annotate | diff | comparison | revisions | |
ucx/utils.h | file | annotate | diff | comparison | revisions |
1.1 --- a/test/Makefile Tue Aug 13 14:20:12 2013 +0200 1.2 +++ b/test/Makefile Wed Aug 14 15:22:35 2013 +0200 1.3 @@ -36,6 +36,7 @@ 1.4 SRC += string_tests.c 1.5 SRC += logging_tests.c 1.6 SRC += buffer_tests.c 1.7 +SRC += utils_tests.c 1.8 1.9 OBJ = $(SRC:%.c=../build/%.$(OBJ_EXT)) 1.10
2.1 --- a/test/main.c Tue Aug 13 14:20:12 2013 +0200 2.2 +++ b/test/main.c Wed Aug 14 15:22:35 2013 +0200 2.3 @@ -40,6 +40,7 @@ 2.4 #include "map_tests.h" 2.5 #include "prop_tests.h" 2.6 #include "buffer_tests.h" 2.7 +#include "utils_tests.h" 2.8 2.9 UCX_EXTERN UCX_TEST(testTestSuitePositive) { 2.10 UCX_TEST_BEGIN 2.11 @@ -177,6 +178,10 @@ 2.12 ucx_test_register(suite, test_ucx_buffer_read); 2.13 ucx_test_register(suite, test_ucx_buffer_extract); 2.14 ucx_test_register(suite, test_ucx_stream_copy); 2.15 + 2.16 + /* Utils Tests*/ 2.17 + ucx_test_register(suite, test_ucx_fprintf); 2.18 + ucx_test_register(suite, test_ucx_asprintf); 2.19 2.20 ucx_test_run(suite, stdout); 2.21 fflush(stdout);
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/utils_tests.c Wed Aug 14 15:22:35 2013 +0200 3.3 @@ -0,0 +1,80 @@ 3.4 +/* 3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3.6 + * 3.7 + * Copyright 2013 Olaf Wintermann. All rights reserved. 3.8 + * 3.9 + * Redistribution and use in source and binary forms, with or without 3.10 + * modification, are permitted provided that the following conditions are met: 3.11 + * 3.12 + * 1. Redistributions of source code must retain the above copyright 3.13 + * notice, this list of conditions and the following disclaimer. 3.14 + * 3.15 + * 2. Redistributions in binary form must reproduce the above copyright 3.16 + * notice, this list of conditions and the following disclaimer in the 3.17 + * documentation and/or other materials provided with the distribution. 3.18 + * 3.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 3.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 3.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3.29 + * POSSIBILITY OF SUCH DAMAGE. 3.30 + */ 3.31 + 3.32 +#include "utils_tests.h" 3.33 +#include "ucx/buffer.h" 3.34 + 3.35 +UCX_TEST(test_ucx_fprintf) { 3.36 + UcxBuffer *b1 = ucx_buffer_new(NULL, 32, UCX_BUFFER_AUTOEXTEND); 3.37 + UcxBuffer *b2 = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); 3.38 + 3.39 + char *teststr1 = (char*)calloc(1, 1024); 3.40 + char *teststr2 = (char*)calloc(1, 1024); 3.41 + memset(teststr1, 'a', 1023); 3.42 + memset(teststr2, 'b', 1023); 3.43 + 3.44 + UCX_TEST_BEGIN 3.45 + 3.46 + ucx_fprintf(b1, (write_func)ucx_buffer_write, "Hello %s", "World"); 3.47 + UCX_TEST_ASSERT(!strcmp(b1->space, "Hello World"), "wrong content in b1"); 3.48 + ucx_fprintf(b1, (write_func)ucx_buffer_write, "\nend.\n"); 3.49 + UCX_TEST_ASSERT(!strcmp(b1->space, "Hello World\nend.\n"), 3.50 + "wrong content in b1 after second fprintf"); 3.51 + 3.52 + ucx_fprintf(b2, (write_func)ucx_buffer_write, "%s%s", teststr1, teststr2); 3.53 + UCX_TEST_ASSERT(!memcmp(b2->space, teststr1, 1023), 3.54 + "wrong first half in b2"); 3.55 + UCX_TEST_ASSERT(!memcmp(b2->space+1023, teststr2, 1023), 3.56 + "wrong second half in b2"); 3.57 + 3.58 + UCX_TEST_END 3.59 +} 3.60 + 3.61 +UCX_TEST(test_ucx_asprintf) { 3.62 + char *teststr1 = (char*)calloc(1, 1024); 3.63 + char *teststr2 = (char*)calloc(1, 1024); 3.64 + memset(teststr1, 'a', 1023); 3.65 + memset(teststr2, 'b', 1023); 3.66 + UcxAllocator *a = ucx_default_allocator(); 3.67 + 3.68 + UCX_TEST_BEGIN 3.69 + 3.70 + sstr_t s1 = ucx_asprintf(a, "int: %d\nHello %s!", 123, "World"); 3.71 + UCX_TEST_ASSERT(s1.ptr, "s1.ptr is NULL"); 3.72 + UCX_TEST_ASSERT(s1.length == 21, "wrong length"); 3.73 + UCX_TEST_ASSERT(!sstrcmp(s1, S("int: 123\nHello World!")), "wrong content"); 3.74 + free(s1.ptr); 3.75 + 3.76 + sstr_t s2 = ucx_asprintf(a, "%s%s", teststr1, teststr2); 3.77 + UCX_TEST_ASSERT(!memcmp(s2.ptr, teststr1, 1023), 3.78 + "wrong first half in s2"); 3.79 + UCX_TEST_ASSERT(!memcmp(s2.ptr+1023, teststr2, 1023), 3.80 + "wrong second half in s2"); 3.81 + 3.82 + UCX_TEST_END 3.83 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/utils_tests.h Wed Aug 14 15:22:35 2013 +0200 4.3 @@ -0,0 +1,47 @@ 4.4 +/* 4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 4.6 + * 4.7 + * Copyright 2013 Olaf Wintermann. All rights reserved. 4.8 + * 4.9 + * Redistribution and use in source and binary forms, with or without 4.10 + * modification, are permitted provided that the following conditions are met: 4.11 + * 4.12 + * 1. Redistributions of source code must retain the above copyright 4.13 + * notice, this list of conditions and the following disclaimer. 4.14 + * 4.15 + * 2. Redistributions in binary form must reproduce the above copyright 4.16 + * notice, this list of conditions and the following disclaimer in the 4.17 + * documentation and/or other materials provided with the distribution. 4.18 + * 4.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 4.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 4.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 4.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 4.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 4.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 4.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4.29 + * POSSIBILITY OF SUCH DAMAGE. 4.30 + */ 4.31 + 4.32 +#ifndef UTILS_TESTS_H 4.33 +#define UTILS_TESTS_H 4.34 + 4.35 +#include "ucx/test.h" 4.36 +#include "ucx/utils.h" 4.37 + 4.38 +#ifdef __cplusplus 4.39 +extern "C" { 4.40 +#endif 4.41 + 4.42 +UCX_TEST(test_ucx_fprintf); 4.43 +UCX_TEST(test_ucx_asprintf); 4.44 + 4.45 +#ifdef __cplusplus 4.46 +} 4.47 +#endif 4.48 + 4.49 +#endif /* UTILS_TESTS_H */ 4.50 +
5.1 --- a/ucx/utils.c Tue Aug 13 14:20:12 2013 +0200 5.2 +++ b/ucx/utils.c Wed Aug 14 15:22:35 2013 +0200 5.3 @@ -28,6 +28,9 @@ 5.4 5.5 #include "utils.h" 5.6 #include <math.h> 5.7 +#include <stdio.h> 5.8 +#include <limits.h> 5.9 +#include <errno.h> 5.10 5.11 /* COPY FUCNTIONS */ 5.12 void* ucx_strcpy(void* s, void* data) { 5.13 @@ -75,7 +78,7 @@ 5.14 return ncp; 5.15 } 5.16 5.17 -/* COMPARE FUNCTION */ 5.18 +/* COMPARE FUNCTIONS */ 5.19 5.20 int ucx_strcmp(void *s1, void *s2, void *data) { 5.21 return strcmp((char*)s1, (char*)s2); 5.22 @@ -128,3 +131,80 @@ 5.23 int ucx_memcmp(void *ptr1, void *ptr2, void *n) { 5.24 return memcmp(ptr1, ptr2, *((size_t*)n)); 5.25 } 5.26 + 5.27 +/* PRINTF FUNCTIONS */ 5.28 + 5.29 +#define UCX_PRINTF_BUFSIZE 256 5.30 + 5.31 +int ucx_fprintf(void *stream, write_func wfc, const char *fmt, ...) { 5.32 + va_list ap; 5.33 + int ret; 5.34 + va_start(ap, fmt); 5.35 + ret = ucx_vfprintf(stream, wfc, fmt, ap); 5.36 + va_end(ap); 5.37 + return ret; 5.38 +} 5.39 + 5.40 +int ucx_vfprintf(void *stream, write_func wfc, const char *fmt, va_list ap) { 5.41 + char buf[UCX_PRINTF_BUFSIZE]; 5.42 + int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); 5.43 + if (ret < 0) { 5.44 + return ret; 5.45 + } else if (ret < UCX_PRINTF_BUFSIZE) { 5.46 + return (int)wfc(buf, 1, ret, stream); 5.47 + } else { 5.48 + if (ret == INT_MAX) { 5.49 + errno = ENOMEM; 5.50 + return -1; 5.51 + } 5.52 + 5.53 + int len = ret + 1; 5.54 + char *newbuf = (char*)malloc(len); 5.55 + if (!newbuf) { 5.56 + return -1; 5.57 + } 5.58 + 5.59 + ret = vsnprintf(newbuf, len, fmt, ap); 5.60 + if (ret > 0) { 5.61 + ret = (int)wfc(newbuf, 1, ret, stream); 5.62 + } 5.63 + free(newbuf); 5.64 + } 5.65 + return ret; 5.66 +} 5.67 + 5.68 +sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...) { 5.69 + va_list ap; 5.70 + sstr_t ret; 5.71 + va_start(ap, fmt); 5.72 + ret = ucx_vasprintf(allocator, fmt, ap); 5.73 + va_end(ap); 5.74 + return ret; 5.75 +} 5.76 + 5.77 +sstr_t ucx_vasprintf(UcxAllocator *a, const char *fmt, va_list ap) { 5.78 + sstr_t s; 5.79 + s.ptr = NULL; 5.80 + s.length = 0; 5.81 + char buf[UCX_PRINTF_BUFSIZE]; 5.82 + int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); 5.83 + if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) { 5.84 + s.ptr = (char*)a->malloc(a->pool, ret + 1); 5.85 + s.length = (size_t)ret; 5.86 + memcpy(s.ptr, buf, ret); 5.87 + s.ptr[s.length] = '\0'; 5.88 + } else if (ret == INT_MAX) { 5.89 + errno = ENOMEM; 5.90 + } else { 5.91 + int len = ret + 1; 5.92 + s.ptr = (char*)a->malloc(a->pool, len); 5.93 + ret = vsnprintf(s.ptr, len, fmt, ap); 5.94 + if (ret < 0) { 5.95 + free(s.ptr); 5.96 + s.ptr = NULL; 5.97 + } else { 5.98 + s.length = (size_t)ret; 5.99 + } 5.100 + } 5.101 + return s; 5.102 +}
6.1 --- a/ucx/utils.h Tue Aug 13 14:20:12 2013 +0200 6.2 +++ b/ucx/utils.h Wed Aug 14 15:22:35 2013 +0200 6.3 @@ -43,8 +43,11 @@ 6.4 #endif 6.5 6.6 #include "ucx.h" 6.7 +#include "string.h" 6.8 +#include "allocator.h" 6.9 #include <stdint.h> 6.10 #include <string.h> 6.11 +#include <stdarg.h> 6.12 6.13 /** 6.14 * Copies a string. 6.15 @@ -133,7 +136,6 @@ 6.16 * @return -1, if *i1 is less than *i2, 0 if both are equal, 6.17 * 1 if *i1 is greater than *i2 6.18 */ 6.19 - 6.20 int ucx_intcmp(void *i1, void *i2, void *data); 6.21 6.22 /** 6.23 @@ -155,7 +157,6 @@ 6.24 * @return -1, if *d1 is less than *d2, 0 if both are equal, 6.25 * 1 if *d1 is greater than *d2 6.26 */ 6.27 - 6.28 int ucx_doublecmp(void *d1, void *d2, void *data); 6.29 6.30 /** 6.31 @@ -177,6 +178,57 @@ 6.32 */ 6.33 int ucx_memcmp(void *ptr1, void *ptr2, void *n); 6.34 6.35 +/** 6.36 + * A printf like function which writes the output to a stream using a write 6.37 + * function. 6.38 + * @param stream the stream where to write the data 6.39 + * @param wfc the write function for the stream 6.40 + * @param fmt format string 6.41 + * @param ... additional arguments 6.42 + * @return the total number of bytes written 6.43 + */ 6.44 +int ucx_fprintf(void *stream, write_func wfc, const char *fmt, ...); 6.45 + 6.46 +/** 6.47 + * Same as ucx_fprintf() but with an argument list instead of variadic 6.48 + * arguments. 6.49 + * @param stream the stream where to write the data 6.50 + * @param wfc the write function for the stream 6.51 + * @param fmt format string 6.52 + * @param ap argument list 6.53 + * @return the total number of bytes written 6.54 + * @see ucx_fprintf() 6.55 + */ 6.56 +int ucx_vfprintf(void *stream, write_func wfc, const char *fmt, va_list ap); 6.57 + 6.58 +/** 6.59 + * A printf lile function which stores the result in a newly created string. 6.60 + * 6.61 + * The sstr_t data is allocated with the allocators ucx_allocator_malloc 6.62 + * function. So it is implementation depended, whether the returned 6.63 + * sstr_t.ptr pointer must be passed to the allocators ucx_allocator_free 6.64 + * function manually. 6.65 + * 6.66 + * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>- 6.67 + * terminated. 6.68 + * 6.69 + * @param allocator a valid instance of an UcxAllocator 6.70 + * @param fmt format string 6.71 + * @param ... additional arguments 6.72 + * @return a new string 6.73 + */ 6.74 +sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...); 6.75 + 6.76 +/** 6.77 + * Same as ucx_asprintf() but with an argument list instead of variadic 6.78 + * arguments. 6.79 + * @param allocator a valid instance of an UcxAllocator 6.80 + * @param fmt format string 6.81 + * @param ap argument list 6.82 + * @return a new string 6.83 + */ 6.84 +sstr_t ucx_vasprintf(UcxAllocator *allocator, const char *fmt, va_list ap); 6.85 + 6.86 #ifdef __cplusplus 6.87 } 6.88 #endif