From: Erik de Castro Lopo Date: Sun, 21 Apr 2013 06:16:44 +0000 (+1000) Subject: A set of windows utf8 patches fromJanne Hyvärinen . X-Git-Tag: 1.3.0pre4~19 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fupstream%2Fflac.git;a=commitdiff_plain;h=d0c219f1978dbaa00a063ac82aa75c8af152cbbb A set of windows utf8 patches fromJanne Hyvärinen . --- diff --git a/src/flac/decode.c b/src/flac/decode.c index 5f89253..3984eb9 100644 --- a/src/flac/decode.c +++ b/src/flac/decode.c @@ -172,6 +172,7 @@ int flac__decode_file(const char *infilename, const char *outfilename, FLAC__boo ) return 1; + stats_new_file(); if(!DecoderSession_init_decoder(&decoder_session, infilename)) return DecoderSession_finish_error(&decoder_session); @@ -433,19 +434,23 @@ int DecoderSession_finish_ok(DecoderSession *d) if(d->analysis_mode) flac__analyze_finish(d->aopts); if(md5_failure) { - flac__utils_printf(stderr, 1, "\r%s: ERROR, MD5 signature mismatch\n", d->inbasefilename); + stats_print_name(1, d->inbasefilename); + flac__utils_printf(stderr, 1, "ERROR, MD5 signature mismatch\n"); ok = d->continue_through_decode_errors; } else { if(!d->got_stream_info) { - flac__utils_printf(stderr, 1, "\r%s: WARNING, cannot check MD5 signature since there was no STREAMINFO\n", d->inbasefilename); + stats_print_name(1, d->inbasefilename); + flac__utils_printf(stderr, 1, "WARNING, cannot check MD5 signature since there was no STREAMINFO\n"); ok = !d->treat_warnings_as_errors; } else if(!d->has_md5sum) { - flac__utils_printf(stderr, 1, "\r%s: WARNING, cannot check MD5 signature since it was unset in the STREAMINFO\n", d->inbasefilename); + stats_print_name(1, d->inbasefilename); + flac__utils_printf(stderr, 1, "WARNING, cannot check MD5 signature since it was unset in the STREAMINFO\n"); ok = !d->treat_warnings_as_errors; } - flac__utils_printf(stderr, 2, "\r%s: %s \n", d->inbasefilename, d->test_only? "ok ":d->analysis_mode?"done ":"done"); + stats_print_name(2, d->inbasefilename); + flac__utils_printf(stderr, 2, "%s \n", d->test_only? "ok ":d->analysis_mode?"done ":"done"); } DecoderSession_destroy(d, /*error_occurred=*/!ok); if(!d->analysis_mode && !d->test_only && d->format != FORMAT_RAW) { @@ -1348,7 +1353,8 @@ void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderError DecoderSession *decoder_session = (DecoderSession*)client_data; (void)decoder; if(!decoder_session->error_callback_suppress_messages) - flac__utils_printf(stderr, 1, "%s: *** Got error code %d:%s\n", decoder_session->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status]); + stats_print_name(1, decoder_session->inbasefilename); + flac__utils_printf(stderr, 1, "*** Got error code %d:%s\n", status, FLAC__StreamDecoderErrorStatusString[status]); if(!decoder_session->continue_through_decode_errors) { /* if we got a sync error while looking for metadata, either it's not a FLAC file (more likely) or the file is corrupted */ if( @@ -1414,7 +1420,6 @@ void print_error_with_state(const DecoderSession *d, const char *message) void print_stats(const DecoderSession *decoder_session) { - static int count = 0; if(flac__utils_verbosity_ >= 2) { #if defined _MSC_VER || defined __MINGW32__ /* with MSVC you have to spoon feed it the casting */ @@ -1422,24 +1427,22 @@ void print_stats(const DecoderSession *decoder_session) #else const double progress = (double)decoder_session->samples_processed / (double)decoder_session->total_samples * 100.0; #endif - if(decoder_session->total_samples > 0) { - while (count > 0 && count--) - fprintf(stderr, "\b"); + if(decoder_session->total_samples > 0) { if ((unsigned)floor(progress + 0.5) == 100) return; - count = flac_fprintf(stderr, "%s: %s%u%% complete", - decoder_session->inbasefilename, + stats_print_name(2, decoder_session->inbasefilename); + stats_print_info(2, "%s%u%% complete", decoder_session->test_only? "testing, " : decoder_session->analysis_mode? "analyzing, " : "", (unsigned)floor(progress + 0.5) ); } else { - flac_fprintf(stderr, "\r%s: %s %u samples", - decoder_session->inbasefilename, + stats_print_name(2, decoder_session->inbasefilename); + stats_print_info(2, "%s %" PRIu64 " samples", decoder_session->test_only? "tested" : decoder_session->analysis_mode? "analyzed" : "wrote", - (unsigned)decoder_session->samples_processed + decoder_session->samples_processed ); } } diff --git a/src/flac/encode.c b/src/flac/encode.c index 8769f60..fe104cb 100644 --- a/src/flac/encode.c +++ b/src/flac/encode.c @@ -1180,6 +1180,7 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena if(options.format == FORMAT_FLAC || options.format == FORMAT_OGGFLAC) encoder_session.fmt.flac.client_data.samples_left_to_process = encoder_session.total_samples_to_encode; + stats_new_file(); /* init the encoder */ if(!EncoderSession_init_encoder(&encoder_session, options)) return EncoderSession_finish_error(&encoder_session); @@ -2543,7 +2544,8 @@ void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__Strea FLACDecoderData *data = &e->fmt.flac.client_data; (void)decoder; - flac__utils_printf(stderr, 1, "%s: ERROR got %s while decoding FLAC input\n", e->inbasefilename, FLAC__StreamDecoderErrorStatusString[status]); + stats_print_name(1, e->inbasefilename); + flac__utils_printf(stderr, 1, "ERROR got %s while decoding FLAC input\n", FLAC__StreamDecoderErrorStatusString[status]); if(!e->continue_through_decode_errors) data->fatal_error = true; } @@ -2594,33 +2596,36 @@ FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_ void print_stats(const EncoderSession *encoder_session) { - const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written); - const FLAC__uint64 uesize = encoder_session->unencoded_size; + if(flac__utils_verbosity_ >= 2) { + const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written); + const FLAC__uint64 uesize = encoder_session->unencoded_size; #if defined _MSC_VER || defined __MINGW32__ - /* with MSVC you have to spoon feed it the casting */ - const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode; - const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)(uesize? uesize:1) * min(1.0, progress)); + /* with MSVC you have to spoon feed it the casting */ + const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode; + const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)(uesize? uesize:1) * min(1.0, progress)); #else - const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode; - const double ratio = (double)encoder_session->bytes_written / ((double)(uesize? uesize:1) * min(1.0, progress)); + const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode; + const double ratio = (double)encoder_session->bytes_written / ((double)(uesize? uesize:1) * min(1.0, progress)); #endif + char ratiostr[16]; - FLAC__ASSERT(encoder_session->total_samples_to_encode > 0); + FLAC__ASSERT(encoder_session->total_samples_to_encode > 0); - if(samples_written == encoder_session->total_samples_to_encode) { - flac__utils_printf(stderr, 2, "\r%s:%s wrote %" PRIu64 " bytes, ratio=", - encoder_session->inbasefilename, - encoder_session->verify? " Verify OK," : "", - encoder_session->bytes_written - ); - } - else { - flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5)); + if (uesize) sprintf(ratiostr, "%0.3f", ratio); else sprintf(ratiostr, "N/A"); + + if(samples_written == encoder_session->total_samples_to_encode) { + stats_print_name(2, encoder_session->inbasefilename); + stats_print_info(2, "%swrote %" PRIu64 " bytes, ratio=%s", + encoder_session->verify? "Verify OK, " : "", + encoder_session->bytes_written, + ratiostr + ); + } + else { + stats_print_name(2, encoder_session->inbasefilename); + stats_print_info(2, "%u%% complete, ratio=%s", (unsigned)floor(progress * 100.0 + 0.5), ratiostr); + } } - if(uesize) - flac__utils_printf(stderr, 2, "%0.3f", ratio); - else - flac__utils_printf(stderr, 2, "N/A"); } void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status) diff --git a/src/flac/utils.c b/src/flac/utils.c index 91a7f9e..965ab59 100644 --- a/src/flac/utils.c +++ b/src/flac/utils.c @@ -29,6 +29,10 @@ #include "FLAC/assert.h" #include "FLAC/metadata.h" #include "share/compat.h" +#ifndef _WIN32 +#include +#include +#endif const char *CHANNEL_MASK_TAG = "WAVEFORMATEXTENSIBLE_CHANNEL_MASK"; @@ -158,6 +162,95 @@ void flac__utils_printf(FILE *stream, int level, const char *format, ...) } } +/* variables and functions for console status output */ +static FLAC__bool is_name_printed; +static int stats_char_count = 0; +static int console_width; +static int console_chars_left; + +int get_console_width() +{ + int width = 80; +#ifdef _WIN32 + width = win_get_console_width(); +#else + struct winsize w; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) width = w.ws_col; +#endif + return width; +} + +size_t strlen_console(const char *text) +{ +#ifdef _WIN32 + return strlen_utf8(text); +#else + size_t len; + wchar_t *wtmp; + + len = strlen(text)+1; + wtmp = (wchar_t *)malloc(len*sizeof(wchar_t)); + if (wtmp == NULL) return len-1; + mbstowcs(wtmp, text, len); + len = wcswidth(wtmp, len); + free(wtmp); + + return len; +#endif +} + +void stats_new_file() +{ + is_name_printed = false; +} + +void stats_clear() +{ + while (stats_char_count > 0 && stats_char_count--) + fprintf(stderr, "\b"); +} + +void stats_print_name(int level, const char *name) +{ + int len; + + if (flac__utils_verbosity_ >= level) { + stats_clear(); + if(is_name_printed) return; + + console_width = get_console_width(); + len = strlen_console(name)+2; + console_chars_left = console_width - (len % console_width); + flac_fprintf(stderr, "%s: ", name); + is_name_printed = true; + } +} + +void stats_print_info(int level, const char *format, ...) +{ + char tmp[80]; + int len, cleared_len; + + if (flac__utils_verbosity_ >= level) { + va_list args; + va_start(args, format); + len = vsnprintf(tmp, sizeof(tmp), format, args); + va_end(args); + if (len < 0 || len == sizeof(tmp)) { + tmp[sizeof(tmp)-1] = '\0'; + len = sizeof(tmp)-1; + } + cleared_len = stats_char_count; + stats_clear(); + if (len >= console_chars_left) { + while (cleared_len > 0 && cleared_len--) fprintf(stderr, " "); + fprintf(stderr, "\n"); + console_chars_left = console_width; + } + stats_char_count = fprintf(stderr, "%s", tmp); + } +} + #ifdef FLAC__VALGRIND_TESTING size_t flac__utils_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { diff --git a/src/flac/utils.h b/src/flac/utils.h index 41a0f91..b5ce839 100644 --- a/src/flac/utils.h +++ b/src/flac/utils.h @@ -53,6 +53,13 @@ size_t flac__utils_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stre extern int flac__utils_verbosity_; void flac__utils_printf(FILE *stream, int level, const char *format, ...); +int get_console_width(); +size_t strlen_console(const char *text); +void stats_new_file(); +void stats_clear(); +void stats_print_name(int level, const char *name); +void stats_print_info(int level, const char *format, ...); + FLAC__bool flac__utils_parse_skip_until_specification(const char *s, utils__SkipUntilSpecification *spec); void flac__utils_canonicalize_skip_until_specification(utils__SkipUntilSpecification *spec, unsigned sample_rate); diff --git a/src/metaflac/utils.c b/src/metaflac/utils.c index 934cfcf..af17d5b 100644 --- a/src/metaflac/utils.c +++ b/src/metaflac/utils.c @@ -136,7 +136,7 @@ void print_error_with_chain_status(FLAC__Metadata_Chain *chain, const char *form va_start(args, format); - (void) vfprintf(stderr, format, args); + (void) flac_vfprintf(stderr, format, args); va_end(args); diff --git a/src/share/win_utf8_io/win_utf8_io.c b/src/share/win_utf8_io/win_utf8_io.c index d7d1dbd..fae78a8 100644 --- a/src/share/win_utf8_io/win_utf8_io.c +++ b/src/share/win_utf8_io/win_utf8_io.c @@ -91,8 +91,47 @@ int get_utf8_argv(int *argc, char ***argv) return ret; } +/* return number of characters in the UTF-8 string */ +size_t strlen_utf8(const char *str) +{ + size_t len; + if ((len = MultiByteToWideChar(win_utf8_io_codepage, 0, str, -1, NULL, 0)) == 0) + len = strlen(str); + return len; +} + +/* get the console width in characters */ +int win_get_console_width() +{ + int width = 80; + CONSOLE_SCREEN_BUFFER_INFO csbi; + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (GetConsoleScreenBufferInfo(hOut, &csbi) != 0) width = csbi.dwSize.X; + return width; +} + /* print functions */ +int print_console(FILE *stream, const wchar_t *text, DWORD len) +{ + static HANDLE hOut; + static HANDLE hErr; + DWORD out; + hOut = GetStdHandle(STD_OUTPUT_HANDLE); + hErr = GetStdHandle(STD_ERROR_HANDLE); + if (stream == stdout && hOut != INVALID_HANDLE_VALUE && GetFileType(hOut) == FILE_TYPE_CHAR) { + if (WriteConsoleW(hOut, text, len, &out, NULL) == 0) return -1; + return out; + } else if (stream == stderr && hErr != INVALID_HANDLE_VALUE && GetFileType(hErr) == FILE_TYPE_CHAR) { + if (WriteConsoleW(hErr, text, len, &out, NULL) == 0) return -1; + return out; + } else { + int ret = fwprintf(stream, L"%s", text); + if (ret < 0) return ret; + return len; + } +} + int printf_utf8(const char *format, ...) { char *utmp = NULL; @@ -110,7 +149,7 @@ int printf_utf8(const char *format, ...) ret = -1; break; } - ret = wprintf(L"%s", wout); + ret = print_console(stdout, wout, wcslen(wout)); break; } if (utmp) free(utmp); @@ -136,7 +175,7 @@ int fprintf_utf8(FILE *stream, const char *format, ...) ret = -1; break; } - ret = fwprintf(stream, L"%s", wout); + ret = print_console(stream, wout, wcslen(wout)); break; } if (utmp) free(utmp); @@ -158,7 +197,7 @@ int vfprintf_utf8(FILE *stream, const char *format, va_list argptr) ret = -1; break; } - ret = fwprintf(stream, L"%s", wout); + ret = print_console(stream, wout, wcslen(wout)); break; } if (utmp) free(utmp);