Add %o, %x and %X formats to *wprintf fallback implemnentation

darcs-hash:20060212112030-ac50b-1e3153c25dca3d2e12a8eb0e65da29bf70fa0d2e.gz
This commit is contained in:
axel 2006-02-12 21:20:30 +10:00
parent 5718ea41df
commit 7c7f744b4c
2 changed files with 147 additions and 108 deletions

View file

@ -41,6 +41,7 @@
#include "output.h"
#include "exec.h"
#include "event.h"
#include "halloc_util.h"
/**
Number of laps to run performance testing loop
@ -327,7 +328,7 @@ static void sb_test()
sb_init( &b );
if( res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " ) == -1 )
if( (res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " )) == -1 )
{
err( L"Error %d while testing stringbuffers", res );
}
@ -336,7 +337,22 @@ static void sb_test()
{
err( L"Error %d while testing stringbuffers", res );
}
say( (wchar_t *)b.buff );
sb_clear( &b );
#define NUM_ANS L"-7 99999999 1234567 deadbeef DEADBEEFDEADBEEF"
sb_printf( &b, L"%d %u %o %x %llX", -7, 99999999, 01234567, 0xdeadbeef, 0xdeadbeefdeadbeefll );
if( wcscmp( (wchar_t *)b.buff, NUM_ANS) != 0 )
{
err( L"numerical formating is broken, '%ls' != '%ls'", (wchar_t *)b.buff, NUM_ANS );
}
else
say( L"numerical formating works" );
}
/**
@ -533,7 +549,7 @@ static int expand_test( const wchar_t *in, int flags, ... )
wchar_t *arg;
al_init( &out );
expand_string( wcsdup(in), &out, flags);
expand_string( 0, wcsdup(in), &out, flags);
va_start( va, flags );
@ -669,7 +685,7 @@ int main( int argc, char **argv )
say( L"Lines beginning with '(ignore):' are not errors, they are warning messages\ngenerated by the fish parser library when given broken input, and can be\nignored. All actual errors begin with 'Error:'." );
proc_init();
output_init();
halloc_util_init();
event_init();
exec_init();
parser_init();
@ -701,7 +717,7 @@ int main( int argc, char **argv )
wutil_destroy();
exec_destroy();
event_destroy();
output_destroy();
proc_destroy();
halloc_util_destroy();
}

231
wutil.c
View file

@ -350,19 +350,18 @@ void pad( void (*writer)(wchar_t), int count)
are secretly a wrapper around this function. vgprintf does not
implement all the filters supported by printf, only those that are
currently used by fish. vgprintf internally uses snprintf to
implement the %f %d and %u filters.
implement the number outputs, such as %f and %x.
Currently supported functionality:
- precision specification, both through .* and .N
- width specification through * and N
- Padding through * and N
- Right padding using the - prefix
- long versions of all filters thorugh l and ll prefix
- Character outout using %c
- Character output using %c
- String output through %s
- Floating point number output through %f
- Integer output through %d or %i
- Unsigned integer output through %u
- Left padding using the - prefix
- Integer output through %d, %i, %u, %o, %x and %X
For a full description on the usage of *printf, see use 'man 3 printf'.
*/
@ -452,7 +451,7 @@ static int vgwprintf( void (*writer)(wchar_t),
count += maxi( width-1, 0 );
}
c = is_long?va_arg(va, wchar_t):btowc(va_arg(va, int));
c = is_long?va_arg(va, wint_t):btowc(va_arg(va, int));
if( precision != 0 )
writer( c );
@ -522,115 +521,138 @@ static int vgwprintf( void (*writer)(wchar_t),
case L'd':
case L'i':
{
char str[32];
char *pos;
switch( is_long )
{
case 0:
{
int d = va_arg( va, int );
if( precision >= 0 )
snprintf( str, 32, "%.*d", precision, d );
else
snprintf( str, 32, "%d", d );
break;
}
case 1:
{
long d = va_arg( va, long );
if( precision >= 0 )
snprintf( str, 32, "%.*ld", precision, d );
else
snprintf( str, 32, "%ld", d );
break;
}
case 2:
{
long long d = va_arg( va, long long );
if( precision >= 0 )
snprintf( str, 32, "%.*lld", precision, d );
else
snprintf( str, 32, "%lld", d );
break;
}
default:
return -1;
}
if( (width >= 0) && pad_left )
{
pad( writer, width-strlen(str) );
count +=maxi(width-strlen(str), 0 );
}
pos = str;
while( *pos )
{
writer( *(pos++) );
count++;
}
if( (width >= 0) && !pad_left )
{
pad( writer, width-strlen(str) );
count += maxi(width-strlen(str), 0 );
}
break;
}
case L'o':
case L'u':
case L'x':
case L'X':
{
char str[32];
char str[33];
char *pos;
char format[16];
int len;
format[0]=0;
strcat( format, "%");
if( precision >= 0 )
strcat( format, ".*" );
switch( is_long )
{
case 0:
{
unsigned d = va_arg( va, unsigned );
if( precision >= 0 )
snprintf( str, 32, "%.*u", precision, d );
else
snprintf( str, 32, "%u", d );
break;
}
case 1:
{
unsigned long d = va_arg( va, unsigned long );
if( precision >= 0 )
snprintf( str, 32, "%.*lu", precision, d );
else
snprintf( str, 32, "%lu", d );
break;
}
case 2:
{
unsigned long long d = va_arg( va, unsigned long long );
if( precision >= 0 )
snprintf( str, 32, "%.*llu", precision, d );
else
snprintf( str, 32, "%llu", d );
strcat( format, "ll" );
break;
case 1:
strcat( format, "l" );
break;
}
len = strlen(format);
format[len++]=(char)*filter;
format[len]=0;
switch( *filter )
{
case L'd':
case L'i':
{
switch( is_long )
{
case 0:
{
int d = va_arg( va, int );
if( precision >= 0 )
snprintf( str, 32, format, precision, d );
else
snprintf( str, 32, format, d );
break;
}
case 1:
{
long d = va_arg( va, long );
if( precision >= 0 )
snprintf( str, 32, format, precision, d );
else
snprintf( str, 32, format, d );
break;
}
case 2:
{
long long d = va_arg( va, long long );
if( precision >= 0 )
snprintf( str, 32, format, precision, d );
else
snprintf( str, 32, format, d );
break;
}
default:
debug( 0, L"Invalid length modifier in string %ls\n", filter_org );
return -1;
}
break;
}
case L'u':
case L'o':
case L'x':
case L'X':
{
switch( is_long )
{
case 0:
{
unsigned d = va_arg( va, unsigned );
if( precision >= 0 )
snprintf( str, 32, format, precision, d );
else
snprintf( str, 32, format, d );
break;
}
case 1:
{
unsigned long d = va_arg( va, unsigned long );
if( precision >= 0 )
snprintf( str, 32, format, precision, d );
else
snprintf( str, 32, format, d );
break;
}
case 2:
{
unsigned long long d = va_arg( va, unsigned long long );
if( precision >= 0 )
snprintf( str, 32, format, precision, d );
else
snprintf( str, 32, format, d );
break;
}
default:
debug( 0, L"Invalid length modifier in string %ls\n", filter_org );
return -1;
}
break;
}
default:
debug( 0, L"Invalid filter %ls in string %ls\n", *filter, filter_org );
return -1;
}
if( (width >= 0) && pad_left )
{
pad( writer, width-strlen(str) );
count += maxi( width-strlen(str), 0 );
int l = maxi(width-strlen(str), 0 );
pad( writer, l );
count += l;
}
pos = str;
@ -643,8 +665,9 @@ static int vgwprintf( void (*writer)(wchar_t),
if( (width >= 0) && !pad_left )
{
pad( writer, width-strlen(str) );
count += maxi( width-strlen(str), 0 );
int l = maxi(width-strlen(str), 0 );
pad( writer, l );
count += l;
}
break;
@ -705,7 +728,7 @@ static int vgwprintf( void (*writer)(wchar_t),
}
default:
debug( 0, L"Unknown switch %lc in string %ls\n", *filter, filter_org );
// exit(1);
return -1;
}
}
else