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. This file is part of the Sortix C Library.
@ -27,37 +27,35 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
struct vasprintf_state struct vasprintf
{ {
char* string; char* buffer;
size_t string_length; size_t used;
size_t string_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; struct vasprintf* state = (struct vasprintf*) ctx;
if ( !state->string ) size_t needed_size = state->used + length + 1;
return 0; if ( state->size < needed_size )
size_t needed_length = state->string_used + length + 1;
if ( state->string_length < needed_length )
{ {
size_t new_length = 2 * state->string_used; // TODO: Overflow check.
if ( new_length < needed_length ) size_t new_size = 2 * state->size;
new_length = needed_length; if ( new_size < needed_size )
size_t new_size = new_length * sizeof(char); new_size = needed_size;
char* new_string = (char*) realloc(state->string, new_size); char* new_buffer = (char*) realloc(state->buffer, new_size);
if ( !new_string ) if ( !new_buffer )
{ {
free(state->string); free(state->buffer);
state->string = NULL; state->buffer = NULL;
return 0; return 0;
} }
state->string = new_string; state->buffer = new_buffer;
state->string_length = new_length; state->size = new_size;
} }
memcpy(state->string + state->string_used, string, sizeof(char) * length); memcpy(state->buffer + state->used, string, length);
state->string_used += length; state->used += length;
return length; return length;
} }
@ -66,15 +64,14 @@ int vasprintf(char** restrict result_ptr,
const char* restrict format, const char* restrict format,
va_list list) va_list list)
{ {
const size_t DEFAULT_SIZE = 32; struct vasprintf state;
struct vasprintf_state state; state.used = 0;
state.string_length = DEFAULT_SIZE; state.size = 32;
state.string_used = 0; if ( !(state.buffer = (char*) malloc(state.size)) )
if ( !(state.string = (char*) malloc(state.string_length * sizeof(char))) ) return -1;
return *result_ptr = NULL, -1;
int result = vcbprintf(&state, vasprintf_callback, format, list); int result = vcbprintf(&state, vasprintf_callback, format, list);
if ( !state.string ) if ( !state.buffer )
return *result_ptr = NULL, -1; return -1;
state.string[state.string_used] = '\0'; state.buffer[state.used] = '\0';
return *result_ptr = state.string, result; 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. 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 ) while ( base <= copy )
copy /= base, result++; copy /= base, result++;
for ( size_t i = result; i != 0; i-- ) for ( size_t i = result; i != 0; i-- )
destination[i-1] = digits[value % base], {
destination[i-1] = digits[value % base];
value /= base; value /= base;
}
return result; return result;
} }
@ -49,16 +51,8 @@ static size_t noop_callback(void*, const char*, size_t amount)
return 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" extern "C"
int vcbprintf(void* user, int vcbprintf(void* ctx,
size_t (*callback)(void*, const char*, size_t), size_t (*callback)(void*, const char*, size_t),
const char* format, const char* format,
va_list parameters) va_list parameters)
@ -77,7 +71,7 @@ int vcbprintf(void* user,
size_t amount = 1; size_t amount = 1;
while ( format[amount] && format[amount] != '%' ) while ( format[amount] && format[amount] != '%' )
amount++; amount++;
if ( callback(user, format, amount) != amount ) if ( callback(ctx, format, amount) != amount )
return -1; return -1;
format += amount; format += amount;
written += amount; written += amount;
@ -106,9 +100,6 @@ int vcbprintf(void* user,
bool group_thousands = false; bool group_thousands = false;
bool alternate_output_digits = false; bool alternate_output_digits = false;
(void) group_thousands;
(void) alternate_output_digits;
while ( true ) while ( true )
{ {
switch ( *format++ ) switch ( *format++ )
@ -125,6 +116,9 @@ int vcbprintf(void* user,
break; break;
} }
(void) group_thousands;
(void) alternate_output_digits;
int field_width = 0; int field_width = 0;
if ( *format == '*' && (format++, true) ) if ( *format == '*' && (format++, true) )
field_width = va_arg(parameters, int); field_width = va_arg(parameters, int);
@ -143,14 +137,15 @@ int vcbprintf(void* user,
int int_precision = va_arg(parameters, int); int int_precision = va_arg(parameters, int);
precision = 0 <= int_precision ? (size_t) int_precision : 0; precision = 0 <= int_precision ? (size_t) int_precision : 0;
} }
else if ( *format == '-' && (format++, true) )
{
while ( '0' <= *format && *format <= '9' )
format++;
}
else else
{ {
if ( *format == '-' && (format++, true) ) while ( '0' <= *format && *format <= '9' )
while ( '0' <= *format && *format <= '9' ) precision = 10 * precision + *format++ - '0';
format++;
else
while ( '0' <= *format && *format <= '9' )
precision = 10 * precision + *format++ - '0';
} }
} }
@ -281,8 +276,10 @@ int vcbprintf(void* user,
else if ( prepend_blank_if_positive ) else if ( prepend_blank_if_positive )
prefix[prefix_length++] = ' '; prefix[prefix_length++] = ' ';
if ( alternate && (conversion == 'x' || conversion == 'X') && value != 0 ) 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; prefix[prefix_digits_length++, prefix_length++] = conversion;
}
if ( alternate && conversion == 'o' && value != 0 ) if ( alternate && conversion == 'o' && value != 0 )
prefix[prefix_digits_length++, prefix_length++] = '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; bool use_right_pad = !use_zero_pad && field_width < 0;
if ( use_left_pad ) if ( use_left_pad )
{
for ( size_t i = length_with_precision; i < abs_field_width; i++ ) 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; return -1;
else written++;
written++; }
if ( callback(user, prefix, prefix_length) != prefix_length ) }
if ( callback(ctx, prefix, prefix_length) != prefix_length )
return -1; return -1;
written += prefix_length; written += prefix_length;
if ( use_zero_pad ) if ( use_zero_pad )
{
for ( size_t i = normal_length; i < abs_field_width; i++ ) 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; return -1;
else written++;
written++; }
}
if ( use_precision ) if ( use_precision )
{
for ( size_t i = digits_length; i < precision; i++ ) for ( size_t i = digits_length; i < precision; i++ )
if ( callback_character(user, callback, '0') != 1 ) {
if ( callback(ctx, "0", 1) != 1 )
return -1; return -1;
else written++;
written++; }
if ( callback(user, output, output_length) != output_length ) }
if ( callback(ctx, output, output_length) != output_length )
return -1; return -1;
written += output_length; written += output_length;
if ( use_right_pad ) if ( use_right_pad )
{
for ( size_t i = length_with_precision; i < abs_field_width; i++ ) 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; return -1;
else written++;
written++; }
}
} }
#if !defined(__is_sortix_kernel) #if !defined(__is_sortix_kernel)
else if ( *format == 'e' || *format == 'E' || else if ( *format == 'e' || *format == 'E' ||
@ -376,22 +385,28 @@ int vcbprintf(void* user,
goto incomprehensible_conversion; goto incomprehensible_conversion;
if ( !field_width_is_negative && 1 < abs_field_width ) if ( !field_width_is_negative && 1 < abs_field_width )
{
for ( size_t i = 1; i < abs_field_width; i++ ) for ( size_t i = 1; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 ) {
if ( callback(ctx, " ", 1) != 1 )
return -1; return -1;
else written++;
written++; }
}
if ( callback(user, &c, 1) != 1 ) if ( callback(ctx, &c, 1) != 1 )
return -1; return -1;
written++; written++;
if ( field_width_is_negative && 1 < abs_field_width ) if ( field_width_is_negative && 1 < abs_field_width )
{
for ( size_t i = 1; i < abs_field_width; i++ ) for ( size_t i = 1; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 ) {
if ( callback(ctx, " ", 1) != 1 )
return -1; return -1;
else written++;
written++; }
}
} }
else if ( *format == 'm' || *format == 's' ) else if ( *format == 'm' || *format == 's' )
{ {
@ -419,22 +434,28 @@ int vcbprintf(void* user,
string_length++; string_length++;
if ( !field_width_is_negative && string_length < abs_field_width ) if ( !field_width_is_negative && string_length < abs_field_width )
{
for ( size_t i = string_length; i < abs_field_width; i++ ) for ( size_t i = string_length; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 ) {
if ( callback(ctx, " ", 1) != 1 )
return -1; return -1;
else written++;
written++; }
}
if ( callback(user, string, string_length) != string_length ) if ( callback(ctx, string, string_length) != string_length )
return -1; return -1;
written += string_length; written += string_length;
if ( field_width_is_negative && string_length < abs_field_width ) if ( field_width_is_negative && string_length < abs_field_width )
{
for ( size_t i = string_length; i < abs_field_width; i++ ) for ( size_t i = string_length; i < abs_field_width; i++ )
if ( callback_character(user, callback, ' ') != 1 ) {
if ( callback(ctx, " ", 1) != 1 )
return -1; return -1;
else written++;
written++; }
}
} }
else if ( *format == 'n' && (format++, true) ) else if ( *format == 'n' && (format++, true) )
@ -463,7 +484,7 @@ int vcbprintf(void* user,
} }
if ( INT_MAX < written ) if ( INT_MAX < written )
return INT_MAX; return -1;
return written; 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. This file is part of the Sortix C Library.
@ -28,12 +28,12 @@
#include <stdint.h> #include <stdint.h>
#include <unistd.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) 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. This file is part of the Sortix C Library.
@ -27,16 +27,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.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" extern "C"
int vfprintf_unlocked(FILE* fp, const char* restrict format, va_list list) int vfprintf_unlocked(FILE* fp, const char* restrict format, va_list list)
{ {
if ( !(fp->flags & _FILE_WRITABLE) ) if ( !(fp->flags & _FILE_WRITABLE) )
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF; return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, -1;
return vcbprintf(fp, vfprintf_callback, format, list);
return vcbprintf(fp, FileWriteCallback, format, list);
} }

View File

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