Commit 3759fcb7 authored by Anton Mitrofanov's avatar Anton Mitrofanov

Remove CRT objects use between DLL boundaries

Fix crash of MSVC builds compiled with --system-libx264 and /MT (default) CRT.
parent 76c5afc2
Pipeline #8241 passed with stages
in 10 minutes and 14 seconds
......@@ -27,11 +27,6 @@
#include "osdep.h"
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#endif
#if SYS_WINDOWS
#include <sys/types.h>
#include <sys/timeb.h>
......@@ -111,114 +106,3 @@ int x264_threading_init( void )
return 0;
}
#endif
#ifdef _WIN32
/* Functions for dealing with Unicode on Windows. */
FILE *x264_fopen( const char *filename, const char *mode )
{
wchar_t filename_utf16[MAX_PATH];
wchar_t mode_utf16[16];
if( utf8_to_utf16( filename, filename_utf16 ) && utf8_to_utf16( mode, mode_utf16 ) )
return _wfopen( filename_utf16, mode_utf16 );
return NULL;
}
int x264_rename( const char *oldname, const char *newname )
{
wchar_t oldname_utf16[MAX_PATH];
wchar_t newname_utf16[MAX_PATH];
if( utf8_to_utf16( oldname, oldname_utf16 ) && utf8_to_utf16( newname, newname_utf16 ) )
{
/* POSIX says that rename() removes the destination, but Win32 doesn't. */
_wunlink( newname_utf16 );
return _wrename( oldname_utf16, newname_utf16 );
}
return -1;
}
int x264_stat( const char *path, x264_struct_stat *buf )
{
wchar_t path_utf16[MAX_PATH];
if( utf8_to_utf16( path, path_utf16 ) )
return _wstati64( path_utf16, buf );
return -1;
}
#if !HAVE_WINRT
int x264_vfprintf( FILE *stream, const char *format, va_list arg )
{
HANDLE console = NULL;
DWORD mode;
if( stream == stdout )
console = GetStdHandle( STD_OUTPUT_HANDLE );
else if( stream == stderr )
console = GetStdHandle( STD_ERROR_HANDLE );
/* Only attempt to convert to UTF-16 when writing to a non-redirected console screen buffer. */
if( GetConsoleMode( console, &mode ) )
{
char buf[4096];
wchar_t buf_utf16[4096];
va_list arg2;
va_copy( arg2, arg );
int length = vsnprintf( buf, sizeof(buf), format, arg2 );
va_end( arg2 );
if( length > 0 && length < sizeof(buf) )
{
/* WriteConsoleW is the most reliable way to output Unicode to a console. */
int length_utf16 = MultiByteToWideChar( CP_UTF8, 0, buf, length, buf_utf16, sizeof(buf_utf16)/sizeof(wchar_t) );
DWORD written;
WriteConsoleW( console, buf_utf16, length_utf16, &written, NULL );
return length;
}
}
return vfprintf( stream, format, arg );
}
int x264_is_pipe( const char *path )
{
wchar_t path_utf16[MAX_PATH];
if( utf8_to_utf16( path, path_utf16 ) )
return WaitNamedPipeW( path_utf16, 0 );
return 0;
}
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
/* MSVC pre-VS2015 has broken snprintf/vsnprintf implementations which are incompatible with C99. */
int x264_snprintf( char *s, size_t n, const char *fmt, ... )
{
va_list arg;
va_start( arg, fmt );
int length = x264_vsnprintf( s, n, fmt, arg );
va_end( arg );
return length;
}
int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
{
int length = -1;
if( n )
{
va_list arg2;
va_copy( arg2, arg );
length = _vsnprintf( s, n, fmt, arg2 );
va_end( arg2 );
/* _(v)snprintf adds a null-terminator only if the length is less than the buffer size. */
if( length < 0 || length >= n )
s[n-1] = '\0';
}
/* _(v)snprintf returns a negative number if the length is greater than the buffer size. */
if( length < 0 )
return _vscprintf( fmt, arg );
return length;
}
#endif
#endif
......@@ -43,6 +43,11 @@
#include <math.h>
#endif
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#endif
#include "x264.h"
#if !HAVE_LOG2F
......@@ -56,12 +61,6 @@
#define strncasecmp _strnicmp
#define strtok_r strtok_s
#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
#if _MSC_VER < 1900
X264_API int x264_snprintf( char *s, size_t n, const char *fmt, ... );
X264_API int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
#define snprintf x264_snprintf
#define vsnprintf x264_vsnprintf
#endif
#else
#include <strings.h>
#endif
......@@ -78,14 +77,81 @@ X264_API int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
#define strtok_r(str,delim,save) strtok(str,delim)
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
/* MSVC pre-VS2015 has broken snprintf/vsnprintf implementations which are incompatible with C99. */
static inline int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
{
int length = -1;
if( n )
{
va_list arg2;
va_copy( arg2, arg );
length = _vsnprintf( s, n, fmt, arg2 );
va_end( arg2 );
/* _(v)snprintf adds a null-terminator only if the length is less than the buffer size. */
if( length < 0 || length >= n )
s[n-1] = '\0';
}
/* _(v)snprintf returns a negative number if the length is greater than the buffer size. */
if( length < 0 )
return _vscprintf( fmt, arg );
return length;
}
static inline int x264_snprintf( char *s, size_t n, const char *fmt, ... )
{
va_list arg;
va_start( arg, fmt );
int length = x264_vsnprintf( s, n, fmt, arg );
va_end( arg );
return length;
}
#define snprintf x264_snprintf
#define vsnprintf x264_vsnprintf
#endif
#ifdef _WIN32
#define utf8_to_utf16( utf8, utf16 )\
MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, utf16, sizeof(utf16)/sizeof(wchar_t) )
X264_API FILE *x264_fopen( const char *filename, const char *mode );
X264_API int x264_rename( const char *oldname, const char *newname );
/* Functions for dealing with Unicode on Windows. */
static inline FILE *x264_fopen( const char *filename, const char *mode )
{
wchar_t filename_utf16[MAX_PATH];
wchar_t mode_utf16[16];
if( utf8_to_utf16( filename, filename_utf16 ) && utf8_to_utf16( mode, mode_utf16 ) )
return _wfopen( filename_utf16, mode_utf16 );
return NULL;
}
static inline int x264_rename( const char *oldname, const char *newname )
{
wchar_t oldname_utf16[MAX_PATH];
wchar_t newname_utf16[MAX_PATH];
if( utf8_to_utf16( oldname, oldname_utf16 ) && utf8_to_utf16( newname, newname_utf16 ) )
{
/* POSIX says that rename() removes the destination, but Win32 doesn't. */
_wunlink( newname_utf16 );
return _wrename( oldname_utf16, newname_utf16 );
}
return -1;
}
#define x264_struct_stat struct _stati64
#define x264_fstat _fstati64
X264_API int x264_stat( const char *path, x264_struct_stat *buf );
static inline int x264_stat( const char *path, x264_struct_stat *buf )
{
wchar_t path_utf16[MAX_PATH];
if( utf8_to_utf16( path, path_utf16 ) )
return _wstati64( path_utf16, buf );
return -1;
}
#else
#define x264_fopen fopen
#define x264_rename rename
......@@ -98,8 +164,46 @@ X264_API int x264_stat( const char *path, x264_struct_stat *buf );
X264_API int64_t x264_mdate( void );
#if defined(_WIN32) && !HAVE_WINRT
X264_API int x264_vfprintf( FILE *stream, const char *format, va_list arg );
X264_API int x264_is_pipe( const char *path );
static inline int x264_vfprintf( FILE *stream, const char *format, va_list arg )
{
HANDLE console = NULL;
DWORD mode;
if( stream == stdout )
console = GetStdHandle( STD_OUTPUT_HANDLE );
else if( stream == stderr )
console = GetStdHandle( STD_ERROR_HANDLE );
/* Only attempt to convert to UTF-16 when writing to a non-redirected console screen buffer. */
if( GetConsoleMode( console, &mode ) )
{
char buf[4096];
wchar_t buf_utf16[4096];
va_list arg2;
va_copy( arg2, arg );
int length = vsnprintf( buf, sizeof(buf), format, arg2 );
va_end( arg2 );
if( length > 0 && length < sizeof(buf) )
{
/* WriteConsoleW is the most reliable way to output Unicode to a console. */
int length_utf16 = MultiByteToWideChar( CP_UTF8, 0, buf, length, buf_utf16, sizeof(buf_utf16)/sizeof(wchar_t) );
DWORD written;
WriteConsoleW( console, buf_utf16, length_utf16, &written, NULL );
return length;
}
}
return vfprintf( stream, format, arg );
}
static inline int x264_is_pipe( const char *path )
{
wchar_t path_utf16[MAX_PATH];
if( utf8_to_utf16( path, path_utf16 ) )
return WaitNamedPipeW( path_utf16, 0 );
return 0;
}
#else
#define x264_vfprintf vfprintf
#define x264_is_pipe(x) 0
......
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