ucx/printf.c

branch
newapi
changeset 253
087cc9216f28
parent 174
0358f1d9c506
equal deleted inserted replaced
252:7d176764756d 253:087cc9216f28
32 #include <string.h> 32 #include <string.h>
33 33
34 #ifndef CX_PRINTF_SBO_SIZE 34 #ifndef CX_PRINTF_SBO_SIZE
35 #define CX_PRINTF_SBO_SIZE 512 35 #define CX_PRINTF_SBO_SIZE 512
36 #endif 36 #endif
37 unsigned const cx_printf_sbo_size = CX_PRINTF_SBO_SIZE;
37 38
38 int cx_fprintf( 39 int cx_fprintf(
39 void *stream, 40 void *stream,
40 cx_write_func wfc, 41 cx_write_func wfc,
41 char const *fmt, 42 char const *fmt,
58 char buf[CX_PRINTF_SBO_SIZE]; 59 char buf[CX_PRINTF_SBO_SIZE];
59 va_list ap2; 60 va_list ap2;
60 va_copy(ap2, ap); 61 va_copy(ap2, ap);
61 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); 62 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap);
62 if (ret < 0) { 63 if (ret < 0) {
64 va_end(ap2);
63 return ret; 65 return ret;
64 } else if (ret < CX_PRINTF_SBO_SIZE) { 66 } else if (ret < CX_PRINTF_SBO_SIZE) {
67 va_end(ap2);
65 return (int) wfc(buf, 1, ret, stream); 68 return (int) wfc(buf, 1, ret, stream);
66 } else { 69 } else {
67 int len = ret + 1; 70 int len = ret + 1;
68 char *newbuf = malloc(len); 71 char *newbuf = malloc(len);
69 if (!newbuf) { 72 if (!newbuf) {
73 va_end(ap2);
70 return -1; 74 return -1;
71 } 75 }
72 76
73 ret = vsnprintf(newbuf, len, fmt, ap2); 77 ret = vsnprintf(newbuf, len, fmt, ap2);
78 va_end(ap2);
74 if (ret > 0) { 79 if (ret > 0) {
75 ret = (int) wfc(newbuf, 1, ret, stream); 80 ret = (int) wfc(newbuf, 1, ret, stream);
76 } 81 }
77 free(newbuf); 82 free(newbuf);
78 } 83 }
83 CxAllocator const *allocator, 88 CxAllocator const *allocator,
84 char const *fmt, 89 char const *fmt,
85 ... 90 ...
86 ) { 91 ) {
87 va_list ap; 92 va_list ap;
88 cxmutstr ret;
89 va_start(ap, fmt); 93 va_start(ap, fmt);
90 ret = cx_vasprintf_a(allocator, fmt, ap); 94 cxmutstr ret = cx_vasprintf_a(allocator, fmt, ap);
91 va_end(ap); 95 va_end(ap);
92 return ret; 96 return ret;
93 } 97 }
94 98
95 cxmutstr cx_vasprintf_a( 99 cxmutstr cx_vasprintf_a(
102 s.length = 0; 106 s.length = 0;
103 char buf[CX_PRINTF_SBO_SIZE]; 107 char buf[CX_PRINTF_SBO_SIZE];
104 va_list ap2; 108 va_list ap2;
105 va_copy(ap2, ap); 109 va_copy(ap2, ap);
106 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); 110 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap);
107 if (ret > 0 && ret < CX_PRINTF_SBO_SIZE) { 111 if (ret >= 0 && ret < CX_PRINTF_SBO_SIZE) {
108 s.ptr = cxMalloc(a, ret + 1); 112 s.ptr = cxMalloc(a, ret + 1);
109 if (s.ptr) { 113 if (s.ptr) {
110 s.length = (size_t) ret; 114 s.length = (size_t) ret;
111 memcpy(s.ptr, buf, ret); 115 memcpy(s.ptr, buf, ret);
112 s.ptr[s.length] = '\0'; 116 s.ptr[s.length] = '\0';
122 } else { 126 } else {
123 s.length = (size_t) ret; 127 s.length = (size_t) ret;
124 } 128 }
125 } 129 }
126 } 130 }
131 va_end(ap2);
127 return s; 132 return s;
128 } 133 }
129 134
135 int cx_sprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, ... ) {
136 va_list ap;
137 va_start(ap, fmt);
138 int ret = cx_vsprintf_a(alloc, str, len, fmt, ap);
139 va_end(ap);
140 return ret;
141 }
142
143 int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, va_list ap) {
144 va_list ap2;
145 va_copy(ap2, ap);
146 int ret = vsnprintf(*str, len, fmt, ap);
147 if ((unsigned) ret >= len) {
148 unsigned newlen = ret + 1;
149 char *ptr = cxRealloc(alloc, *str, newlen);
150 if (ptr) {
151 int newret = vsnprintf(ptr, newlen, fmt, ap2);
152 if (newret < 0) {
153 cxFree(alloc, ptr);
154 } else {
155 *str = ptr;
156 ret = newret;
157 }
158 }
159 }
160 va_end(ap2);
161 return ret;
162 }
163
164 int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, ... ) {
165 va_list ap;
166 va_start(ap, fmt);
167 int ret = cx_vsprintf_sa(alloc, buf, len, str, fmt, ap);
168 va_end(ap);
169 return ret;
170 }
171
172 int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, va_list ap) {
173 va_list ap2;
174 va_copy(ap2, ap);
175 int ret = vsnprintf(buf, len, fmt, ap);
176 *str = buf;
177 if ((unsigned) ret >= len) {
178 unsigned newlen = ret + 1;
179 char *ptr = cxMalloc(alloc, newlen);
180 if (ptr) {
181 int newret = vsnprintf(ptr, newlen, fmt, ap2);
182 if (newret < 0) {
183 cxFree(alloc, ptr);
184 } else {
185 *str = ptr;
186 ret = newret;
187 }
188 }
189 }
190 va_end(ap2);
191 return ret;
192 }

mercurial