| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 | /* Copyright (C) 2004       Manuel Novoa III    <mjn3@codepoet.org> * * GNU Library General Public License (LGPL) version 2 or later. * * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details. */#include "_stdio.h"#include <stdarg.h>libc_hidden_proto(vsnprintf)libc_hidden_proto(vfprintf)#ifdef __UCLIBC_MJN3_ONLY__#warning WISHLIST: Implement vsnprintf for non-buffered and no custom stream case.#endif /* __UCLIBC_MJN3_ONLY__ */#ifdef __STDIO_BUFFERSint vsnprintf(char *__restrict buf, size_t size,			  const char * __restrict format, va_list arg){	FILE f;	int rv;/* 	__STDIO_STREAM_RESET_GCS(&f); */#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__	f.__cookie = &(f.__filedes);	f.__gcs.read = NULL;	f.__gcs.write = NULL;	f.__gcs.seek = NULL;	f.__gcs.close = NULL;#endif	f.__filedes = __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES;	f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);#ifdef __UCLIBC_HAS_WCHAR__	f.__ungot_width[0] = 0;#endif /* __UCLIBC_HAS_WCHAR__ */#ifdef __STDIO_MBSTATE	__INIT_MBSTATE(&(f.__state));#endif /* __STDIO_MBSTATE */#ifdef __UCLIBC_HAS_THREADS__	f.__user_locking = 1;		/* Set user locking. */	__stdio_init_mutex(&f.__lock);#endif	f.__nextopen = NULL;	if (size > SIZE_MAX - (size_t) buf) {		size = SIZE_MAX - (size_t) buf;	}	/* Set these last since __bufputc initialization depends on	 * __user_locking and only gets set if user locking is on. */	f.__bufstart = buf;	f.__bufend = buf + size;	__STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f);	__STDIO_STREAM_DISABLE_GETC(&f);	__STDIO_STREAM_ENABLE_PUTC(&f);	rv = vfprintf(&f, format, arg);	if (size) {		if (f.__bufpos == f.__bufend) {			--f.__bufpos;		}		*f.__bufpos = 0;	}	return rv;}libc_hidden_def(vsnprintf)#elif defined(__USE_OLD_VFPRINTF__)typedef struct {	FILE f;	unsigned char *bufend;		/* pointer to 1 past end of buffer */	unsigned char *bufpos;} __FILE_vsnprintf;int vsnprintf(char *__restrict buf, size_t size,			  const char * __restrict format, va_list arg){	__FILE_vsnprintf f;	int rv;	f.bufpos = buf;	if (size > SIZE_MAX - (size_t) buf) {		size = SIZE_MAX - (size_t) buf;	}	f.bufend = buf + size;/* 	__STDIO_STREAM_RESET_GCS(&f.f); */#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__	f.f.__cookie = &(f.f.__filedes);	f.f.__gcs.read = NULL;	f.f.__gcs.write = NULL;	f.f.__gcs.seek = NULL;	f.f.__gcs.close = NULL;#endif	f.f.__filedes = __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB;	f.f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);#ifdef __UCLIBC_HAS_WCHAR__	f.f.__ungot_width[0] = 0;#endif /* __UCLIBC_HAS_WCHAR__ */#ifdef __STDIO_MBSTATE	__INIT_MBSTATE(&(f.f.__state));#endif /* __STDIO_MBSTATE */#ifdef __UCLIBC_HAS_THREADS__	f.f.__user_locking = 1;		/* Set user locking. */	__stdio_init_mutex(&f.f.__lock);#endif	f.f.__nextopen = NULL;	rv = vfprintf((FILE *) &f, format, arg);	if (size) {		if (f.bufpos == f.bufend) {			--f.bufpos;		}		*f.bufpos = 0;	}	return rv;}libc_hidden_def(vsnprintf)#elif defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)typedef struct {	size_t pos;	size_t len;	unsigned char *buf;	FILE *fp;} __snpf_cookie;#define COOKIE ((__snpf_cookie *) cookie)static ssize_t snpf_write(register void *cookie, const char *buf,						  size_t bufsize){	size_t count;	register char *p;	/* Note: bufsize < SSIZE_MAX because of _stdio_WRITE. */	if (COOKIE->len > COOKIE->pos) {		count = COOKIE->len - COOKIE->pos - 1; /* Leave space for nul. */		if (count > bufsize) {			count = bufsize;		}		p = COOKIE->buf + COOKIE->pos;		while (count) {			*p++ = *buf++;			--count;		}		*p = 0;	}	COOKIE->pos += bufsize;	return bufsize;}#undef COOKIEint vsnprintf(char *__restrict buf, size_t size,			  const char * __restrict format, va_list arg){	FILE f;	__snpf_cookie cookie;	int rv;	cookie.buf = buf;	cookie.len = size;	cookie.pos = 0;	cookie.fp = &f;	f.__cookie = &cookie;	f.__gcs.write = snpf_write;	f.__gcs.read = NULL;	f.__gcs.seek = NULL;	f.__gcs.close = NULL;	f.__filedes = -1;			/* For debugging. */	f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);#ifdef __UCLIBC_HAS_WCHAR__	f.__ungot_width[0] = 0;#endif /* __UCLIBC_HAS_WCHAR__ */#ifdef __STDIO_MBSTATE	__INIT_MBSTATE(&(f.__state));#endif /* __STDIO_MBSTATE */#ifdef __UCLIBC_HAS_THREADS__	f.__user_locking = 1;		/* Set user locking. */	__stdio_init_mutex(&f.__lock);#endif	f.__nextopen = NULL;	rv = vfprintf(&f, format, arg);	return rv;}libc_hidden_def(vsnprintf)#else#warning Skipping vsnprintf since no buffering, no custom streams, and not old vfprintf!#ifdef __STDIO_HAS_VSNPRINTF#error WHOA! __STDIO_HAS_VSNPRINTF is defined!#endif#endif
 |