View Single Post
Old 09-20-2006, 05:55 PM   #139
The Stig
ensiform's Avatar
Join Date: Nov 2004
Location: Sawtooth Cauldron
Posts: 1,241
Current Game: Borderlands 2
Okay, here is a good vsnprintf that works (maybe not for mac but you will have to check) for jka since you dont use qvm:

q_shared.c (somewhere above Com_sprintf preferably):

(comes from idStr::vsnPrintf from Str.c and Str.h from D3/Q4 1.3 SDK)


vsnprintf portability:

C99 standard: vsnprintf returns the number of characters (excluding the trailing
'\0') which would have been written to the final string if enough space had been available
snprintf and vsnprintf do not write more than size bytes (including the trailing '\0')

win32: _vsnprintf returns the number of characters written, not including the terminating null character,
or a negative value if an output error occurs. If the number of characters to write exceeds count, then count 
characters are written and -1 is returned and no trailing '\0' is added.

Q_vsnprintf: always appends a trailing '\0', returns number of characters written (not including terminal \0)
or returns -1 on failure or if the buffer would be overflowed.
int Q_vsnprintf( char *dest, int size, const char *fmt, va_list argptr ) {
	int ret;

#ifdef _WIN32
	ret = _vsnprintf( dest, size-1, fmt, argptr );
	ret = vsnprintf( dest, size, fmt, argptr );
	dest[size-1] = '\0';
	if ( ret < 0 || ret >= size ) {
		return -1;
	return ret;

look for this code:

// strlen that discounts Quake color sequences
int Q_PrintStrlen( const char *string );
// removes color sequences from string
char *Q_CleanStr( char *string );
add this below it:

int Q_vsnprintf( char *dest, int size, const char *fmt, va_list argptr );
Use this for many things like, G_Printf, G_LogPrintf, G_Error, CG_Printf, and CG_Error that use vsprintf. However, leave va, and if you wish to use a cleaner Com_sprintf try something like this:

(comes from Enemy Territory)

void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) {
	int		ret;
	va_list		argptr;

	va_start (argptr,fmt);
	ret = Q_vsnprintf (dest, size, fmt, argptr);
	va_end (argptr);
	if (ret == -1) {
		Com_Printf ("Com_sprintf: overflow of %i bytes buffer\n", size);
My updated G_LogPrintf with the time fix also:


Print to the logfile with a time stamp if it is open
void QDECL G_LogPrintf( const char *fmt, ... ) {
	va_list		argptr;
	char		string[1024];
	int			mins, seconds, msec, l;

	msec = level.time;

	seconds = msec / 1000;
	mins = seconds / 60;
	seconds %= 60;
	msec %= 1000;

	Com_sprintf( string, sizeof(string), "%i:%02i ", mins, seconds );

	l = strlen( string );

	va_start( argptr, fmt );
	Q_vsnprintf( string + l, sizeof( string ) - l, fmt, argptr );
	va_end( argptr );

	if ( g_dedicated.integer ) {
		G_Printf( "%s", string + l );

	if ( !level.logFile ) {

	trap_FS_Write( string, strlen( string ), level.logFile );

iojamp project lead / coder

Last edited by ensiform; 12-02-2006 at 12:49 AM.
ensiform is offline   you may: quote & reply,