1 /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
3 * GNU Library General Public License (LGPL) version 2 or later.
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
11 #ifdef __STDIO_BUFFERS
12 /* NB: we can still have __USE_OLD_VFPRINTF__ defined in this case! */
14 int vsnprintf(char *__restrict buf
, size_t size
,
15 const char * __restrict format
, va_list arg
)
20 f
.__filedes
= __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES
;
21 f
.__modeflags
= (__FLAG_NARROW
|__FLAG_WRITEONLY
|__FLAG_WRITING
);
23 #ifdef __UCLIBC_HAS_WCHAR__
24 f
.__ungot_width
[0] = 0;
25 #endif /* __UCLIBC_HAS_WCHAR__ */
26 #ifdef __STDIO_MBSTATE
27 __INIT_MBSTATE(&(f
.__state
));
28 #endif /* __STDIO_MBSTATE */
30 #if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__)
31 f
.__user_locking
= 1; /* Set user locking. */
32 STDIO_INIT_MUTEX(f
.__lock
);
36 if (size
> SIZE_MAX
- (size_t) buf
) {
37 size
= SIZE_MAX
- (size_t) buf
;
40 /* TODO: this comment seems to be wrong */
41 /* Set these last since __bufputc initialization depends on
42 * __user_locking and only gets set if user locking is on. */
43 f
.__bufstart
= (unsigned char *) buf
;
44 f
.__bufend
= (unsigned char *) buf
+ size
;
45 __STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f
);
46 __STDIO_STREAM_DISABLE_GETC(&f
);
47 __STDIO_STREAM_ENABLE_PUTC(&f
);
49 #ifdef __USE_OLD_VFPRINTF__
50 rv
= vfprintf(&f
, format
, arg
);
52 rv
= _vfprintf_internal(&f
, format
, arg
);
55 if (f
.__bufpos
== f
.__bufend
) {
62 libc_hidden_def(vsnprintf
)
64 #elif defined(__USE_OLD_VFPRINTF__)
68 unsigned char *bufend
; /* pointer to 1 past end of buffer */
69 unsigned char *bufpos
;
72 int vsnprintf(char *__restrict buf
, size_t size
,
73 const char * __restrict format
, va_list arg
)
80 if (size
> SIZE_MAX
- (size_t) buf
) {
81 size
= SIZE_MAX
- (size_t) buf
;
83 f
.bufend
= buf
+ size
;
85 f
.f
.__filedes
= __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB
;
86 f
.f
.__modeflags
= (__FLAG_NARROW
|__FLAG_WRITEONLY
|__FLAG_WRITING
);
88 #ifdef __UCLIBC_HAS_WCHAR__
89 f
.f
.__ungot_width
[0] = 0;
90 #endif /* __UCLIBC_HAS_WCHAR__ */
91 #ifdef __STDIO_MBSTATE
92 __INIT_MBSTATE(&(f
.f
.__state
));
93 #endif /* __STDIO_MBSTATE */
95 #ifdef __UCLIBC_HAS_THREADS__
96 f
.f
.__user_locking
= 1; /* Set user locking. */
97 STDIO_INIT_MUTEX(f
.f
.__lock
);
99 f
.f
.__nextopen
= NULL
;
101 rv
= vfprintf((FILE *) &f
, format
, arg
);
103 if (f
.bufpos
== f
.bufend
) {
110 libc_hidden_def(vsnprintf
)
112 #elif defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)
121 #define COOKIE ((__snpf_cookie *) cookie)
123 static ssize_t
snpf_write(register void *cookie
, const char *buf
,
129 /* Note: bufsize < SSIZE_MAX because of _stdio_WRITE. */
131 if (COOKIE
->len
> COOKIE
->pos
) {
132 count
= COOKIE
->len
- COOKIE
->pos
- 1; /* Leave space for nul. */
133 if (count
> bufsize
) {
137 p
= COOKIE
->buf
+ COOKIE
->pos
;
145 COOKIE
->pos
+= bufsize
;
152 int vsnprintf(char *__restrict buf
, size_t size
,
153 const char * __restrict format
, va_list arg
)
155 _IO_cookie_file_t cf
;
156 __snpf_cookie cookie
;
162 cookie
.fp
= &cf
.__fp
;
164 cf
.__cookie
= &cookie
;
165 cf
.__gcs
.write
= snpf_write
;
166 cf
.__gcs
.read
= NULL
;
167 cf
.__gcs
.seek
= NULL
;
168 cf
.__gcs
.close
= NULL
;
170 cf
.__fp
.__filedes
= __STDIO_STREAM_GLIBC_CUSTOM_FILEDES
;
171 cf
.__fp
.__modeflags
= (__FLAG_NARROW
|__FLAG_WRITEONLY
|__FLAG_WRITING
);
173 #ifdef __UCLIBC_HAS_WCHAR__
174 cf
.__fp
.__ungot_width
[0] = 0;
175 #endif /* __UCLIBC_HAS_WCHAR__ */
176 #ifdef __STDIO_MBSTATE
177 __INIT_MBSTATE(&(cf
.__fp
.__state
));
178 #endif /* __STDIO_MBSTATE */
180 cf
.__fp
.__nextopen
= NULL
;
182 rv
= _vfprintf_internal(&cf
.__fp
, format
, arg
);
186 libc_hidden_def(vsnprintf
)
189 #warning Skipping vsnprintf since no buffering, no custom streams, and not old vfprintf!
190 #ifdef __STDIO_HAS_VSNPRINTF
191 #error WHOA! __STDIO_HAS_VSNPRINTF is defined!