1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/printf.c Sat Nov 05 17:17:17 2022 +0100 1.3 @@ -0,0 +1,109 @@ 1.4 +/* 1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 + * 1.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions are met: 1.11 + * 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 1.15 + * 2. Redistributions in binary form must reproduce the above copyright 1.16 + * notice, this list of conditions and the following disclaimer in the 1.17 + * documentation and/or other materials provided with the distribution. 1.18 + * 1.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.29 + * POSSIBILITY OF SUCH DAMAGE. 1.30 + */ 1.31 + 1.32 +#include "cx/printf.h" 1.33 + 1.34 +#include <stdio.h> 1.35 +#include <string.h> 1.36 + 1.37 +#define UCX_PRINTF_BUFSIZE 256 1.38 + 1.39 +int cx_fprintf(void *stream, cx_write_func wfc, const char *fmt, ...) { 1.40 + int ret; 1.41 + va_list ap; 1.42 + va_start(ap, fmt); 1.43 + ret = cx_vfprintf(stream, wfc, fmt, ap); 1.44 + va_end(ap); 1.45 + return ret; 1.46 +} 1.47 + 1.48 +int cx_vfprintf(void *stream, cx_write_func wfc, const char *fmt, va_list ap) { 1.49 + char buf[UCX_PRINTF_BUFSIZE]; 1.50 + va_list ap2; 1.51 + va_copy(ap2, ap); 1.52 + int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); 1.53 + if (ret < 0) { 1.54 + return ret; 1.55 + } else if (ret < UCX_PRINTF_BUFSIZE) { 1.56 + return (int) wfc(buf, 1, ret, stream); 1.57 + } else { 1.58 + int len = ret + 1; 1.59 + char *newbuf = malloc(len); 1.60 + if (!newbuf) { 1.61 + return -1; 1.62 + } 1.63 + 1.64 + ret = vsnprintf(newbuf, len, fmt, ap2); 1.65 + if (ret > 0) { 1.66 + ret = (int) wfc(newbuf, 1, ret, stream); 1.67 + } 1.68 + free(newbuf); 1.69 + } 1.70 + return ret; 1.71 +} 1.72 + 1.73 +cxmutstr cx_asprintf_a(CxAllocator *allocator, const char *fmt, ...) { 1.74 + va_list ap; 1.75 + cxmutstr ret; 1.76 + va_start(ap, fmt); 1.77 + ret = cx_vasprintf_a(allocator, fmt, ap); 1.78 + va_end(ap); 1.79 + return ret; 1.80 +} 1.81 + 1.82 +cxmutstr cx_vasprintf_a(CxAllocator *a, const char *fmt, va_list ap) { 1.83 + cxmutstr s; 1.84 + s.ptr = NULL; 1.85 + s.length = 0; 1.86 + char buf[UCX_PRINTF_BUFSIZE]; 1.87 + va_list ap2; 1.88 + va_copy(ap2, ap); 1.89 + int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); 1.90 + if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) { 1.91 + s.ptr = cxMalloc(a, ret + 1); 1.92 + if (s.ptr) { 1.93 + s.length = (size_t) ret; 1.94 + memcpy(s.ptr, buf, ret); 1.95 + s.ptr[s.length] = '\0'; 1.96 + } 1.97 + } else { 1.98 + int len = ret + 1; 1.99 + s.ptr = cxMalloc(a, len); 1.100 + if (s.ptr) { 1.101 + ret = vsnprintf(s.ptr, len, fmt, ap2); 1.102 + if (ret < 0) { 1.103 + free(s.ptr); 1.104 + s.ptr = NULL; 1.105 + } else { 1.106 + s.length = (size_t) ret; 1.107 + } 1.108 + } 1.109 + } 1.110 + return s; 1.111 +} 1.112 +