Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/waterbox/libc/functions/stdio/_vcbprintf.c
2 views
1
/* vsnprintf( char *, size_t, const char *, va_list )
2
3
This file is part of the Public Domain C Library (PDCLib).
4
Permission is granted to use, modify, and / or redistribute at will.
5
*/
6
7
#include <stdio.h>
8
#include <stdarg.h>
9
#include <stdbool.h>
10
11
#ifndef REGTEST
12
#include "_PDCLIB_io.h"
13
14
/* returns true if callback-based output succeeded; else false */
15
static inline bool cbout(
16
struct _PDCLIB_status_t * status,
17
const char *buf,
18
size_t size )
19
{
20
size_t rv = status->write( status->ctx, buf, size );
21
status->i += rv;
22
return rv == size;
23
}
24
25
int _vcbprintf(
26
void *p,
27
size_t ( *cb ) ( void *p, const char *buf, size_t size ),
28
const char *format,
29
va_list arg )
30
{
31
struct _PDCLIB_status_t status;
32
status.base = 0;
33
status.flags = 0;
34
status.n = 0;
35
status.i = 0;
36
status.current = 0;
37
status.width = 0;
38
status.prec = 0;
39
status.ctx = p;
40
status.write = cb;
41
va_copy( status.arg, arg );
42
43
/* Alternate between outputing runs of verbatim text and conversions */
44
while ( *format != '\0' )
45
{
46
const char *mark = format;
47
while ( *format != '\0' && *format != '%')
48
{
49
format++;
50
}
51
52
if ( mark != format )
53
{
54
if ( !cbout(&status, mark, format - mark) )
55
return -1;
56
}
57
58
if ( *format == '%' ) {
59
int consumed = _PDCLIB_print( format, &status );
60
if ( consumed > 0 )
61
{
62
format += consumed;
63
}
64
else if ( consumed == 0 )
65
{
66
/* not a conversion specifier, print verbatim */
67
if ( !cbout(&status, format++, 1) )
68
return -1;
69
}
70
else
71
{
72
/* I/O callback error */
73
return -1;
74
}
75
}
76
}
77
78
va_end( status.arg );
79
return status.i;
80
}
81
82
#endif
83
84
#ifdef TEST
85
#define _PDCLIB_FILEID "stdio/_vcbprintf.c"
86
#define _PDCLIB_STRINGIO
87
#include <stdint.h>
88
#include <stddef.h>
89
#include "_PDCLIB_test.h"
90
91
#ifndef REGTEST
92
93
static size_t testcb( void *p, const char *buf, size_t size )
94
{
95
char **destbuf = p;
96
memcpy(*destbuf, buf, size);
97
*destbuf += size;
98
return size;
99
}
100
101
static int testprintf( char * s, const char * format, ... )
102
{
103
int i;
104
va_list arg;
105
va_start( arg, format );
106
i = _vcbprintf( &s, testcb, format, arg );
107
*s = 0;
108
va_end( arg );
109
return i;
110
}
111
112
#endif
113
114
int main( void )
115
{
116
#ifndef REGTEST
117
char target[100];
118
#include "printf_testcases.h"
119
#endif
120
return TEST_RESULTS;
121
}
122
123
#endif
124
125
126