Update printf family to current coding conventions.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-12-01 22:16:55 +01:00
parent b5f9876089
commit 8b03a9ab94
5 changed files with 122 additions and 105 deletions

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2014.
Copyright(C) Jonas 'Sortie' Termansen 2014, 2015.
This file is part of the Sortix C Library.
@ -27,37 +27,35 @@
#include <string.h>
#include <stdlib.h>
struct vasprintf_state
struct vasprintf
{
char* string;
size_t string_length;
size_t string_used;
char* buffer;
size_t used;
size_t size;
};
static size_t vasprintf_callback(void* user, const char* string, size_t length)
static size_t vasprintf_callback(void* ctx, const char* string, size_t length)
{
struct vasprintf_state* state = (struct vasprintf_state*) user;
if ( !state->string )
return 0;
size_t needed_length = state->string_used + length + 1;
if ( state->string_length < needed_length )
struct vasprintf* state = (struct vasprintf*) ctx;
size_t needed_size = state->used + length + 1;
if ( state->size < needed_size )
{
size_t new_length = 2 * state->string_used;
if ( new_length < needed_length )
new_length = needed_length;
size_t new_size = new_length * sizeof(char);
char* new_string = (char*) realloc(state->string, new_size);
if ( !new_string )
// TODO: Overflow check.
size_t new_size = 2 * state->size;
if ( new_size < needed_size )
new_size = needed_size;
char* new_buffer = (char*) realloc(state->buffer, new_size);
if ( !new_buffer )
{
free(state->string);
state->string = NULL;
free(state->buffer);
state->buffer = NULL;
return 0;
}
state->string = new_string;
state->string_length = new_length;
state->buffer = new_buffer;
state->size = new_size;
}
memcpy(state->string + state->string_used, string, sizeof(char) * length);
state->string_used += length;
memcpy(state->buffer + state->used, string, length);
state->used += length;
return length;
}
@ -66,15 +64,14 @@ int vasprintf(char** restrict result_ptr,
const char* restrict format,
va_list list)
{
const size_t DEFAULT_SIZE = 32;
struct vasprintf_state state;
state.string_length = DEFAULT_SIZE;
state.string_used = 0;
if ( !(state.string = (char*) malloc(state.string_length * sizeof(char))) )
return *result_ptr = NULL, -1;
struct vasprintf state;
state.used = 0;
state.size = 32;
if ( !(state.buffer = (char*) malloc(state.size)) )
return -1;
int result = vcbprintf(&state, vasprintf_callback, format, list);
if ( !state.string )
return *result_ptr = NULL, -1;
state.string[state.string_used] = '\0';
return *result_ptr = state.string, result;
if ( !state.buffer )
return -1;
state.buffer[state.used] = '\0';
return *result_ptr = state.buffer, result;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of the Sortix C Library.
@ -39,8 +39,10 @@ static size_t convert_integer(char* destination, uintmax_t value,
while ( base <= copy )
copy /= base, result++;
for ( size_t i = result; i != 0; i-- )
destination[i-1] = digits[value % base],
{
destination[i-1] = digits[value % base];
value /= base;
}
return result;
}
@ -49,16 +51,8 @@ static size_t noop_callback(void*, const char*, size_t amount)
return amount;
}
static inline
size_t callback_character(void* user,
size_t (*callback)(void*, const char*, size_t),
char c)
{
return callback(user, &c, 1);
}
extern "C"
int vcbprintf(void* user,
int vcbprintf(void* ctx,
size_t (*callback)(void*, const char*, size_t),
const char* format,
va_list parameters)
@ -77,7 +71,7 @@ int vcbprintf(void* user,
size_t amount = 1;
while ( format[amount] && format[amount] != '%' )
amount++;
if ( callback(user, format, amount) != amount )
if ( callback(ctx, format, amount) != amount )
return -1;
format += amount;
written += amount;
@ -106,9 +100,6 @@ int vcbprintf(void* user,
bool group_thousands = false;
bool alternate_output_digits = false;
(void) group_thousands;
(void) alternate_output_digits;
while ( true )
{
switch ( *format++ )
@ -125,6 +116,9 @@ int vcbprintf(void* user,
break;
}
(void) group_thousands;
(void) alternate_output_digits;
int field_width = 0;
if ( *format == '*' && (format++, true) )
field_width = va_arg(parameters, int);
@ -143,14 +137,15 @@ int vcbprintf(void* user,
int int_precision = va_arg(parameters, int);
precision = 0 <= int_precision ? (size_t) int_precision : 0;
}
else if ( *format == '-' && (format++, true) )
{
while ( '0' <= *format && *format <= '9' )
format++;
}
else
{
if ( *format == '-' && (format++, true) )
while ( '0' <= *format && *format <= '9' )
format++;
else
while ( '0' <= *format && *format <= '9' )
precision = 10 * precision + *format++ - '0';
while ( '0' <= *format && *format <= '9' )
precision = 10 * precision + *format++ - '0';
}
}
@ -281,8 +276,10 @@ int vcbprintf(void* user,
else if ( prepend_blank_if_positive )
prefix[prefix_length++] = ' ';
if ( alternate && (conversion == 'x' || conversion == 'X') && value != 0 )
prefix[prefix_digits_length++, prefix_length++] = '0',
{
prefix[prefix_digits_length++, prefix_length++] = '0';
prefix[prefix_digits_length++, prefix_length++] = conversion;
}
if ( alternate && conversion == 'o' && value != 0 )
prefix[prefix_digits_length++, prefix_length++] = '0';
@ -308,35 +305,47 @@ int vcbprintf(void* user,
bool use_right_pad = !use_zero_pad && field_width < 0;
if ( use_left_pad )
{
for ( size_t i = length_with_precision; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 )
{
if ( callback(ctx, " ", 1) != 1 )
return -1;
else
written++;
if ( callback(user, prefix, prefix_length) != prefix_length )
written++;
}
}
if ( callback(ctx, prefix, prefix_length) != prefix_length )
return -1;
written += prefix_length;
if ( use_zero_pad )
{
for ( size_t i = normal_length; i < abs_field_width; i++ )
if ( callback_character(user, callback, '0') != 1 )
{
if ( callback(ctx, "0", 1) != 1 )
return -1;
else
written++;
written++;
}
}
if ( use_precision )
{
for ( size_t i = digits_length; i < precision; i++ )
if ( callback_character(user, callback, '0') != 1 )
{
if ( callback(ctx, "0", 1) != 1 )
return -1;
else
written++;
if ( callback(user, output, output_length) != output_length )
written++;
}
}
if ( callback(ctx, output, output_length) != output_length )
return -1;
written += output_length;
if ( use_right_pad )
{
for ( size_t i = length_with_precision; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 )
{
if ( callback(ctx, " ", 1) != 1 )
return -1;
else
written++;
written++;
}
}
}
#if !defined(__is_sortix_kernel)
else if ( *format == 'e' || *format == 'E' ||
@ -376,22 +385,28 @@ int vcbprintf(void* user,
goto incomprehensible_conversion;
if ( !field_width_is_negative && 1 < abs_field_width )
{
for ( size_t i = 1; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 )
{
if ( callback(ctx, " ", 1) != 1 )
return -1;
else
written++;
written++;
}
}
if ( callback(user, &c, 1) != 1 )
if ( callback(ctx, &c, 1) != 1 )
return -1;
written++;
if ( field_width_is_negative && 1 < abs_field_width )
{
for ( size_t i = 1; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 )
{
if ( callback(ctx, " ", 1) != 1 )
return -1;
else
written++;
written++;
}
}
}
else if ( *format == 'm' || *format == 's' )
{
@ -419,22 +434,28 @@ int vcbprintf(void* user,
string_length++;
if ( !field_width_is_negative && string_length < abs_field_width )
{
for ( size_t i = string_length; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 )
{
if ( callback(ctx, " ", 1) != 1 )
return -1;
else
written++;
written++;
}
}
if ( callback(user, string, string_length) != string_length )
if ( callback(ctx, string, string_length) != string_length )
return -1;
written += string_length;
if ( field_width_is_negative && string_length < abs_field_width )
{
for ( size_t i = string_length; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 )
{
if ( callback(ctx, " ", 1) != 1 )
return -1;
else
written++;
written++;
}
}
}
else if ( *format == 'n' && (format++, true) )
@ -463,7 +484,7 @@ int vcbprintf(void* user,
}
if ( INT_MAX < written )
return INT_MAX;
return -1;
return written;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
This file is part of the Sortix C Library.
@ -28,12 +28,12 @@
#include <stdint.h>
#include <unistd.h>
static size_t write_callback(void* user, const char* string, size_t stringlen)
static size_t vdprintf_callback(void* fdptr, const char* string, size_t length)
{
return writeall((int) (uintptr_t) user, string, stringlen);
return writeall(*(int*) fdptr, string, length);
}
extern "C" int vdprintf(int fd, const char* restrict format, va_list list)
{
return vcbprintf((void*) (uintptr_t) fd, write_callback, format, list);
return vcbprintf(&fd, vdprintf_callback, format, list);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of the Sortix C Library.
@ -27,16 +27,15 @@
#include <stdio.h>
#include <stdint.h>
static size_t FileWriteCallback(void* user, const char* string, size_t stringlen)
static size_t vfprintf_callback(void* ctx, const char* string, size_t length)
{
return fwrite_unlocked(string, 1, stringlen, (FILE*) user);
return fwrite_unlocked(string, 1, length, (FILE*) ctx);
}
extern "C"
int vfprintf_unlocked(FILE* fp, const char* restrict format, va_list list)
{
if ( !(fp->flags & _FILE_WRITABLE) )
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF;
return vcbprintf(fp, FileWriteCallback, format, list);
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, -1;
return vcbprintf(fp, vfprintf_callback, format, list);
}

View File

@ -35,13 +35,13 @@ struct vsnprintf
static size_t vsnprintf_callback(void* ctx, const char* string, size_t length)
{
struct vsnprintf* info = (struct vsnprintf*) ctx;
if ( 1 <= info->size && info->written < info->size )
struct vsnprintf* state = (struct vsnprintf*) ctx;
if ( 1 <= state->size && state->written < state->size )
{
size_t available = info->size - info->written;
size_t available = state->size - state->written;
size_t possible = length < available ? length : available;
memcpy(info->str + info->written, string, possible);
info->written += possible;
memcpy(state->str + state->written, string, possible);
state->written += possible;
}
return length;
}
@ -52,12 +52,12 @@ int vsnprintf(char* restrict str,
const char* restrict format,
va_list list)
{
struct vsnprintf info;
info.str = str;
info.size = size ? size - 1 : 0;
info.written = 0;
int result = vcbprintf(&info, vsnprintf_callback, format, list);
struct vsnprintf state;
state.str = str;
state.size = size ? size - 1 : 0;
state.written = 0;
int result = vcbprintf(&state, vsnprintf_callback, format, list);
if ( 1 <= size )
info.str[info.written] = '\0';
state.str[state.written] = '\0';
return result;
}