string/string.c
/*
 * @return The number of printed characters or CX_ERR (-1) if an error occurred.
 */
@return The number of printed characters or CX_ERR (-1) if an error occurred.
@return The number of printed characters or CX_ERR ( - 1 ) if an error occurred .
int
StringBuffer_vsnprintf(StringBuffer* buffer, size_t offset, const char* format, va_list args)
{
	if (offset > buffer->length)
	{
		STRING_BUFFER_FERROR(buffer, STRING_BUFFER_STATUS_ERROR_INVALID_ACCESS,
				     "offset %zu out of bounds", offset);
		return CX_ERR;
	}
	char* string_start = S_get(buffer->string, offset);
	size_t nchars_available = buffer->length - offset;
	int nchars_printed; 
	va_list ap;
	va_copy(ap, args);
	nchars_printed = vsnprintf(string_start, nchars_available + 1, format, ap);
	va_end(ap);
	assert(nchars_printed >= 0); 
	if ((size_t)nchars_printed > nchars_available)
	{
		if (StringBuffer_make_room(buffer, offset, (size_t)nchars_printed))
		{
			va_copy(ap, args);
			string_start = S_get(buffer->string, offset);
			nchars_available = buffer->length - offset;
			nchars_printed = vsnprintf(string_start, nchars_available + 1, format, ap);
			va_end(ap);
			assert((size_t)nchars_printed == nchars_available); 
		}
		else
			return CX_ERR;
	}
	buffer->string->length = offset + (size_t)nchars_printed;
	STRING_BUFFER_FDBG(buffer, "printed %d byte", nchars_printed);
	return nchars_printed;
}
int StringBuffer_vsnprintf ( StringBuffer * buffer , size_t offset , const char * format , va_list args ) { if ( offset > buffer -> length ) { STRING_BUFFER_FERROR ( buffer , STRING_BUFFER_STATUS_ERROR_INVALID_ACCESS , " " , offset ) ; return CX_ERR ; } char * string_start = S_get ( buffer -> string , offset ) ; size_t nchars_available = buffer -> length - offset ; int nchars_printed ; va_list ap ; va_copy ( ap , args ) ; nchars_printed = vsnprintf ( string_start , nchars_available + 1 , format , ap ) ; va_end ( ap ) ; assert ( nchars_printed >= 0 ) ; if ( ( size_t ) nchars_printed > nchars_available ) { if ( StringBuffer_make_room ( buffer , offset , ( size_t ) nchars_printed ) ) { va_copy ( ap , args ) ; string_start = S_get ( buffer -> string , offset ) ; nchars_available = buffer -> length - offset ; nchars_printed = vsnprintf ( string_start , nchars_available + 1 , format , ap ) ; va_end ( ap ) ; assert ( ( size_t ) nchars_printed == nchars_available ) ; } else return CX_ERR ; } buffer -> string -> length = offset + ( size_t ) nchars_printed ; STRING_BUFFER_FDBG ( buffer , " " , nchars_printed ) ; return nchars_printed ; }
@return The number of printed characters or CX_ERR (-1) if an error occurred.
@return The number of printed characters or CX_ERR ( - 1 ) if an error occurred .
/* check that offset is within within range */ /* number of chars printed (excluding \0) */ /*
	 * vsnprintf never returns a negative value, instead
	 * it returns the number of characters that would have been printed
	 * if buffer would have been large enough.
	 *
	 * snprintf/vsnprintf maximum output size is restricted by the integer return type
	 * but the upper limit might be smaller.
	 * TODO check what happens when the output exceeds INT_MAX
	 * http://stackoverflow.com/questions/8119914/printf-fprintf-maximum-size-according-to-c99
	 */ /* c library bug */ /* if buffer was to small then grow buffer and repeat the procedure */ /* expand string buffer */ /* application bug */