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 "output.h"
#include "exec.h" #include "exec.h"
#include "event.h" #include "event.h"
#include "halloc_util.h"
/** /**
Number of laps to run performance testing loop Number of laps to run performance testing loop
@ -327,7 +328,7 @@ static void sb_test()
sb_init( &b ); 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 ); err( L"Error %d while testing stringbuffers", res );
} }
@ -336,7 +337,22 @@ static void sb_test()
{ {
err( L"Error %d while testing stringbuffers", res ); err( L"Error %d while testing stringbuffers", res );
} }
say( (wchar_t *)b.buff ); 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; wchar_t *arg;
al_init( &out ); al_init( &out );
expand_string( wcsdup(in), &out, flags); expand_string( 0, wcsdup(in), &out, flags);
va_start( va, 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:'." ); 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(); proc_init();
output_init(); halloc_util_init();
event_init(); event_init();
exec_init(); exec_init();
parser_init(); parser_init();
@ -701,7 +717,7 @@ int main( int argc, char **argv )
wutil_destroy(); wutil_destroy();
exec_destroy(); exec_destroy();
event_destroy(); event_destroy();
output_destroy();
proc_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 are secretly a wrapper around this function. vgprintf does not
implement all the filters supported by printf, only those that are implement all the filters supported by printf, only those that are
currently used by fish. vgprintf internally uses snprintf to 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: Currently supported functionality:
- precision specification, both through .* and .N - 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 - long versions of all filters thorugh l and ll prefix
- Character outout using %c - Character output using %c
- String output through %s - String output through %s
- Floating point number output through %f - Floating point number output through %f
- Integer output through %d or %i - Integer output through %d, %i, %u, %o, %x and %X
- Unsigned integer output through %u
- Left padding using the - prefix
For a full description on the usage of *printf, see use 'man 3 printf'. 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 ); 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 ) if( precision != 0 )
writer( c ); writer( c );
@ -522,115 +521,138 @@ static int vgwprintf( void (*writer)(wchar_t),
case L'd': case L'd':
case L'i': case L'i':
{ case L'o':
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'u': case L'u':
case L'x':
case L'X':
{ {
char str[32]; char str[33];
char *pos; char *pos;
char format[16];
int len;
format[0]=0;
strcat( format, "%");
if( precision >= 0 )
strcat( format, ".*" );
switch( is_long ) 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: case 2:
{ strcat( format, "ll" );
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 );
break; 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: default:
debug( 0, L"Invalid filter %ls in string %ls\n", *filter, filter_org );
return -1; return -1;
} }
if( (width >= 0) && pad_left ) if( (width >= 0) && pad_left )
{ {
pad( writer, width-strlen(str) ); int l = maxi(width-strlen(str), 0 );
count += maxi( width-strlen(str), 0 ); pad( writer, l );
count += l;
} }
pos = str; pos = str;
@ -643,8 +665,9 @@ static int vgwprintf( void (*writer)(wchar_t),
if( (width >= 0) && !pad_left ) if( (width >= 0) && !pad_left )
{ {
pad( writer, width-strlen(str) ); int l = maxi(width-strlen(str), 0 );
count += maxi( width-strlen(str), 0 ); pad( writer, l );
count += l;
} }
break; break;
@ -705,7 +728,7 @@ static int vgwprintf( void (*writer)(wchar_t),
} }
default: default:
debug( 0, L"Unknown switch %lc in string %ls\n", *filter, filter_org ); debug( 0, L"Unknown switch %lc in string %ls\n", *filter, filter_org );
// exit(1); return -1;
} }
} }
else else