* Fixed the semantics of [v]snprintf(): If the buffer is not large enough,
the function shall nevertheless return the length of the string that would be written, if the buffer were large enough. Added a touch of C++ while doing that. :-) * Fixed the instances in boot loader, kernel, and kernel modules where the wrong semantics were expected. The majority of uses actually. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34826 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3069ca963e
commit
3ce2634533
@ -7,6 +7,8 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
static char sTraceBuffer[256];
|
||||
static uint32 sTraceBufferOffset = 0;
|
||||
@ -15,11 +17,15 @@ static uint32 sTraceBufferOffset = 0;
|
||||
void
|
||||
ata_trace_printf(uint32 flags, const char *format, ...)
|
||||
{
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
sTraceBufferOffset += vsnprintf(sTraceBuffer + sTraceBufferOffset,
|
||||
sizeof(sTraceBuffer) - sTraceBufferOffset, format, arguments);
|
||||
va_end(arguments);
|
||||
if (sTraceBufferOffset < sizeof(sTraceBuffer)) {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
size_t totalBytes = vsnprintf(sTraceBuffer + sTraceBufferOffset,
|
||||
sizeof(sTraceBuffer) - sTraceBufferOffset, format, arguments);
|
||||
sTraceBufferOffset += std::min(totalBytes,
|
||||
sizeof(sTraceBuffer) - sTraceBufferOffset - 1);
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
if (flags & ATA_TRACE_FLUSH) {
|
||||
#if ATA_TRACING
|
||||
|
@ -7,9 +7,13 @@
|
||||
* Niels S. Reedijk
|
||||
*/
|
||||
|
||||
|
||||
#include "usb_p.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort,
|
||||
usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed,
|
||||
@ -386,18 +390,30 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize,
|
||||
status_t result = Device::BuildDeviceName(string, index, bufferSize, device);
|
||||
if (result < B_OK) {
|
||||
// recursion to parent failed, we're at the root(hub)
|
||||
int32 managerIndex = GetStack()->IndexOfBusManager(GetBusManager());
|
||||
*index += snprintf(string + *index, bufferSize - *index, "%ld", managerIndex);
|
||||
if (*index < bufferSize) {
|
||||
int32 managerIndex = GetStack()->IndexOfBusManager(GetBusManager());
|
||||
size_t totalBytes = snprintf(string + *index, bufferSize - *index,
|
||||
"%ld", managerIndex);
|
||||
*index += std::min(totalBytes, bufferSize - *index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!device) {
|
||||
// no device was specified - report the hub
|
||||
*index += snprintf(string + *index, bufferSize - *index, "/hub");
|
||||
if (*index < bufferSize) {
|
||||
size_t totalBytes = snprintf(string + *index, bufferSize - *index,
|
||||
"/hub");
|
||||
*index += std::min(totalBytes, bufferSize - *index - 1);
|
||||
}
|
||||
} else {
|
||||
// find out where the requested device sitts
|
||||
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
|
||||
if (fChildren[i] == device) {
|
||||
*index += snprintf(string + *index, bufferSize - *index, "/%ld", i);
|
||||
if (*index < bufferSize) {
|
||||
size_t totalBytes = snprintf(string + *index,
|
||||
bufferSize - *index, "/%ld", i);
|
||||
*index += std::min(totalBytes, bufferSize - *index - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -276,6 +276,7 @@ log_writer_daemon(void *arg, int /*iteration*/)
|
||||
log->team, log->timestamp, log->team_name,
|
||||
log->device, log->parent, log->launch.parent,
|
||||
log->launch.args[0]);
|
||||
length = std::min(length, (ssize_t)sizeof(line) - 1);
|
||||
|
||||
for (int32 j = 1; j < log->launch.arg_count; j++) {
|
||||
// write argument list one by one, so that we can deal
|
||||
@ -302,12 +303,14 @@ log_writer_daemon(void *arg, int /*iteration*/)
|
||||
length = snprintf(line, sizeof(line), "%ld: %Ld \"%s\" c%d %ld:%Ld %ld\n",
|
||||
log->team, log->timestamp, log->team_name, log->type,
|
||||
log->device, log->node, log->access_type);
|
||||
length = std::min(length, (ssize_t)sizeof(line) - 1);
|
||||
break;
|
||||
|
||||
default: // open, ?
|
||||
length = snprintf(line, sizeof(line), "%ld: %Ld \"%s\" %c%d %ld:%Ld:%Ld:\"%s\"\n",
|
||||
log->team, log->timestamp, log->team_name, log->action, log->type, log->device,
|
||||
log->parent, log->node, log->file_name);
|
||||
length = std::min(length, (ssize_t)sizeof(line) - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "RootFileSystem.h"
|
||||
#include "load_driver_settings.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <util/kernel_cpp.h>
|
||||
@ -503,8 +505,9 @@ apply_safe_mode_options(Menu *menu)
|
||||
|| item->Data() == NULL || (uint32)pos > sizeof(buffer))
|
||||
continue;
|
||||
|
||||
pos += snprintf(buffer + pos, sizeof(buffer) - pos, "%s true\n",
|
||||
(const char *)item->Data());
|
||||
size_t totalBytes = snprintf(buffer + pos, sizeof(buffer) - pos,
|
||||
"%s true\n", (const char *)item->Data());
|
||||
pos += std::min(totalBytes, sizeof(buffer) - pos - 1);
|
||||
}
|
||||
|
||||
add_safe_mode_settings(buffer);
|
||||
|
@ -11,6 +11,9 @@
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
//#undef stdout
|
||||
//#undef stdin
|
||||
//extern FILE *stdout;
|
||||
@ -28,6 +31,7 @@ vfprintf(FILE *file, const char *format, va_list list)
|
||||
// the buffer handling could (or should) be done better...
|
||||
|
||||
int length = vsnprintf(buffer, sizeof(buffer), format, list);
|
||||
length = std::min(length, (int)sizeof(buffer) - 1);
|
||||
if (length > 0)
|
||||
node->Write(buffer, length);
|
||||
|
||||
@ -77,7 +81,7 @@ fputc(int c, FILE *file)
|
||||
status_t status;
|
||||
char character = (char)c;
|
||||
|
||||
// we only support direct console output right now...
|
||||
// we only support direct console output right now...
|
||||
status = ((ConsoleNode *)file)->Write(&character, 1);
|
||||
|
||||
if (status > 0)
|
||||
|
@ -21,7 +21,6 @@ panic(const char *format, ...)
|
||||
const char greetings[] = "\n*** PANIC ***";
|
||||
char buffer[512];
|
||||
va_list list;
|
||||
int length;
|
||||
|
||||
//platform_switch_to_text_mode();
|
||||
|
||||
@ -31,7 +30,7 @@ panic(const char *format, ...)
|
||||
nat_feat_debugprintf("\n");
|
||||
|
||||
va_start(list, format);
|
||||
length = vsnprintf(buffer, sizeof(buffer), format, list);
|
||||
vsnprintf(buffer, sizeof(buffer), format, list);
|
||||
va_end(list);
|
||||
|
||||
Bconputs(DEV_CONSOLE, buffer);
|
||||
@ -52,10 +51,9 @@ dprintf(const char *format, ...)
|
||||
{
|
||||
char buffer[512];
|
||||
va_list list;
|
||||
int length;
|
||||
|
||||
va_start(list, format);
|
||||
length = vsnprintf(buffer, sizeof(buffer), format, list);
|
||||
vsnprintf(buffer, sizeof(buffer), format, list);
|
||||
va_end(list);
|
||||
|
||||
Bconput(DEV_AUX, buffer);
|
||||
|
@ -46,6 +46,9 @@ dprintf(const char *format, ...)
|
||||
length = vsnprintf(buffer, sizeof(buffer), format, list);
|
||||
va_end(list);
|
||||
|
||||
if (length >= (int)sizeof(buffer))
|
||||
length = sizeof(buffer) - 1;
|
||||
|
||||
serial_puts(buffer, length);
|
||||
|
||||
if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT)
|
||||
|
@ -46,6 +46,9 @@ dprintf(const char *format, ...)
|
||||
length = vsnprintf(buffer, sizeof(buffer), format, list);
|
||||
va_end(list);
|
||||
|
||||
if (length >= (int)sizeof(buffer))
|
||||
length = sizeof(buffer) - 1;
|
||||
|
||||
serial_puts(buffer, length);
|
||||
|
||||
if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT)
|
||||
|
@ -1169,7 +1169,8 @@ syslog_init(struct kernel_args* args)
|
||||
length = snprintf(revisionBuffer, sizeof(revisionBuffer),
|
||||
"Welcome to syslog debug output!\nHaiku revision: %lu\n",
|
||||
get_haiku_revision());
|
||||
syslog_write(revisionBuffer, length);
|
||||
syslog_write(revisionBuffer,
|
||||
std::min(length, (ssize_t)sizeof(revisionBuffer) - 1));
|
||||
|
||||
add_debugger_command_etc("syslog", &cmd_dump_syslog,
|
||||
"Dumps the syslog buffer.",
|
||||
@ -1267,6 +1268,7 @@ flush_pending_repeats(bool syslogOutput)
|
||||
static char temp[40];
|
||||
size_t length = snprintf(temp, sizeof(temp),
|
||||
"Last message repeated %ld times.\n", sMessageRepeatCount);
|
||||
length = std::min(length, sizeof(temp) - 1);
|
||||
|
||||
if (sSerialDebugEnabled)
|
||||
arch_debug_serial_puts(temp);
|
||||
@ -1328,8 +1330,9 @@ dprintf_args(const char* format, va_list args, bool syslogOutput)
|
||||
if (are_interrupts_enabled()) {
|
||||
MutexLocker locker(sOutputLock);
|
||||
|
||||
int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE,
|
||||
format, args);
|
||||
int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format,
|
||||
args);
|
||||
length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
|
||||
|
||||
InterruptsSpinLocker _(sSpinlock);
|
||||
debug_output(sOutputBuffer, length, syslogOutput);
|
||||
@ -1338,6 +1341,7 @@ dprintf_args(const char* format, va_list args, bool syslogOutput)
|
||||
|
||||
int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE,
|
||||
format, args);
|
||||
length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
|
||||
|
||||
debug_output(sInterruptOutputBuffer, length, syslogOutput);
|
||||
}
|
||||
|
@ -7,12 +7,15 @@
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include "debug_commands.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <debug.h>
|
||||
@ -111,8 +114,12 @@ public:
|
||||
return;
|
||||
|
||||
// print directly into the buffer
|
||||
fBufferSize += vsnprintf(fBuffer + fBufferSize,
|
||||
fBufferCapacity - fBufferSize, format, args);
|
||||
if (fBufferSize < fBufferCapacity) {
|
||||
size_t totalBytes = vsnprintf(fBuffer + fBufferSize,
|
||||
fBufferCapacity - fBufferSize, format, args);
|
||||
fBufferSize += std::min(totalBytes,
|
||||
fBufferCapacity - fBufferSize - 1);
|
||||
}
|
||||
|
||||
// execute every complete line
|
||||
fBuffer[fBufferSize] = '\0';
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <arch/debug.h>
|
||||
#include <debug.h>
|
||||
#include <elf.h>
|
||||
@ -596,10 +598,14 @@ TraceOutput::Print(const char* format,...)
|
||||
if (IsFull())
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
fSize += vsnprintf(fBuffer + fSize, fCapacity - fSize, format, args);
|
||||
va_end(args);
|
||||
if (fSize < fCapacity) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
size_t length = vsnprintf(fBuffer + fSize, fCapacity - fSize, format,
|
||||
args);
|
||||
fSize += std::min(length, fCapacity - fSize - 1);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2003-2008, Axel Dörfler. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
@ -9,10 +10,12 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
@ -26,6 +29,73 @@
|
||||
#define FLOATING_SUPPORT
|
||||
|
||||
|
||||
struct Buffer {
|
||||
Buffer(char* buffer, size_t size)
|
||||
:
|
||||
fCurrent(buffer),
|
||||
fSize(size),
|
||||
fBytesWritten(0)
|
||||
{
|
||||
}
|
||||
|
||||
size_t BytesWritten() const
|
||||
{
|
||||
return fBytesWritten;
|
||||
}
|
||||
|
||||
void PutCharacter(char c)
|
||||
{
|
||||
if (fBytesWritten < fSize) {
|
||||
*fCurrent = c;
|
||||
fCurrent++;
|
||||
}
|
||||
|
||||
fBytesWritten++;
|
||||
}
|
||||
|
||||
void PutPadding(int32 count)
|
||||
{
|
||||
if (count <= 0)
|
||||
return;
|
||||
|
||||
if (fBytesWritten < fSize) {
|
||||
int32 toWrite = std::min(fSize - fBytesWritten, (size_t)count);
|
||||
while (--toWrite >= 0)
|
||||
*fCurrent++ = ' ';
|
||||
}
|
||||
|
||||
fBytesWritten += count;
|
||||
}
|
||||
|
||||
void PutString(const char *source, int32 length)
|
||||
{
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (fBytesWritten < fSize) {
|
||||
int32 toWrite = std::min(fSize - fBytesWritten, (size_t)length);
|
||||
memcpy(fCurrent, source, toWrite);
|
||||
fCurrent += toWrite;
|
||||
}
|
||||
|
||||
fBytesWritten += length;
|
||||
}
|
||||
|
||||
void NullTerminate()
|
||||
{
|
||||
if (fBytesWritten < fSize)
|
||||
*fCurrent = '\0';
|
||||
else if (fSize > 0)
|
||||
fCurrent[-1] = '\0';
|
||||
}
|
||||
|
||||
private:
|
||||
char* fCurrent;
|
||||
size_t fSize;
|
||||
size_t fBytesWritten;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
skip_atoi(const char **s)
|
||||
{
|
||||
@ -48,88 +118,6 @@ do_div(uint64 *_number, uint32 base)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
put_padding(char **_buffer, int32 *_bytesLeft, int32 count)
|
||||
{
|
||||
int32 left = *_bytesLeft;
|
||||
char *string = *_buffer;
|
||||
int32 written;
|
||||
bool allWritten;
|
||||
|
||||
if (count <= 0)
|
||||
return true;
|
||||
if (left == 0)
|
||||
return false;
|
||||
|
||||
if (left < count) {
|
||||
count = left;
|
||||
allWritten = false;
|
||||
} else
|
||||
allWritten = true;
|
||||
|
||||
written = count;
|
||||
|
||||
while (count-- > 0)
|
||||
*string++ = ' ';
|
||||
|
||||
*_buffer = string;
|
||||
*_bytesLeft = left - written;
|
||||
|
||||
return allWritten;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
put_string(char **_buffer, int32 *_bytesLeft, const char *source, int32 length)
|
||||
{
|
||||
int32 left = *_bytesLeft;
|
||||
char *target = *_buffer;
|
||||
bool allWritten;
|
||||
|
||||
if (length == 0)
|
||||
return true;
|
||||
if (left == 0)
|
||||
return false;
|
||||
|
||||
if (left < length) {
|
||||
length = left;
|
||||
allWritten = false;
|
||||
} else
|
||||
allWritten = true;
|
||||
|
||||
#if 0
|
||||
// take care of string arguments in user space
|
||||
if (CHECK_USER_ADDRESS(source)) {
|
||||
if (user_memcpy(target, source, length) < B_OK)
|
||||
return put_string(_buffer, _bytesLeft, "<FAULT>", 7);
|
||||
} else
|
||||
#endif
|
||||
memcpy(target, source, length);
|
||||
|
||||
*_bytesLeft = left - length;
|
||||
*_buffer = target + length;
|
||||
|
||||
return allWritten;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
put_character(char **_buffer, int32 *_bytesLeft, char c)
|
||||
{
|
||||
int32 left = *_bytesLeft;
|
||||
char *string = *_buffer;
|
||||
|
||||
if (left > 0) {
|
||||
*string++ = c;
|
||||
*_buffer = string;
|
||||
*_bytesLeft = left - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static char
|
||||
sign_symbol(int flags, bool negative)
|
||||
{
|
||||
@ -148,7 +136,7 @@ sign_symbol(int flags, bool negative)
|
||||
|
||||
|
||||
static void
|
||||
number(char **_string, int32 *_bytesLeft, uint64 num, uint32 base, int size,
|
||||
number(Buffer& outBuffer, uint64 num, uint32 base, int size,
|
||||
int precision, int flags)
|
||||
{
|
||||
const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
@ -191,31 +179,31 @@ number(char **_string, int32 *_bytesLeft, uint64 num, uint32 base, int size,
|
||||
size -= precision;
|
||||
|
||||
if (!(flags & (ZEROPAD + LEFT))) {
|
||||
put_padding(_string, _bytesLeft, size);
|
||||
outBuffer.PutPadding(size);
|
||||
size = 0;
|
||||
}
|
||||
if (sign)
|
||||
put_character(_string, _bytesLeft, sign);
|
||||
outBuffer.PutCharacter(sign);
|
||||
|
||||
if ((flags & SPECIAL) != 0) {
|
||||
if (base == 8)
|
||||
put_character(_string, _bytesLeft, '0');
|
||||
outBuffer.PutCharacter('0');
|
||||
else if (base == 16) {
|
||||
put_character(_string, _bytesLeft, '0');
|
||||
put_character(_string, _bytesLeft, digits[33]);
|
||||
outBuffer.PutCharacter('0');
|
||||
outBuffer.PutCharacter(digits[33]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & LEFT)) {
|
||||
while (size-- > 0)
|
||||
put_character(_string, _bytesLeft, c);
|
||||
outBuffer.PutCharacter(c);
|
||||
}
|
||||
while (i < precision--)
|
||||
put_character(_string, _bytesLeft, '0');
|
||||
outBuffer.PutCharacter('0');
|
||||
while (i-- > 0)
|
||||
put_character(_string, _bytesLeft, tmp[i]);
|
||||
outBuffer.PutCharacter(tmp[i]);
|
||||
|
||||
put_padding(_string, _bytesLeft, size);
|
||||
outBuffer.PutPadding(size);
|
||||
}
|
||||
|
||||
|
||||
@ -225,9 +213,8 @@ number(char **_string, int32 *_bytesLeft, uint64 num, uint32 base, int size,
|
||||
It prints up to 3 fraction digits, and doesn't support any precision arguments.
|
||||
It's just here for your convenience so that you can use it for debug output.
|
||||
*/
|
||||
static bool
|
||||
floating(char **_string, int32 *_bytesLeft, double value, int fieldWidth,
|
||||
int flags)
|
||||
static void
|
||||
floating(Buffer& outBuffer, double value, int fieldWidth, int flags)
|
||||
{
|
||||
char buffer[66];
|
||||
uint64 fraction;
|
||||
@ -259,29 +246,26 @@ floating(char **_string, int32 *_bytesLeft, double value, int fieldWidth,
|
||||
|
||||
// put integer part
|
||||
|
||||
if (integer == 0)
|
||||
if (integer == 0) {
|
||||
buffer[length++] = '0';
|
||||
else while (integer != 0) {
|
||||
buffer[length++] = '0' + do_div(&integer, 10);
|
||||
} else {
|
||||
while (integer != 0)
|
||||
buffer[length++] = '0' + do_div(&integer, 10);
|
||||
}
|
||||
|
||||
// write back to string
|
||||
|
||||
if (!(flags & LEFT) && !put_padding(_string, _bytesLeft, fieldWidth))
|
||||
return false;
|
||||
if (!(flags & LEFT))
|
||||
outBuffer.PutPadding(fieldWidth);
|
||||
|
||||
if (sign && !put_character(_string, _bytesLeft, sign))
|
||||
return false;
|
||||
if (sign)
|
||||
outBuffer.PutCharacter(sign);
|
||||
|
||||
while (length-- > 0) {
|
||||
if (!put_character(_string, _bytesLeft, buffer[length]))
|
||||
return false;
|
||||
}
|
||||
while (length-- > 0)
|
||||
outBuffer.PutCharacter(buffer[length]);
|
||||
|
||||
if ((flags & LEFT) != 0 && !put_padding(_string, _bytesLeft, fieldWidth))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
if ((flags & LEFT) != 0)
|
||||
outBuffer.PutPadding(fieldWidth);
|
||||
}
|
||||
#endif // FLOATING_SUPPORT
|
||||
|
||||
@ -289,28 +273,19 @@ floating(char **_string, int32 *_bytesLeft, double value, int fieldWidth,
|
||||
int
|
||||
vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
{
|
||||
int32 bytesLeft;
|
||||
uint64 num;
|
||||
int base;
|
||||
char *string;
|
||||
int flags; /* flags to number() */
|
||||
int fieldWidth; /* width of output field */
|
||||
int precision;
|
||||
/* min. # of digits for integers; max number of chars for from string */
|
||||
int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
||||
|
||||
if (bufferSize == 0)
|
||||
return 0;
|
||||
Buffer outBuffer(buffer, bufferSize);
|
||||
|
||||
bytesLeft = ((int32)bufferSize - 1) & 0x7fffffff;
|
||||
// make space for the terminating '\0' byte, and we
|
||||
// only allow 2G characters :)
|
||||
|
||||
for (string = buffer; format[0] && bytesLeft > 0; format++) {
|
||||
for (; format[0]; format++) {
|
||||
if (format[0] != '%') {
|
||||
if (!put_character(&string, &bytesLeft, format[0]))
|
||||
break;
|
||||
|
||||
outBuffer.PutCharacter(format[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -329,8 +304,7 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
case '0': flags |= ZEROPAD; goto repeat;
|
||||
|
||||
case '%':
|
||||
if (!put_character(&string, &bytesLeft, format[0]))
|
||||
break;
|
||||
outBuffer.PutCharacter(format[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -384,15 +358,13 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
|
||||
switch (format[0]) {
|
||||
case 'c':
|
||||
if (!(flags & LEFT) && !put_padding(&string, &bytesLeft,
|
||||
fieldWidth - 1))
|
||||
goto out;
|
||||
if (!(flags & LEFT))
|
||||
outBuffer.PutPadding(fieldWidth - 1);
|
||||
|
||||
put_character(&string, &bytesLeft, (char)va_arg(args, int));
|
||||
outBuffer.PutCharacter((char)va_arg(args, int));
|
||||
|
||||
if ((flags & LEFT) != 0 && !put_padding(&string, &bytesLeft,
|
||||
fieldWidth - 1))
|
||||
goto out;
|
||||
if ((flags & LEFT) != 0)
|
||||
outBuffer.PutPadding(fieldWidth - 1);
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
@ -406,16 +378,13 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
length = strnlen(argument, precision);
|
||||
fieldWidth -= length;
|
||||
|
||||
if (!(flags & LEFT) && !put_padding(&string, &bytesLeft,
|
||||
fieldWidth))
|
||||
goto out;
|
||||
if (!(flags & LEFT))
|
||||
outBuffer.PutPadding(fieldWidth);
|
||||
|
||||
if (!put_string(&string, &bytesLeft, argument, length))
|
||||
goto out;
|
||||
outBuffer.PutString(argument, length);
|
||||
|
||||
if ((flags & LEFT) != 0 && !put_padding(&string, &bytesLeft,
|
||||
fieldWidth))
|
||||
goto out;
|
||||
if ((flags & LEFT) != 0)
|
||||
outBuffer.PutPadding(fieldWidth);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -426,9 +395,7 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
case 'G':
|
||||
{
|
||||
double value = va_arg(args, double);
|
||||
if (!floating(&string, &bytesLeft, value, fieldWidth,
|
||||
flags | SIGN))
|
||||
goto out;
|
||||
floating(outBuffer, value, fieldWidth, flags | SIGN);
|
||||
continue;
|
||||
}
|
||||
#endif // FLOATING_SUPPORT
|
||||
@ -439,19 +406,18 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
flags |= ZEROPAD;
|
||||
}
|
||||
|
||||
if (!put_string(&string, &bytesLeft, "0x", 2))
|
||||
goto out;
|
||||
number(&string, &bytesLeft, (uint32)va_arg(args, void *), 16,
|
||||
fieldWidth, precision, flags);
|
||||
outBuffer.PutString("0x", 2);
|
||||
number(outBuffer, (uint32)va_arg(args, void *), 16, fieldWidth,
|
||||
precision, flags);
|
||||
continue;
|
||||
|
||||
case 'n':
|
||||
if (qualifier == 'l') {
|
||||
long *ip = va_arg(args, long *);
|
||||
*ip = (string - buffer);
|
||||
*ip = outBuffer.BytesWritten();
|
||||
} else {
|
||||
int *ip = va_arg(args, int *);
|
||||
*ip = (string - buffer);
|
||||
*ip = outBuffer.BytesWritten();
|
||||
}
|
||||
continue;
|
||||
|
||||
@ -474,12 +440,12 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
|
||||
default:
|
||||
if (format[0] != '%')
|
||||
put_character(&string, &bytesLeft, '%');
|
||||
outBuffer.PutCharacter('%');
|
||||
|
||||
if (!format[0])
|
||||
goto out;
|
||||
|
||||
put_character(&string, &bytesLeft, format[0]);
|
||||
outBuffer.PutCharacter(format[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -498,12 +464,12 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
else
|
||||
num = va_arg(args, unsigned int);
|
||||
|
||||
number(&string, &bytesLeft, num, base, fieldWidth, precision, flags);
|
||||
number(outBuffer, num, base, fieldWidth, precision, flags);
|
||||
}
|
||||
|
||||
out:
|
||||
*string = '\0';
|
||||
return string - buffer;
|
||||
outBuffer.NullTerminate();
|
||||
return outBuffer.BytesWritten();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user