From 9ef2b2b164a92081bf3466af9ac0d0c28acae79d Mon Sep 17 00:00:00 2001 From: KWSys Upstream Date: Tue, 19 Jul 2016 08:20:26 -0400 Subject: KWSys 2016-07-19 (9d1dbd95) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code extracted from: http://public.kitware.com/KWSys.git at commit 9d1dbd95835638e4c0fcf74dc8020cd4cd3426c1 (master). Upstream Shortlog ----------------- Dāvis Mosāns (2): d2cdfc6d FStream: Use common base for basic_ifstream and basic_ofstream 9d1dbd95 FStream: Add MinGW support --- CMakeLists.txt | 5 + Configure.hxx.in | 7 +- FStream.hxx.in | 234 ++++++++++++++++++++++++++++++++-------------- kwsysPlatformTestsCXX.cxx | 5 + 4 files changed, 179 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39b03b3..87f6048 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -632,6 +632,11 @@ IF(KWSYS_USE_SystemInformation) ENDIF() ENDIF() +IF(KWSYS_USE_FStream) + KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H + "Checking whether is available" DIRECT) +ENDIF() + #----------------------------------------------------------------------------- # Choose a directory for the generated headers. IF(NOT KWSYS_HEADER_ROOT) diff --git a/Configure.hxx.in b/Configure.hxx.in index ff8e49d..4ce680d 100644 --- a/Configure.hxx.in +++ b/Configure.hxx.in @@ -17,6 +17,8 @@ /* Whether wstring is available. */ #define @KWSYS_NAMESPACE@_STL_HAS_WSTRING @KWSYS_STL_HAS_WSTRING@ +/* Whether is available. */ +#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H @KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@ /* If building a C++ file in kwsys itself, give the source file access to the macros without a configured namespace. */ @@ -24,8 +26,9 @@ # if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS # define kwsys @KWSYS_NAMESPACE@ # endif -# define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING +# define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS +# define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING +# define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H #endif #endif diff --git a/FStream.hxx.in b/FStream.hxx.in index 681e4d8..5471247 100644 --- a/FStream.hxx.in +++ b/FStream.hxx.in @@ -12,154 +12,248 @@ #ifndef @KWSYS_NAMESPACE@_FStream_hxx #define @KWSYS_NAMESPACE@_FStream_hxx +#include <@KWSYS_NAMESPACE@/Configure.hxx> #include <@KWSYS_NAMESPACE@/Encoding.hxx> #include +#if defined(_WIN32) +# if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H +# include +# endif +#endif namespace @KWSYS_NAMESPACE@ { -#if defined(_MSC_VER) && _MSC_VER >= 1400 +#if defined(_WIN32) && (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H) # if defined(_NOEXCEPT) # define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT # else # define @KWSYS_NAMESPACE@_FStream_NOEXCEPT # endif + +#if defined(_MSC_VER) + template class basic_filebuf : public std::basic_filebuf { +# if _MSC_VER >= 1400 public: typedef std::basic_filebuf my_base_type; basic_filebuf *open(char const *s,std::ios_base::openmode mode) { + const std::wstring wstr = Encoding::ToWide(s); return static_cast( - my_base_type::open(Encoding::ToWide(s).c_str(), mode) + my_base_type::open(wstr.c_str(), mode) ); } +# endif + }; + +#else + + inline std::wstring getcmode(const std::ios_base::openmode mode) { + std::wstring cmode; + bool plus = false; + if (mode & std::ios_base::app) { + cmode += L"a"; + plus = mode & std::ios_base::in ? true : false; + } else if (mode & std::ios_base::trunc || + (mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) { + cmode += L"w"; + plus = mode & std::ios_base::in ? true : false; + } else { + cmode += L"r"; + plus = mode & std::ios_base::out ? true : false; + } + if (plus) { + cmode += L"+"; + } + if (mode & std::ios_base::binary) { + cmode += L"b"; + } else { + cmode += L"t"; + } + return cmode; }; +#endif + template > - class basic_ifstream : public std::basic_istream + class basic_efilebuf { + public: +#if defined(_MSC_VER) + typedef basic_filebuf internal_buffer_type; +#else + typedef __gnu_cxx::stdio_filebuf internal_buffer_type; +#endif + + basic_efilebuf() : file_(0) + { + buf_ = 0; + } + + bool _open(char const *file_name,std::ios_base::openmode mode) + { + if (is_open() || file_) { + return false; + } +#if defined(_MSC_VER) + const bool success = buf_->open(file_name,mode) != 0; +#else + const std::wstring wstr = Encoding::ToWide(file_name); + bool success = false; + std::wstring cmode = getcmode(mode); + file_ = _wfopen(wstr.c_str(), cmode.c_str()); + if (file_) { + if (buf_) { + delete buf_; + } + buf_ = new internal_buffer_type(file_, mode); + success = true; + } +#endif + return success; + } + + bool is_open() + { + if (!buf_) { + return false; + } + return buf_->is_open(); + } + + bool is_open() const + { + if (!buf_) { + return false; + } + return buf_->is_open(); + } + + bool _close() + { + bool success = false; + if (buf_) { + success = buf_->close() != 0; +#if !defined(_MSC_VER) + if (file_) { + success = fclose(file_) == 0 ? success : false; + file_ = 0; + } +#endif + } + return success; + } + + static void _set_state(bool success, std::basic_ios *ios, basic_efilebuf* efilebuf) + { +#if !defined(_MSC_VER) + ios->rdbuf(efilebuf->buf_); +#endif + if (!success) { + ios->setstate(std::ios_base::failbit); + } else { + ios->clear(); + } + } + + ~basic_efilebuf() + { + if (buf_) { + delete buf_; + } + } + + protected: + internal_buffer_type* buf_; + FILE *file_; + }; + +template > +class basic_ifstream : public std::basic_istream, + public basic_efilebuf +{ + using basic_efilebuf::is_open; + public: - typedef basic_filebuf internal_buffer_type; + typedef typename basic_efilebuf::internal_buffer_type internal_buffer_type; typedef std::basic_istream internal_stream_type; basic_ifstream() : internal_stream_type(new internal_buffer_type()) { - buf_ = static_cast(internal_stream_type::rdbuf()); + this->buf_ = static_cast(internal_stream_type::rdbuf()); } explicit basic_ifstream(char const *file_name, std::ios_base::openmode mode = std::ios_base::in) : internal_stream_type(new internal_buffer_type()) { - buf_ = static_cast(internal_stream_type::rdbuf()); + this->buf_ = static_cast(internal_stream_type::rdbuf()); open(file_name,mode); } + void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in) { - if(!buf_->open(file_name,mode | std::ios_base::in)) - { - this->setstate(std::ios_base::failbit); - } - else - { - this->clear(); - } - } - bool is_open() - { - return buf_->is_open(); - } - bool is_open() const - { - return buf_->is_open(); + mode = mode | std::ios_base::in; + this->_set_state(this->_open(file_name, mode), this, this); } + void close() { - if(!buf_->close()) - { - this->setstate(std::ios_base::failbit); - } - else - { - this->clear(); - } + this->_set_state(this->_close(), this, this); } internal_buffer_type *rdbuf() const { - return buf_; + return this->buf_; } ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { - buf_->close(); - delete buf_; + close(); } - - private: - internal_buffer_type* buf_; }; template > -class basic_ofstream : public std::basic_ostream +class basic_ofstream : public std::basic_ostream, + public basic_efilebuf { + using basic_efilebuf::is_open; + public: - typedef basic_filebuf internal_buffer_type; + typedef typename basic_efilebuf::internal_buffer_type internal_buffer_type; typedef std::basic_ostream internal_stream_type; basic_ofstream() : internal_stream_type(new internal_buffer_type()) { - buf_ = static_cast(internal_stream_type::rdbuf()); + this->buf_ = static_cast(internal_stream_type::rdbuf()); } explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) : internal_stream_type(new internal_buffer_type()) { - buf_ = static_cast(internal_stream_type::rdbuf()); + this->buf_ = static_cast(internal_stream_type::rdbuf()); open(file_name,mode); } void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) { - if(!buf_->open(file_name,mode | std::ios_base::out)) - { - this->setstate(std::ios_base::failbit); - } - else - { - this->clear(); - } - } - bool is_open() - { - return buf_->is_open(); - } - bool is_open() const - { - return buf_->is_open(); + mode = mode | std::ios_base::out; + this->_set_state(this->_open(file_name, mode), this, this); } + void close() { - if(!buf_->close()) - { - this->setstate(std::ios_base::failbit); - } - else - { - this->clear(); - } + this->_set_state(this->_close(), this, this); } internal_buffer_type *rdbuf() const { - return buf_.get(); + return this->buf_; } + ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { - buf_->close(); - delete buf_; + close(); } - - private: - internal_buffer_type* buf_; }; typedef basic_ifstream ifstream; diff --git a/kwsysPlatformTestsCXX.cxx b/kwsysPlatformTestsCXX.cxx index fc87f91..b35808b 100644 --- a/kwsysPlatformTestsCXX.cxx +++ b/kwsysPlatformTestsCXX.cxx @@ -349,3 +349,8 @@ int main() void f(std ::wstring*) {} int main() { return 0; } #endif + +#ifdef TEST_KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H +#include +int main() { return 0; } +#endif -- cgit v0.12 From e9849d35aa612bc49667a9db7dadc30f87653783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C4=81vis=20Mos=C4=81ns?= Date: Sun, 17 Jul 2016 03:22:10 +0300 Subject: bootstrap: Add check for ext/stdio_filebuf.h needed by KWSys --- bootstrap | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bootstrap b/bootstrap index ad0c8ec..20b64a1 100755 --- a/bootstrap +++ b/bootstrap @@ -511,6 +511,7 @@ cmake_kwsys_config_replace_string () s/@KWSYS_LFS_REQUESTED@/${KWSYS_LFS_REQUESTED}/g; s/@KWSYS_NAME_IS_KWSYS@/${KWSYS_NAME_IS_KWSYS}/g; s/@KWSYS_STL_HAS_WSTRING@/${KWSYS_STL_HAS_WSTRING}/g; + s/@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@/${KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H}/g; }" >> "${OUTFILE}${_tmp}" if [ -f "${OUTFILE}${_tmp}" ]; then if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then @@ -1182,6 +1183,7 @@ KWSYS_BUILD_SHARED=0 KWSYS_LFS_AVAILABLE=0 KWSYS_LFS_REQUESTED=0 KWSYS_STL_HAS_WSTRING=0 +KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H=0 KWSYS_CXX_HAS_SETENV=0 KWSYS_CXX_HAS_UNSETENV=0 KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=0 @@ -1224,6 +1226,15 @@ else echo "${cmake_cxx_compiler} does not have stl wstring" fi +if cmake_try_run "${cmake_cxx_compiler}" \ + "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H" \ + "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then + KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H=1 + echo "${cmake_cxx_compiler} has " +else + echo "${cmake_cxx_compiler} does not have " +fi + # Just to be safe, let us store compiler and flags to the header file cmake_bootstrap_version='$Revision$' -- cgit v0.12