added printf functions

Wed, 14 Aug 2013 15:22:35 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 14 Aug 2013 15:22:35 +0200
changeset 142
ee8cb27d8b8e
parent 140
15f871f50bfd
child 143
b843d463ac58

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

mercurial