|
|
|
@ -3,7 +3,7 @@ |
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application. |
|
|
|
* |
|
|
|
* Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> |
|
|
|
* Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors. |
|
|
|
* Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors. |
|
|
|
* |
|
|
|
* This program is free software; you can redistribute it and/or |
|
|
|
* modify it under the terms of the GNU General Public License |
|
|
|
@ -43,6 +43,14 @@ |
|
|
|
static int vprint( std::string* result, const char* format, va_list ap ) |
|
|
|
{ |
|
|
|
char msg[512]; |
|
|
|
// This function can call vsnprintf twice.
|
|
|
|
// But internally, vsnprintf retrieves arguments from the va_list identified by arg as if
|
|
|
|
// va_arg was used on it, and thus the state of the va_list is likely to be altered by the call.
|
|
|
|
// see: www.cplusplus.com/reference/cstdio/vsnprintf
|
|
|
|
// we make a copy of va_list ap for the second call, if happens
|
|
|
|
va_list tmp; |
|
|
|
va_copy( tmp, ap ); |
|
|
|
|
|
|
|
size_t len = vsnprintf( msg, sizeof(msg), format, ap ); |
|
|
|
|
|
|
|
if( len < sizeof(msg) ) // the output fit into msg
|
|
|
|
@ -58,11 +66,13 @@ static int vprint( std::string* result, const char* format, va_list ap ) |
|
|
|
|
|
|
|
buf.reserve( len+1 ); // reserve(), not resize() which writes. +1 for trailing nul.
|
|
|
|
|
|
|
|
len = vsnprintf( &buf[0], len+1, format, ap ); |
|
|
|
len = vsnprintf( &buf[0], len+1, format, tmp ); |
|
|
|
|
|
|
|
result->append( &buf[0], &buf[0] + len ); |
|
|
|
} |
|
|
|
|
|
|
|
va_end( tmp ); // Release the temporary va_list, initialised from ap
|
|
|
|
|
|
|
|
return len; |
|
|
|
} |
|
|
|
|
|
|
|
@ -397,13 +407,23 @@ const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee ) |
|
|
|
|
|
|
|
int OUTPUTFORMATTER::vprint( const char* fmt, va_list ap ) throw( IO_ERROR ) |
|
|
|
{ |
|
|
|
// This function can call vsnprintf twice.
|
|
|
|
// But internally, vsnprintf retrieves arguments from the va_list identified by arg as if
|
|
|
|
// va_arg was used on it, and thus the state of the va_list is likely to be altered by the call.
|
|
|
|
// see: www.cplusplus.com/reference/cstdio/vsnprintf
|
|
|
|
// we make a copy of va_list ap for the second call, if happens
|
|
|
|
va_list tmp; |
|
|
|
va_copy( tmp, ap ); |
|
|
|
int ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap ); |
|
|
|
|
|
|
|
if( ret >= (int) buffer.size() ) |
|
|
|
{ |
|
|
|
buffer.resize( ret + 2000 ); |
|
|
|
ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap ); |
|
|
|
buffer.resize( ret + 1000 ); |
|
|
|
ret = vsnprintf( &buffer[0], buffer.size(), fmt, tmp ); |
|
|
|
} |
|
|
|
|
|
|
|
va_end( tmp ); // Release the temporary va_list, initialised from ap
|
|
|
|
|
|
|
|
if( ret > 0 ) |
|
|
|
write( &buffer[0], ret ); |
|
|
|
|
|
|
|
|