src/printf.c

Sat, 05 Nov 2022 17:17:17 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 05 Nov 2022 17:17:17 +0100
changeset 599
6536a9a75b71
child 600
19211b88cc0f
permissions
-rw-r--r--

#222 add printf-like functions

universe@599 1 /*
universe@599 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@599 3 *
universe@599 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@599 5 *
universe@599 6 * Redistribution and use in source and binary forms, with or without
universe@599 7 * modification, are permitted provided that the following conditions are met:
universe@599 8 *
universe@599 9 * 1. Redistributions of source code must retain the above copyright
universe@599 10 * notice, this list of conditions and the following disclaimer.
universe@599 11 *
universe@599 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@599 13 * notice, this list of conditions and the following disclaimer in the
universe@599 14 * documentation and/or other materials provided with the distribution.
universe@599 15 *
universe@599 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@599 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@599 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@599 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@599 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@599 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@599 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@599 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@599 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@599 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@599 26 * POSSIBILITY OF SUCH DAMAGE.
universe@599 27 */
universe@599 28
universe@599 29 #include "cx/printf.h"
universe@599 30
universe@599 31 #include <stdio.h>
universe@599 32 #include <string.h>
universe@599 33
universe@599 34 #define UCX_PRINTF_BUFSIZE 256
universe@599 35
universe@599 36 int cx_fprintf(void *stream, cx_write_func wfc, const char *fmt, ...) {
universe@599 37 int ret;
universe@599 38 va_list ap;
universe@599 39 va_start(ap, fmt);
universe@599 40 ret = cx_vfprintf(stream, wfc, fmt, ap);
universe@599 41 va_end(ap);
universe@599 42 return ret;
universe@599 43 }
universe@599 44
universe@599 45 int cx_vfprintf(void *stream, cx_write_func wfc, const char *fmt, va_list ap) {
universe@599 46 char buf[UCX_PRINTF_BUFSIZE];
universe@599 47 va_list ap2;
universe@599 48 va_copy(ap2, ap);
universe@599 49 int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
universe@599 50 if (ret < 0) {
universe@599 51 return ret;
universe@599 52 } else if (ret < UCX_PRINTF_BUFSIZE) {
universe@599 53 return (int) wfc(buf, 1, ret, stream);
universe@599 54 } else {
universe@599 55 int len = ret + 1;
universe@599 56 char *newbuf = malloc(len);
universe@599 57 if (!newbuf) {
universe@599 58 return -1;
universe@599 59 }
universe@599 60
universe@599 61 ret = vsnprintf(newbuf, len, fmt, ap2);
universe@599 62 if (ret > 0) {
universe@599 63 ret = (int) wfc(newbuf, 1, ret, stream);
universe@599 64 }
universe@599 65 free(newbuf);
universe@599 66 }
universe@599 67 return ret;
universe@599 68 }
universe@599 69
universe@599 70 cxmutstr cx_asprintf_a(CxAllocator *allocator, const char *fmt, ...) {
universe@599 71 va_list ap;
universe@599 72 cxmutstr ret;
universe@599 73 va_start(ap, fmt);
universe@599 74 ret = cx_vasprintf_a(allocator, fmt, ap);
universe@599 75 va_end(ap);
universe@599 76 return ret;
universe@599 77 }
universe@599 78
universe@599 79 cxmutstr cx_vasprintf_a(CxAllocator *a, const char *fmt, va_list ap) {
universe@599 80 cxmutstr s;
universe@599 81 s.ptr = NULL;
universe@599 82 s.length = 0;
universe@599 83 char buf[UCX_PRINTF_BUFSIZE];
universe@599 84 va_list ap2;
universe@599 85 va_copy(ap2, ap);
universe@599 86 int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
universe@599 87 if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) {
universe@599 88 s.ptr = cxMalloc(a, ret + 1);
universe@599 89 if (s.ptr) {
universe@599 90 s.length = (size_t) ret;
universe@599 91 memcpy(s.ptr, buf, ret);
universe@599 92 s.ptr[s.length] = '\0';
universe@599 93 }
universe@599 94 } else {
universe@599 95 int len = ret + 1;
universe@599 96 s.ptr = cxMalloc(a, len);
universe@599 97 if (s.ptr) {
universe@599 98 ret = vsnprintf(s.ptr, len, fmt, ap2);
universe@599 99 if (ret < 0) {
universe@599 100 free(s.ptr);
universe@599 101 s.ptr = NULL;
universe@599 102 } else {
universe@599 103 s.length = (size_t) ret;
universe@599 104 }
universe@599 105 }
universe@599 106 }
universe@599 107 return s;
universe@599 108 }
universe@599 109

mercurial