Mercurial > hg > th-libs
comparison th_string.c @ 251:7b76108248e9
More work on printing functions.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 16 Feb 2016 20:32:02 +0200 |
parents | f4b541e0433e |
children | 80ffeb316596 |
comparison
equal
deleted
inserted
replaced
250:f4b541e0433e | 251:7b76108248e9 |
---|---|
109 | 109 |
110 | 110 |
111 // | 111 // |
112 // Simple implementations of printf() type functions | 112 // Simple implementations of printf() type functions |
113 // | 113 // |
114 static int th_vput_int(void *ctx, int (*vputch)(void *ctx, const char ch), | 114 static int th_vput_int(th_printf_ctx *ctx, int (*vputch)(th_printf_ctx *ctx, const char ch), |
115 int val, const int radix, const char padMode, const char padChar, | 115 int val, const int radix, const char padMode, const char padChar, |
116 const int width, const BOOL unsig, const BOOL upcase, const BOOL sign) | 116 const int width, const BOOL unsig, const BOOL upcase, const BOOL sign) |
117 { | 117 { |
118 char buf[64]; | 118 char buf[64]; |
119 size_t pos = 0; | 119 size_t pos = 0; |
189 out: | 189 out: |
190 return ret; | 190 return ret; |
191 } | 191 } |
192 | 192 |
193 | 193 |
194 static int th_vput_str(void *ctx, int (*vputch)(void *ctx, const char ch), | 194 static int th_vput_str(th_printf_ctx *ctx, int (*vputch)(th_printf_ctx *ctx, const char ch), |
195 const char *str, const char padMode, const char padChar, | 195 const char *str, const char padMode, const char padChar, |
196 const int width, const int prec) | 196 const int width, const int prec) |
197 { | 197 { |
198 int nwidth, ret = 0; | 198 int nwidth, ret = 0; |
199 | 199 |
232 out: | 232 out: |
233 return ret; | 233 return ret; |
234 } | 234 } |
235 | 235 |
236 | 236 |
237 int th_vprintf_do(void *ctx, int (*vputch)(void *ctx, const char ch), const char *fmt, va_list ap) | 237 int th_vprintf_do(th_printf_ctx *ctx, |
238 int (*vputch)(th_printf_ctx *ctx, const char ch), | |
239 const char *fmt, va_list ap, const BOOL eol) | |
238 { | 240 { |
239 int ret = 0; | 241 int ret = 0; |
240 | 242 |
241 while (*fmt) | 243 while (*fmt) |
242 { | 244 { |
292 prec = prec * 10 + (*fmt++ - '0'); | 294 prec = prec * 10 + (*fmt++ - '0'); |
293 } | 295 } |
294 | 296 |
295 switch (*fmt) | 297 switch (*fmt) |
296 { | 298 { |
297 case '%': | |
298 vputch(ctx, *fmt); | |
299 break; | |
300 | |
301 case 0: | 299 case 0: |
302 return -104; | 300 return -104; |
303 | 301 |
304 case 'c': | 302 case 'c': |
305 if (padMode != 0 || width >= 0 || prec >= 0 || sign) | 303 if (padMode != 0 || width >= 0 || prec >= 0 || sign) |
339 | 337 |
340 if ((ret = th_vput_str(ctx, vputch, va_arg(ap, char *), padMode, padChar, width, prec)) == EOF) | 338 if ((ret = th_vput_str(ctx, vputch, va_arg(ap, char *), padMode, padChar, width, prec)) == EOF) |
341 goto out; | 339 goto out; |
342 break; | 340 break; |
343 | 341 |
342 case '%': | |
344 default: | 343 default: |
345 vputch(ctx, *fmt); | 344 if ((ret = vputch(ctx, *fmt)) == EOF) |
345 goto out; | |
346 break; | 346 break; |
347 } | 347 } |
348 } | 348 } |
349 fmt++; | 349 fmt++; |
350 } | 350 } |
351 | 351 |
352 if (eol) | |
353 ret = vputch(ctx, 0); | |
354 | |
352 out: | 355 out: |
353 return ret; | 356 return ret == EOF ? ret : ctx->pos - 1; |
354 } | 357 } |
355 | 358 |
356 | 359 |
357 #ifdef TH_USE_INTERNAL_SPRINTF | 360 #ifdef TH_USE_INTERNAL_SPRINTF |
358 typedef struct | 361 static int th_pbuf_vputch(th_printf_ctx *ctx, const char ch) |
359 { | 362 { |
360 char *buf; | |
361 size_t size, pos; | |
362 } th_pbuf_ctx; | |
363 | |
364 | |
365 static int th_pbuf_vputch(void *pctx, const char ch) | |
366 { | |
367 th_pbuf_ctx *ctx = (th_pbuf_ctx *) pctx; | |
368 if (ctx->pos < ctx->size) | 363 if (ctx->pos < ctx->size) |
369 ctx->buf[ctx->pos] = ch; | 364 ctx->buf[ctx->pos] = ch; |
370 ctx->pos++; | 365 ctx->pos++; |
371 return ch; | 366 return ch; |
372 } | 367 } |
373 | 368 |
374 | 369 |
375 static int th_stdio_vputch(void *ctx, const char ch) | 370 static int th_stdio_vputch(th_printf_ctx *ctx, const char ch) |
376 { | 371 { |
377 return fputc(ch, (FILE *) ctx); | 372 ctx->pos++; |
373 return fputc(ch, (FILE *) ctx->data); | |
378 } | 374 } |
379 #endif | 375 #endif |
380 | 376 |
381 | 377 |
382 int th_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) | 378 int th_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) |
383 { | 379 { |
384 #ifdef TH_USE_INTERNAL_SPRINTF | 380 #ifdef TH_USE_INTERNAL_SPRINTF |
385 th_pbuf_ctx ctx; | 381 th_printf_ctx ctx; |
386 ctx.buf = buf; | 382 ctx.buf = buf; |
387 ctx.size = size; | 383 ctx.size = size; |
388 ctx.pos = 0; | 384 ctx.pos = 0; |
389 | 385 |
390 return th_vprintf_do((void *) &ctx, th_pbuf_vputch, fmt, ap); | 386 return th_vprintf_do(&ctx, th_pbuf_vputch, fmt, ap, TRUE); |
391 #else | 387 #else |
392 return vsnprintf(buf, size, fmt, ap); | 388 return vsnprintf(buf, size, fmt, ap); |
393 #endif | 389 #endif |
394 } | 390 } |
395 | 391 |
410 | 406 |
411 | 407 |
412 int th_vfprintf(FILE *fh, const char *fmt, va_list ap) | 408 int th_vfprintf(FILE *fh, const char *fmt, va_list ap) |
413 { | 409 { |
414 #ifdef TH_USE_INTERNAL_SPRINTF | 410 #ifdef TH_USE_INTERNAL_SPRINTF |
415 return th_vprintf_do((void *) fh, th_stdio_vputch, fmt, ap); | 411 th_printf_ctx ctx; |
412 ctx.data = (void *) fh; | |
413 ctx.pos = 0; | |
414 | |
415 return th_vprintf_do(&ctx, th_stdio_vputch, fmt, ap, FALSE); | |
416 #else | 416 #else |
417 return vfprintf(fh, fmt, ap); | 417 return vfprintf(fh, fmt, ap); |
418 #endif | 418 #endif |
419 } | 419 } |
420 | 420 |
421 | 421 |
422 int th_fprintf(FILE *fh, const char *fmt, ...) | 422 int th_fprintf(FILE *fh, const char *fmt, ...) |
423 { | 423 { |
424 int ret; | 424 int ret; |
425 #ifdef TH_USE_INTERNAL_SPRINTF | |
426 th_printf_ctx ctx; | |
427 #endif | |
425 va_list ap; | 428 va_list ap; |
426 va_start(ap, fmt); | 429 va_start(ap, fmt); |
427 #ifdef TH_USE_INTERNAL_SPRINTF | 430 #ifdef TH_USE_INTERNAL_SPRINTF |
428 ret = th_vprintf_do((void *) fh, th_stdio_vputch, fmt, ap); | 431 ctx.data = (void *) fh; |
432 ctx.pos = 0; | |
433 ret = th_vprintf_do(&ctx, th_stdio_vputch, fmt, ap, FALSE); | |
429 #else | 434 #else |
430 ret = fprintf(fh, fmt, ap); | 435 ret = fprintf(fh, fmt, ap); |
431 #endif | 436 #endif |
432 va_end(ap); | 437 va_end(ap); |
433 return ret; | 438 return ret; |