From 6065b23ce5cc2bcf8fb0218713adf8f4ef8fa5bc Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Wed, 31 May 2017 21:23:35 -0500 Subject: [PATCH] Added iostream.cpp from boost.nowide when building on Windows platforms. Simplified target_link_libraries(). --- src/CMakeLists.txt | 16 ++- src/utils/nowide-iostream.cpp | 261 ++++++++++++++++++++++++++++++++++ 2 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 src/utils/nowide-iostream.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 14f4a657a..c97640aa1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,17 +139,29 @@ include_directories(${Boost_INCLUDE_DIRS}) IF(CMAKE_HOST_UNIX) #set(Boost_LIBRARIES bsystem bthread bfilesystem) ENDIF(CMAKE_HOST_UNIX) + +target_link_libraries (slic3r libslic3r admesh clipper expat polypartition poly2tri boost-nowide ${Boost_LIBRARIES}) + IF(wxWidgets_FOUND) MESSAGE("wx found!") INCLUDE("${wxWidgets_USE_FILE}") add_library(slic3r_gui STATIC ${LIBDIR}/slic3r/GUI/3DScene.cpp ${LIBDIR}/slic3r/GUI/GUI.cpp) #only build GUI lib if building with wx - target_link_libraries (slic3r slic3r_gui libslic3r admesh clipper expat polypartition poly2tri ${Boost_LIBRARIES} ${wxWidgets_LIBRARIES}) + target_link_libraries (slic3r slic3r-gui ${wxWidgets_LIBRARIES}) ELSE(wxWidgets_FOUND) # For convenience. When we cannot continue, inform the user MESSAGE("wx not found!") - target_link_libraries (slic3r libslic3r admesh clipper expat polypartition poly2tri ${Boost_LIBRARIES}) #skip gui when no wx included ENDIF(wxWidgets_FOUND) +# Windows needs a compiled component for Boost.nowide +IF (WIN32) + add_library(boost-nowide STATIC + ${CMAKE_CURRENT_SOURCE_DIR}/utils/nowide-iostream.cpp + ) + + target_link_libraries(slic3r boost-nowide) + target_link_libraries(extrude-tin boost-nowide) +ENDIF(WIN32) + target_link_libraries (extrude-tin libslic3r admesh clipper expat polypartition poly2tri ${Boost_LIBRARIES}) diff --git a/src/utils/nowide-iostream.cpp b/src/utils/nowide-iostream.cpp new file mode 100644 index 000000000..b68945ab8 --- /dev/null +++ b/src/utils/nowide-iostream.cpp @@ -0,0 +1,261 @@ +// +// Copyright (c) 2012 Artyom Beilis (Tonkikh) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +#define BOOST_NOWIDE_SOURCE +#include +#include +#include +#include + +#ifdef BOOST_WINDOWS + +#ifndef NOMINMAX +# define NOMINMAX +#endif + + +#include + +namespace boost { +namespace nowide { +namespace details { + class console_output_buffer : public std::streambuf { + public: + console_output_buffer(HANDLE h) : + handle_(h), + isatty_(false) + { + if(handle_) { + DWORD dummy; + isatty_ = GetConsoleMode(handle_,&dummy) == TRUE; + } + } + protected: + int sync() + { + return overflow(EOF); + } + int overflow(int c) + { + if(!handle_) + return -1; + int n = pptr() - pbase(); + int r = 0; + + if(n > 0 && (r=write(pbase(),n)) < 0) + return -1; + if(r < n) { + memmove(pbase(),pbase() + r,n-r); + } + setp(buffer_, buffer_ + buffer_size); + pbump(n-r); + if(c!=EOF) + sputc(c); + return 0; + } + private: + + int write(char const *p,int n) + { + namespace uf = boost::locale::utf; + char const *b = p; + char const *e = p+n; + if(!isatty_) { + DWORD size=0; + if(!WriteFile(handle_,p,n,&size,0) || static_cast(size) != n) + return -1; + return n; + } + if(n > buffer_size) + return -1; + wchar_t *out = wbuffer_; + uf::code_point c; + size_t decoded = 0; + while(p < e && (c = uf::utf_traits::decode(p,e))!=uf::illegal && c!=uf::incomplete) { + out = uf::utf_traits::encode(c,out); + decoded = p-b; + } + if(c==uf::illegal) + return -1; + if(!WriteConsoleW(handle_,wbuffer_,out - wbuffer_,0,0)) + return -1; + return decoded; + } + + static const int buffer_size = 1024; + char buffer_[buffer_size]; + wchar_t wbuffer_[buffer_size]; // for null + HANDLE handle_; + bool isatty_; + }; + + class console_input_buffer: public std::streambuf { + public: + console_input_buffer(HANDLE h) : + handle_(h), + isatty_(false), + wsize_(0) + { + if(handle_) { + DWORD dummy; + isatty_ = GetConsoleMode(handle_,&dummy) == TRUE; + } + } + + protected: + int pbackfail(int c) + { + if(c==EOF) + return EOF; + + if(gptr()!=eback()) { + gbump(-1); + *gptr() = c; + return 0; + } + + if(pback_buffer_.empty()) { + pback_buffer_.resize(4); + char *b = &pback_buffer_[0]; + char *e = b + pback_buffer_.size(); + setg(b,e-1,e); + *gptr() = c; + } + else { + size_t n = pback_buffer_.size(); + std::vector tmp; + tmp.resize(n*2); + memcpy(&tmp[n],&pback_buffer_[0],n); + tmp.swap(pback_buffer_); + char *b = &pback_buffer_[0]; + char *e = b + n * 2; + char *p = b+n-1; + *p = c; + setg(b,p,e); + } + + return 0; + } + + int underflow() + { + if(!handle_) + return -1; + if(!pback_buffer_.empty()) + pback_buffer_.clear(); + + size_t n = read(); + setg(buffer_,buffer_,buffer_+n); + if(n == 0) + return EOF; + return std::char_traits::to_int_type(*gptr()); + } + + private: + + size_t read() + { + namespace uf = boost::locale::utf; + if(!isatty_) { + DWORD read_bytes = 0; + if(!ReadFile(handle_,buffer_,buffer_size,&read_bytes,0)) + return 0; + return read_bytes; + } + DWORD read_wchars = 0; + size_t n = wbuffer_size - wsize_; + if(!ReadConsoleW(handle_,wbuffer_,n,&read_wchars,0)) + return 0; + wsize_ += read_wchars; + char *out = buffer_; + wchar_t *b = wbuffer_; + wchar_t *e = b + wsize_; + wchar_t *p = b; + uf::code_point c; + wsize_ = e-p; + while(p < e && (c = uf::utf_traits::decode(p,e))!=uf::illegal && c!=uf::incomplete) { + out = uf::utf_traits::encode(c,out); + wsize_ = e-p; + } + + if(c==uf::illegal) + return -1; + + + if(c==uf::incomplete) { + memmove(b,e-wsize_,sizeof(wchar_t)*wsize_); + } + + return out - buffer_; + } + + static const size_t buffer_size = 1024 * 3; + static const size_t wbuffer_size = 1024; + char buffer_[buffer_size]; + wchar_t wbuffer_[buffer_size]; // for null + HANDLE handle_; + bool isatty_; + int wsize_; + std::vector pback_buffer_; + }; + + winconsole_ostream::winconsole_ostream(int fd) : std::ostream(0) + { + HANDLE h = 0; + switch(fd) { + case 1: + h = GetStdHandle(STD_OUTPUT_HANDLE); + break; + case 2: + h = GetStdHandle(STD_ERROR_HANDLE); + break; + } + d.reset(new console_output_buffer(h)); + std::ostream::rdbuf(d.get()); + } + + winconsole_ostream::~winconsole_ostream() + { + } + + winconsole_istream::winconsole_istream() : std::istream(0) + { + HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + d.reset(new console_input_buffer(h)); + std::istream::rdbuf(d.get()); + } + + winconsole_istream::~winconsole_istream() + { + } + +} // details + +BOOST_NOWIDE_DECL details::winconsole_istream cin; +BOOST_NOWIDE_DECL details::winconsole_ostream cout(1); +BOOST_NOWIDE_DECL details::winconsole_ostream cerr(2); +BOOST_NOWIDE_DECL details::winconsole_ostream clog(2); + +namespace { + struct initialize { + initialize() + { + boost::nowide::cin.tie(&boost::nowide::cout); + boost::nowide::cerr.tie(&boost::nowide::cout); + boost::nowide::clog.tie(&boost::nowide::cout); + } + } inst; +} + + + +} // nowide +} // namespace boost + +#endif +/// +// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4