Commit d0c219f1 authored by Erik de Castro Lopo's avatar Erik de Castro Lopo
Browse files

A set of windows utf8 patches fromJanne Hyvärinen <cse@sci.fi>.

parent 2de567fb
......@@ -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
);
}
}
......
......@@ -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)
......
......@@ -29,6 +29,10 @@
#include "FLAC/assert.h"
#include "FLAC/metadata.h"
#include "share/compat.h"
#ifndef _WIN32
#include <wchar.h>
#include <sys/ioctl.h>
#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)
{
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment