diff --git a/fish_tests.c b/fish_tests.c index 280ce4fff..2275eccda 100644 --- a/fish_tests.c +++ b/fish_tests.c @@ -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(); } diff --git a/wutil.c b/wutil.c index 97b5d764f..cc4368334 100644 --- a/wutil.c +++ b/wutil.c @@ -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