summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2013-04-21 16:16:44 +1000
committerErik de Castro Lopo <erikd@mega-nerd.com>2013-04-21 16:50:24 +1000
commitd0c219f1978dbaa00a063ac82aa75c8af152cbbb (patch)
tree87c523bd1ad507ba884a9932acdf9a42256ab2f3 /src
parent2de567fb11ce3bbb711d993922d69af6d2cf817f (diff)
downloadflac-d0c219f1978dbaa00a063ac82aa75c8af152cbbb.tar.gz
A set of windows utf8 patches fromJanne Hyvärinen <cse@sci.fi>.
Diffstat (limited to 'src')
-rw-r--r--src/flac/decode.c31
-rw-r--r--src/flac/encode.c49
-rw-r--r--src/flac/utils.c93
-rw-r--r--src/flac/utils.h7
-rw-r--r--src/metaflac/utils.c2
-rw-r--r--src/share/win_utf8_io/win_utf8_io.c45
6 files changed, 187 insertions, 40 deletions
diff --git a/src/flac/decode.c b/src/flac/decode.c
index 5f89253a..3984eb9c 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 8769f604..fe104cb4 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 91a7f9ed..965ab595 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 <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)
{
diff --git a/src/flac/utils.h b/src/flac/utils.h
index 41a0f911..b5ce839b 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 934cfcf3..af17d5ba 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 d7d1dbdb..fae78a8a 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);