Sun, 30 Nov 2025 18:25:55 +0100
update ucx to version 3.2
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
1 | /* |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
3 | * |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
4 | * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
5 | * |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
8 | * |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
11 | * |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
15 | * |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
27 | */ |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
28 | |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
29 | #include "cx/printf.h" |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
30 | |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
31 | #include <stdio.h> |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
32 | #include <string.h> |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
33 | |
| 490 | 34 | #ifndef CX_PRINTF_SBO_SIZE |
| 35 | #define CX_PRINTF_SBO_SIZE 512 | |
| 36 | #endif | |
| 579 | 37 | const unsigned cx_printf_sbo_size = CX_PRINTF_SBO_SIZE; |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
38 | |
| 490 | 39 | int cx_fprintf( |
| 40 | void *stream, | |
| 41 | cx_write_func wfc, | |
| 579 | 42 | const char *fmt, |
| 490 | 43 | ... |
| 44 | ) { | |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
45 | int ret; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
46 | va_list ap; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
47 | va_start(ap, fmt); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
48 | ret = cx_vfprintf(stream, wfc, fmt, ap); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
49 | va_end(ap); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
50 | return ret; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
51 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
52 | |
| 490 | 53 | int cx_vfprintf( |
| 54 | void *stream, | |
| 55 | cx_write_func wfc, | |
| 579 | 56 | const char *fmt, |
| 490 | 57 | va_list ap |
| 58 | ) { | |
| 59 | char buf[CX_PRINTF_SBO_SIZE]; | |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
60 | va_list ap2; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
61 | va_copy(ap2, ap); |
| 490 | 62 | int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
63 | if (ret < 0) { |
|
645
0c85c4cd0dd8
update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
582
diff
changeset
|
64 | // LCOV_EXCL_START |
| 579 | 65 | va_end(ap2); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
66 | return ret; |
|
645
0c85c4cd0dd8
update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
582
diff
changeset
|
67 | // LCOV_EXCL_STOP |
| 490 | 68 | } else if (ret < CX_PRINTF_SBO_SIZE) { |
| 579 | 69 | va_end(ap2); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
70 | return (int) wfc(buf, 1, ret, stream); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
71 | } else { |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
72 | int len = ret + 1; |
| 582 | 73 | char *newbuf = cxMallocDefault(len); |
| 579 | 74 | if (!newbuf) { // LCOV_EXCL_START |
| 75 | va_end(ap2); | |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
76 | return -1; |
| 579 | 77 | } // LCOV_EXCL_STOP |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
78 | |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
79 | ret = vsnprintf(newbuf, len, fmt, ap2); |
| 579 | 80 | va_end(ap2); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
81 | if (ret > 0) { |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
82 | ret = (int) wfc(newbuf, 1, ret, stream); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
83 | } |
| 582 | 84 | cxFreeDefault(newbuf); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
85 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
86 | return ret; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
87 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
88 | |
| 490 | 89 | cxmutstr cx_asprintf_a( |
| 579 | 90 | const CxAllocator *allocator, |
| 91 | const char *fmt, | |
| 490 | 92 | ... |
| 93 | ) { | |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
94 | va_list ap; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
95 | va_start(ap, fmt); |
| 579 | 96 | cxmutstr ret = cx_vasprintf_a(allocator, fmt, ap); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
97 | va_end(ap); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
98 | return ret; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
99 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
100 | |
| 490 | 101 | cxmutstr cx_vasprintf_a( |
| 579 | 102 | const CxAllocator *a, |
| 103 | const char *fmt, | |
| 490 | 104 | va_list ap |
| 105 | ) { | |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
106 | cxmutstr s; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
107 | s.ptr = NULL; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
108 | s.length = 0; |
| 490 | 109 | char buf[CX_PRINTF_SBO_SIZE]; |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
110 | va_list ap2; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
111 | va_copy(ap2, ap); |
| 490 | 112 | int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); |
| 579 | 113 | if (ret >= 0 && ret < CX_PRINTF_SBO_SIZE) { |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
114 | s.ptr = cxMalloc(a, ret + 1); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
115 | if (s.ptr) { |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
116 | s.length = (size_t) ret; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
117 | memcpy(s.ptr, buf, ret); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
118 | s.ptr[s.length] = '\0'; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
119 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
120 | } else { |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
121 | int len = ret + 1; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
122 | s.ptr = cxMalloc(a, len); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
123 | if (s.ptr) { |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
124 | ret = vsnprintf(s.ptr, len, fmt, ap2); |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
125 | if (ret < 0) { |
|
645
0c85c4cd0dd8
update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
582
diff
changeset
|
126 | // LCOV_EXCL_START |
| 582 | 127 | cxFree(a, s.ptr); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
128 | s.ptr = NULL; |
|
645
0c85c4cd0dd8
update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
582
diff
changeset
|
129 | // LCOV_EXCL_STOP |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
130 | } else { |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
131 | s.length = (size_t) ret; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
132 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
133 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
134 | } |
| 579 | 135 | va_end(ap2); |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
136 | return s; |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
137 | } |
|
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
138 | |
| 582 | 139 | int cx_sprintf_a( |
| 140 | const CxAllocator *alloc, | |
| 141 | char **str, | |
| 142 | size_t *len, | |
| 143 | const char *fmt, | |
| 144 | ... | |
| 145 | ) { | |
| 579 | 146 | va_list ap; |
| 147 | va_start(ap, fmt); | |
| 148 | int ret = cx_vsprintf_a(alloc, str, len, fmt, ap); | |
| 149 | va_end(ap); | |
| 150 | return ret; | |
| 151 | } | |
| 152 | ||
| 582 | 153 | int cx_vsprintf_a( |
| 154 | const CxAllocator *alloc, | |
| 155 | char **str, | |
| 156 | size_t *len, | |
| 157 | const char *fmt, | |
| 158 | va_list ap | |
| 159 | ) { | |
| 579 | 160 | va_list ap2; |
| 161 | va_copy(ap2, ap); | |
| 162 | int ret = vsnprintf(*str, *len, fmt, ap); | |
| 163 | if ((unsigned) ret >= *len) { | |
| 164 | unsigned newlen = ret + 1; | |
| 165 | char *ptr = cxRealloc(alloc, *str, newlen); | |
| 166 | if (ptr) { | |
| 167 | int newret = vsnprintf(ptr, newlen, fmt, ap2); | |
| 168 | if (newret < 0) { | |
|
645
0c85c4cd0dd8
update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
582
diff
changeset
|
169 | cxFree(alloc, ptr); // LCOV_EXCL_LINE |
| 579 | 170 | } else { |
| 171 | *len = newlen; | |
| 172 | *str = ptr; | |
| 173 | ret = newret; | |
| 174 | } | |
| 175 | } | |
| 176 | } | |
| 177 | va_end(ap2); | |
| 178 | return ret; | |
| 179 | } | |
| 180 | ||
| 582 | 181 | int cx_sprintf_sa( |
| 182 | const CxAllocator *alloc, | |
| 183 | char *buf, | |
| 184 | size_t *len, | |
| 185 | char **str, | |
| 186 | const char *fmt, | |
| 187 | ... | |
| 188 | ) { | |
| 579 | 189 | va_list ap; |
| 190 | va_start(ap, fmt); | |
| 191 | int ret = cx_vsprintf_sa(alloc, buf, len, str, fmt, ap); | |
| 192 | va_end(ap); | |
| 193 | return ret; | |
| 194 | } | |
| 195 | ||
| 582 | 196 | int cx_vsprintf_sa( |
| 197 | const CxAllocator *alloc, | |
| 198 | char *buf, | |
| 199 | size_t *len, | |
| 200 | char **str, | |
| 201 | const char *fmt, | |
| 202 | va_list ap | |
| 203 | ) { | |
| 579 | 204 | va_list ap2; |
| 205 | va_copy(ap2, ap); | |
| 206 | int ret = vsnprintf(buf, *len, fmt, ap); | |
| 207 | *str = buf; | |
| 208 | if ((unsigned) ret >= *len) { | |
| 209 | unsigned newlen = ret + 1; | |
| 210 | char *ptr = cxMalloc(alloc, newlen); | |
| 211 | if (ptr) { | |
| 212 | int newret = vsnprintf(ptr, newlen, fmt, ap2); | |
| 213 | if (newret < 0) { | |
|
645
0c85c4cd0dd8
update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
582
diff
changeset
|
214 | cxFree(alloc, ptr); // LCOV_EXCL_LINE |
| 579 | 215 | } else { |
| 216 | *len = newlen; | |
| 217 | *str = ptr; | |
| 218 | ret = newret; | |
| 219 | } | |
| 220 | } | |
| 221 | } | |
| 222 | va_end(ap2); | |
| 223 | return ret; | |
| 224 | } |