This source file includes following definitions.
- __argp_make_fmtstream
- weak_alias
- weak_alias
- __argp_fmtstream_ensure
- __argp_fmtstream_printf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <stdarg.h>
30 #include <ctype.h>
31
32 #include "argp-fmtstream.h"
33 #include "argp-namefrob.h"
34
35 #ifndef ARGP_FMTSTREAM_USE_LINEWRAP
36
37 #ifndef isblank
38 #define isblank(ch) ((ch)==' ' || (ch)=='\t')
39 #endif
40
41 #ifdef _LIBC
42 # include <wchar.h>
43 # include <libio/libioP.h>
44 # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
45 #endif
46
47 #define INIT_BUF_SIZE 200
48 #define PRINTF_SIZE_GUESS 150
49
50
51
52
53
54
55
56 argp_fmtstream_t
57 __argp_make_fmtstream (FILE *stream,
58 size_t lmargin, size_t rmargin, ssize_t wmargin)
59 {
60 argp_fmtstream_t fs;
61
62 fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
63 if (fs != NULL)
64 {
65 fs->stream = stream;
66
67 fs->lmargin = lmargin;
68 fs->rmargin = rmargin;
69 fs->wmargin = wmargin;
70 fs->point_col = 0;
71 fs->point_offs = 0;
72
73 fs->buf = (char *) malloc (INIT_BUF_SIZE);
74 if (! fs->buf)
75 {
76 free (fs);
77 fs = 0;
78 }
79 else
80 {
81 fs->p = fs->buf;
82 fs->end = fs->buf + INIT_BUF_SIZE;
83 }
84 }
85
86 return fs;
87 }
88 #if 0
89
90 #ifdef weak_alias
91 weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
92 #endif
93 #endif
94
95
96 void
97 __argp_fmtstream_free (argp_fmtstream_t fs)
98 {
99 __argp_fmtstream_update (fs);
100 if (fs->p > fs->buf)
101 {
102 #ifdef _LIBC
103 __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
104 #else
105 fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
106 #endif
107 }
108 free (fs->buf);
109 free (fs);
110 }
111 #if 0
112
113 #ifdef weak_alias
114 weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
115 #endif
116 #endif
117
118
119
120 void
121 __argp_fmtstream_update (argp_fmtstream_t fs)
122 {
123 char *buf, *nl;
124 size_t len;
125
126
127 buf = fs->buf + fs->point_offs;
128 while (buf < fs->p)
129 {
130 size_t r;
131
132 if (fs->point_col == 0 && fs->lmargin != 0)
133 {
134
135 const size_t pad = fs->lmargin;
136 if (fs->p + pad < fs->end)
137 {
138
139
140 memmove (buf + pad, buf, fs->p - buf);
141 fs->p += pad;
142 memset (buf, ' ', pad);
143 buf += pad;
144 }
145 else
146 {
147
148 size_t i;
149 for (i = 0; i < pad; i++)
150 {
151 #ifdef _LIBC
152 if (_IO_fwide (fs->stream, 0) > 0)
153 putwc_unlocked (L' ', fs->stream);
154 else
155 #endif
156 putc_unlocked (' ', fs->stream);
157 }
158 }
159 fs->point_col = pad;
160 }
161
162 len = fs->p - buf;
163 nl = memchr (buf, '\n', len);
164
165 if (fs->point_col < 0)
166 fs->point_col = 0;
167
168 if (!nl)
169 {
170
171
172 if (fs->point_col + len < fs->rmargin)
173 {
174
175
176
177 fs->point_col += len;
178 break;
179 }
180 else
181
182
183 nl = fs->p;
184 }
185 else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
186 {
187
188
189 fs->point_col = 0;
190 buf = nl + 1;
191 continue;
192 }
193
194
195 r = fs->rmargin - 1;
196
197 if (fs->wmargin < 0)
198 {
199
200
201 if (nl < fs->p)
202 {
203 memmove (buf + (r - fs->point_col), nl, fs->p - nl);
204 fs->p -= buf + (r - fs->point_col) - nl;
205
206 fs->point_col = 0;
207 buf += r + 1;
208 }
209 else
210 {
211
212
213
214 fs->point_col += len;
215 fs->p -= fs->point_col - r;
216 break;
217 }
218 }
219 else
220 {
221
222
223
224
225 char *p, *nextline;
226 int i;
227
228 p = buf + (r + 1 - fs->point_col);
229 while (p >= buf && !isblank ((unsigned char) *p))
230 --p;
231 nextline = p + 1;
232
233 if (nextline > buf)
234 {
235
236 if (p >= buf)
237 do
238 --p;
239 while (p >= buf && isblank ((unsigned char) *p));
240 nl = p + 1;
241 }
242 else
243 {
244
245
246 p = buf + (r + 1 - fs->point_col);
247
248 if (p < nl)
249 do
250 ++p;
251 while (p < nl && !isblank ((unsigned char) *p));
252 if (p == nl)
253 {
254
255 fs->point_col = 0;
256 buf = nl + 1;
257 continue;
258 }
259
260 nl = p;
261
262 do
263 ++p;
264 while (isblank ((unsigned char) *p));
265
266 nextline = p;
267 }
268
269
270
271
272
273
274 if ((nextline == buf + len + 1
275 ? fs->end - nl < fs->wmargin + 1
276 : nextline - (nl + 1) < fs->wmargin)
277 && fs->p > nextline)
278 {
279
280 if (fs->end - fs->p > fs->wmargin + 1)
281
282 {
283 size_t mv = fs->p - nextline;
284 memmove (nl + 1 + fs->wmargin, nextline, mv);
285 nextline = nl + 1 + fs->wmargin;
286 len = nextline + mv - buf;
287 *nl++ = '\n';
288 }
289 else
290
291 {
292 #ifdef _LIBC
293 __fxprintf (fs->stream, "%.*s\n",
294 (int) (nl - fs->buf), fs->buf);
295 #else
296 if (nl > fs->buf)
297 fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
298 putc_unlocked ('\n', fs->stream);
299 #endif
300
301 len += buf - fs->buf;
302 nl = buf = fs->buf;
303 }
304 }
305 else
306
307
308 *nl++ = '\n';
309
310 if (nextline - nl >= fs->wmargin
311 || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
312
313 for (i = 0; i < fs->wmargin; ++i)
314 *nl++ = ' ';
315 else
316 for (i = 0; i < fs->wmargin; ++i)
317 #ifdef _LIBC
318 if (_IO_fwide (fs->stream, 0) > 0)
319 putwc_unlocked (L' ', fs->stream);
320 else
321 #endif
322 putc_unlocked (' ', fs->stream);
323
324
325
326 if (nl < nextline)
327 memmove (nl, nextline, buf + len - nextline);
328 len -= nextline - buf;
329
330
331 buf = nl;
332
333
334 fs->p = nl + len;
335
336
337
338
339 fs->point_col = fs->wmargin ? fs->wmargin : -1;
340 }
341 }
342
343
344 fs->point_offs = fs->p - fs->buf;
345 }
346
347
348
349 int
350 __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
351 {
352 if ((size_t) (fs->end - fs->p) < amount)
353 {
354 ssize_t wrote;
355
356
357 __argp_fmtstream_update (fs);
358
359 #ifdef _LIBC
360 __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
361 wrote = fs->p - fs->buf;
362 #else
363 wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
364 #endif
365 if (wrote == fs->p - fs->buf)
366 {
367 fs->p = fs->buf;
368 fs->point_offs = 0;
369 }
370 else
371 {
372 fs->p -= wrote;
373 fs->point_offs -= wrote;
374 memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
375 return 0;
376 }
377
378 if ((size_t) (fs->end - fs->buf) < amount)
379
380 {
381 size_t old_size = fs->end - fs->buf;
382 size_t new_size = old_size + amount;
383 char *new_buf;
384
385 if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
386 {
387 __set_errno (ENOMEM);
388 return 0;
389 }
390
391 fs->buf = new_buf;
392 fs->end = new_buf + new_size;
393 fs->p = fs->buf;
394 }
395 }
396
397 return 1;
398 }
399
400 ssize_t
401 __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
402 {
403 int out;
404 size_t avail;
405 size_t size_guess = PRINTF_SIZE_GUESS;
406
407 do
408 {
409 va_list args;
410
411 if (! __argp_fmtstream_ensure (fs, size_guess))
412 return -1;
413
414 va_start (args, fmt);
415 avail = fs->end - fs->p;
416 out = __vsnprintf (fs->p, avail, fmt, args);
417 va_end (args);
418 if ((size_t) out >= avail)
419 size_guess = out + 1;
420 }
421 while ((size_t) out >= avail);
422
423 fs->p += out;
424
425 return out;
426 }
427 #if 0
428
429 #ifdef weak_alias
430 weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
431 #endif
432 #endif
433
434 #endif