[FFmpeg-devel] [PATCH] avutil/log: in colored_fputs, convert string from utf8 to CP_ACP charset on Windows
Nicolas George
george at nsup.org
Fri Feb 21 10:13:59 CET 2014
Le tridi 3 ventôse, an CCXXII, 周泽华 a écrit :
> diff --git a/libavutil/log.c b/libavutil/log.c
> index 38ce1e8..c779d64 100644
> --- a/libavutil/log.c
> +++ b/libavutil/log.c
> @@ -50,6 +50,10 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
> static int av_log_level = AV_LOG_INFO;
> static int flags;
>
> +#if HAVE_MULTIBYTETOWIDECHAR && HAVE_WIDECHARTOMULTIBYTE
> +#include<windows.h>
> +#endif
> +
> #if HAVE_SETCONSOLETEXTATTRIBUTE
> #include <windows.h>
> static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
> @@ -101,11 +105,55 @@ static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
> #endif
> static int use_color = -1;
>
> +#if HAVE_MULTIBYTETOWIDECHAR && HAVE_WIDECHARTOMULTIBYTE
> +int is_stderr_redirected()
> +{
> + HANDLE stderr_handle;
> + DWORD file_type, num;
> +
> + stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
> + if (stderr_handle == INVALID_HANDLE_VALUE)
> + return 1;
> + file_type = GetFileType(stderr_handle);
> + if ((file_type & FILE_TYPE_CHAR) != FILE_TYPE_CHAR)
> + return 1;
> + return !GetConsoleMode(stderr_handle, &num);
> +}
> +#endif
> +
> static void colored_fputs(int level, const char *str)
> {
> +#if HAVE_MULTIBYTETOWIDECHAR && HAVE_WIDECHARTOMULTIBYTE
> + int num_wchars, num_chars;
> + wchar_t *wstr = NULL;
> + char *str_acp = NULL; /* str in CP_ACP charset */
> +#endif
> +
> if (!*str)
> return;
>
> +#if HAVE_MULTIBYTETOWIDECHAR && HAVE_WIDECHARTOMULTIBYTE
> + if (is_stderr_redirected())
> + goto no_acp_conversion;
> +
> + /* convert UTF-8 to wide chars, and then convert wide chars to CP_ACP */
> + num_wchars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, NULL, 0);
> + if (num_wchars > 0) {
> + wstr = av_mallocz(sizeof(wchar_t) * num_wchars);
> + if (wstr) {
> + MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, num_wchars);
> + num_chars = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL ,NULL);
> + str_acp = av_mallocz(sizeof(char) * num_chars);
> + if (str_acp) {
> + WideCharToMultiByte(CP_ACP, 0, wstr, -1, str_acp, num_chars, NULL, NULL);
> + str = str_acp;
> + }
> + av_freep(&wstr);
> + }
> + }
> +no_acp_conversion:
> +#endif
> +
> if (use_color < 0) {
> #if HAVE_SETCONSOLETEXTATTRIBUTE
> CONSOLE_SCREEN_BUFFER_INFO con_info;
> @@ -152,6 +200,11 @@ static void colored_fputs(int level, const char *str)
> fputs(str, stderr);
> #endif
>
> +#if HAVE_MULTIBYTETOWIDECHAR && HAVE_WIDECHARTOMULTIBYTE
> + if (str_acp) {
> + av_freep(&str_acp);
> + }
> +#endif
> }
>
> const char *av_default_item_name(void *ptr)
I do not know if this patch does the right thing; in fact I do not care much
about windows. But from a stylistic point of view, I would suggest to group
everything system-dependant into a single function, to reduce the #if
cruft. Something like that:
colored_fputs()
{
+ char to_free = NULL;
...
+ recode_for_console(&str, &to_free);
...
+ free(to_free);
}
And the function itself:
void recode_for_console(char **str, char **to_free)
{
#if HAVE_*
test if stderr is redirected
if (it is)
return; /* do nothing */
do the conversion
*to_free = converted_string;
*str = converted_string;
#endif /* otherwise, do nothing */
}
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140221/87af6122/attachment.asc>
More information about the ffmpeg-devel
mailing list