Path: blob/master/waterbox/libc/functions/stdio/_vcbprintf.c
2 views
/* vsnprintf( char *, size_t, const char *, va_list )12This file is part of the Public Domain C Library (PDCLib).3Permission is granted to use, modify, and / or redistribute at will.4*/56#include <stdio.h>7#include <stdarg.h>8#include <stdbool.h>910#ifndef REGTEST11#include "_PDCLIB_io.h"1213/* returns true if callback-based output succeeded; else false */14static inline bool cbout(15struct _PDCLIB_status_t * status,16const char *buf,17size_t size )18{19size_t rv = status->write( status->ctx, buf, size );20status->i += rv;21return rv == size;22}2324int _vcbprintf(25void *p,26size_t ( *cb ) ( void *p, const char *buf, size_t size ),27const char *format,28va_list arg )29{30struct _PDCLIB_status_t status;31status.base = 0;32status.flags = 0;33status.n = 0;34status.i = 0;35status.current = 0;36status.width = 0;37status.prec = 0;38status.ctx = p;39status.write = cb;40va_copy( status.arg, arg );4142/* Alternate between outputing runs of verbatim text and conversions */43while ( *format != '\0' )44{45const char *mark = format;46while ( *format != '\0' && *format != '%')47{48format++;49}5051if ( mark != format )52{53if ( !cbout(&status, mark, format - mark) )54return -1;55}5657if ( *format == '%' ) {58int consumed = _PDCLIB_print( format, &status );59if ( consumed > 0 )60{61format += consumed;62}63else if ( consumed == 0 )64{65/* not a conversion specifier, print verbatim */66if ( !cbout(&status, format++, 1) )67return -1;68}69else70{71/* I/O callback error */72return -1;73}74}75}7677va_end( status.arg );78return status.i;79}8081#endif8283#ifdef TEST84#define _PDCLIB_FILEID "stdio/_vcbprintf.c"85#define _PDCLIB_STRINGIO86#include <stdint.h>87#include <stddef.h>88#include "_PDCLIB_test.h"8990#ifndef REGTEST9192static size_t testcb( void *p, const char *buf, size_t size )93{94char **destbuf = p;95memcpy(*destbuf, buf, size);96*destbuf += size;97return size;98}99100static int testprintf( char * s, const char * format, ... )101{102int i;103va_list arg;104va_start( arg, format );105i = _vcbprintf( &s, testcb, format, arg );106*s = 0;107va_end( arg );108return i;109}110111#endif112113int main( void )114{115#ifndef REGTEST116char target[100];117#include "printf_testcases.h"118#endif119return TEST_RESULTS;120}121122#endif123124125126