mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Add %o, %x and %X formats to *wprintf fallback implemnentation
darcs-hash:20060212112030-ac50b-1e3153c25dca3d2e12a8eb0e65da29bf70fa0d2e.gz
This commit is contained in:
parent
5718ea41df
commit
7c7f744b4c
2 changed files with 147 additions and 108 deletions
24
fish_tests.c
24
fish_tests.c
|
@ -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
231
wutil.c
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue