DirectResult direct_print( char *buf, size_t size, const char *format, va_list args, char **ret_ptr ) { int len = 1; *ret_ptr = buf; if (buf) { buf[0] = 0; #ifdef __GNUC__ va_list args_copy; va_copy( args_copy, args ); len = direct_vsnprintf( buf, size, format, args_copy ); va_end( args_copy ); #else len = direct_vsnprintf( buf, size, format, args ); #endif if (len < 0) return DR_FAILURE; } else size = 0; if (len >= (int) size) { char *ptr = buf; ptr = direct_malloc( len+1 ); if (!ptr) return DR_NOLOCALMEMORY; len = direct_vsnprintf( ptr, len+1, format, args ); if (len < 0) { direct_free( ptr ); return DR_FAILURE; } *ret_ptr = ptr; } return DR_OK; }
String & String::PrintF( const char *format, va_list args, size_t stack_buffer ) { size_t len; char buf[stack_buffer]; char *ptr = buf; D_ASSERT( format != NULL ); // TODO: check if va_copy is required here #ifdef __GNUC__ va_list ap2; va_copy( ap2, args ); len = direct_vsnprintf( buf, sizeof(buf), format, ap2 ); va_end( ap2 ); #else len = direct_vsnprintf( buf, sizeof(buf), format, args ); #endif if (len < 0) return *this; if (len >= sizeof(buf)) { ptr = (char*) direct_malloc( len+1 ); if (!ptr) { D_OOM(); return *this; } len = direct_vsnprintf( ptr, len+1, format, args ); if (len < 0) { direct_free( ptr ); return *this; } } str.append( ptr ); if (ptr != buf) direct_free( ptr ); return *this; }
int direct_snprintf( char *buffer, size_t bytes, const char *format, ... ) { int ret; va_list args; va_start( args, format ); ret = direct_vsnprintf( buffer, bytes, format, args ); va_end( args ); return ret; }