diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..5bbce14 --- /dev/null +++ b/.clang-format @@ -0,0 +1,125 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: AfterColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 140 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: ' #ifdef BOOST_WINDOWS #include -#include #include #include +#include #endif namespace boost { namespace nowide { - #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) - class args { +#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) + class args + { public: - args(int &,char **&) {} - args(int &,char **&,char **&){} - ~args() {} + args(int &, char **&) + {} + args(int &, char **&, char **&) + {} + ~args() + {} }; - #else +#else /// /// \brief args is a class that fixes standard main() function arguments and changes them to UTF-8 under @@ -43,34 +47,24 @@ namespace nowide { /// /// \note the class owns the memory of the newly allocated strings /// - class args { + class args + { public: - /// - /// Fix command line arguments + /// Fix command line arguments /// - args(int &argc,char **&argv) : - old_argc_(argc), - old_argv_(argv), - old_env_(0), - old_argc_ptr_(&argc), - old_argv_ptr_(&argv), - old_env_ptr_(0) + args(int &argc, char **&argv) : + old_argc_(argc), old_argv_(argv), old_env_(0), old_argc_ptr_(&argc), old_argv_ptr_(&argv), old_env_ptr_(0) { - fix_args(argc,argv); + fix_args(argc, argv); } /// /// Fix command line arguments and environment /// - args(int &argc,char **&argv,char **&env) : - old_argc_(argc), - old_argv_(argv), - old_env_(env), - old_argc_ptr_(&argc), - old_argv_ptr_(&argv), - old_env_ptr_(&env) + args(int &argc, char **&argv, char **&env) : + old_argc_(argc), old_argv_(argv), old_env_(env), old_argc_ptr_(&argc), old_argv_ptr_(&argv), old_env_ptr_(&env) { - fix_args(argc,argv); + fix_args(argc, argv); fix_env(env); } /// @@ -85,6 +79,7 @@ namespace nowide { if(old_env_ptr_) *old_env_ptr_ = old_env_; } + private: class wargv_ptr { @@ -92,30 +87,52 @@ namespace nowide { int argc; wargv_ptr(const wargv_ptr &); // Non-copyable public: - wargv_ptr() : p(CommandLineToArgvW(GetCommandLineW(), &argc)) {} - ~wargv_ptr() { if(p) LocalFree(p); } - int size() const { return argc; } - operator bool() const { return p != NULL; } - const wchar_t* operator[](size_t i) const { return p[i]; } + wargv_ptr() : p(CommandLineToArgvW(GetCommandLineW(), &argc)) + {} + ~wargv_ptr() + { + if(p) + LocalFree(p); + } + int size() const + { + return argc; + } + operator bool() const + { + return p != NULL; + } + const wchar_t *operator[](size_t i) const + { + return p[i]; + } }; class wenv_ptr { wchar_t *p; wenv_ptr(const wenv_ptr &); // Non-copyable public: - wenv_ptr() : p(GetEnvironmentStringsW()) {} - ~wenv_ptr() { if(p) FreeEnvironmentStringsW(p); } - operator const wchar_t*() const { return p; } + wenv_ptr() : p(GetEnvironmentStringsW()) + {} + ~wenv_ptr() + { + if(p) + FreeEnvironmentStringsW(p); + } + operator const wchar_t *() const + { + return p; + } }; - void fix_args(int &argc,char **&argv) + void fix_args(int &argc, char **&argv) { const wargv_ptr wargv; if(!wargv) throw std::runtime_error("Could not get command line!"); - args_.resize(wargv.size()+1,0); + args_.resize(wargv.size() + 1, 0); arg_values_.resize(wargv.size()); - for(int i=0;i -#include -#include -#include #include +#include +#include +#include +#include #include #ifdef BOOST_WINDOWS @@ -21,12 +21,12 @@ namespace boost { namespace nowide { - #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) +#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) using std::getenv; using ::setenv; using ::unsetenv; using ::putenv; - #else +#else /// /// \brief UTF-8 aware getenv. Returns 0 if the variable is not set. /// @@ -42,12 +42,13 @@ namespace nowide { wchar_t buf[buf_size]; std::vector tmp; wchar_t *ptr = buf; - size_t n = GetEnvironmentVariableW(name.c_str(),buf,buf_size); + size_t n = GetEnvironmentVariableW(name.c_str(), buf, buf_size); if(n == 0 && GetLastError() == 203) // ERROR_ENVVAR_NOT_FOUND return 0; - if(n >= buf_size) { - tmp.resize(n+1,L'\0'); - n = GetEnvironmentVariableW(name.c_str(),&tmp[0],static_cast(tmp.size() - 1)); + if(n >= buf_size) + { + tmp.resize(n + 1, L'\0'); + n = GetEnvironmentVariableW(name.c_str(), &tmp[0], static_cast(tmp.size() - 1)); // The size may have changed if(n >= tmp.size() - 1) return 0; @@ -62,16 +63,17 @@ namespace nowide { /// if override is not 0, that the old value is always overridded, otherwise, /// if the variable exists it remains unchanged /// - inline int setenv(char const *key,char const *value,int override) + inline int setenv(char const *key, char const *value, int override) { wshort_stackstring name(key); - if(!override) { + if(!override) + { wchar_t unused[2]; - if(!(GetEnvironmentVariableW(name.c_str(),unused,2)==0 && GetLastError() == 203)) // ERROR_ENVVAR_NOT_FOUND + if(!(GetEnvironmentVariableW(name.c_str(), unused, 2) == 0 && GetLastError() == 203)) // ERROR_ENVVAR_NOT_FOUND return 0; } wstackstring wval(value); - if(SetEnvironmentVariableW(name.c_str(),wval.c_str())) + if(SetEnvironmentVariableW(name.c_str(), wval.c_str())) return 0; return -1; } @@ -81,7 +83,7 @@ namespace nowide { inline int unsetenv(char const *key) { wshort_stackstring name(key); - if(SetEnvironmentVariableW(name.c_str(),0)) + if(SetEnvironmentVariableW(name.c_str(), 0)) return 0; return -1; } @@ -92,22 +94,22 @@ namespace nowide { { char const *key = string; char const *key_end = string; - while(*key_end!='=' && *key_end!='\0') + while(*key_end != '=' && *key_end != '\0') key_end++; if(*key_end == '\0') return -1; wshort_stackstring wkey; wstackstring wvalue; - wkey.convert(key,key_end); - wvalue.convert(key_end+1); + wkey.convert(key, key_end); + wvalue.convert(key_end + 1); - if(SetEnvironmentVariableW(wkey.c_str(),wvalue.c_str())) + if(SetEnvironmentVariableW(wkey.c_str(), wvalue.c_str())) return 0; return -1; } - #endif -} // nowide +#endif +} // namespace nowide } // namespace boost #endif diff --git a/include/boost/nowide/config.hpp b/include/boost/nowide/config.hpp index 50d9a5b..c0db8fa 100644 --- a/include/boost/nowide/config.hpp +++ b/include/boost/nowide/config.hpp @@ -8,18 +8,18 @@ #ifndef BOOST_NOWIDE_CONFIG_HPP_INCLUDED #define BOOST_NOWIDE_CONFIG_HPP_INCLUDED -#include #include +#include #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_NOWIDE_DYN_LINK) -# ifdef BOOST_NOWIDE_SOURCE -# define BOOST_NOWIDE_DECL BOOST_SYMBOL_EXPORT -# else -# define BOOST_NOWIDE_DECL BOOST_SYMBOL_IMPORT -# endif // BOOST_NOWIDE_SOURCE +#ifdef BOOST_NOWIDE_SOURCE +#define BOOST_NOWIDE_DECL BOOST_SYMBOL_EXPORT #else -# define BOOST_NOWIDE_DECL -#endif // DYN_LINK +#define BOOST_NOWIDE_DECL BOOST_SYMBOL_IMPORT +#endif // BOOST_NOWIDE_SOURCE +#else +#define BOOST_NOWIDE_DECL +#endif // DYN_LINK // // Automatically link to the correct build variant where possible. @@ -34,14 +34,13 @@ // If we're importing code from a dll, then tell auto_link.hpp about it: // #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_NOWIDE_DYN_LINK) -# define BOOST_DYN_LINK +#define BOOST_DYN_LINK #endif // // And include the header that does the work: // #include -#endif // auto-linking disabled - +#endif // auto-linking disabled #endif // boost/nowide/config.hpp // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/include/boost/nowide/convert.hpp b/include/boost/nowide/convert.hpp index 53cf471..d23e2a1 100644 --- a/include/boost/nowide/convert.hpp +++ b/include/boost/nowide/convert.hpp @@ -8,10 +8,10 @@ #ifndef BOOST_NOWIDE_CONVERT_H_INCLUDED #define BOOST_NOWIDE_CONVERT_H_INCLUDED -#include -#include #include #include +#include +#include namespace boost { namespace nowide { @@ -24,25 +24,28 @@ namespace nowide { /// If there is not enough room in the buffer 0 is returned, and the contents of the buffer are undefined. /// Any illegal sequences are replaced with U+FFFD substutution charracter /// - template - CharOut *basic_convert(CharOut *buffer,size_t buffer_size,CharIn const *source_begin,CharIn const *source_end) + template + CharOut *basic_convert(CharOut *buffer, size_t buffer_size, CharIn const *source_begin, CharIn const *source_end) { CharOut *rv = buffer; if(buffer_size == 0) return 0; - buffer_size --; - while(source_begin!=source_end) { + buffer_size--; + while(source_begin != source_end) + { using namespace detail::utf; - code_point c = utf_traits::template decode(source_begin,source_end); - if(c==illegal || c==incomplete) { + code_point c = utf_traits::template decode(source_begin, source_end); + if(c == illegal || c == incomplete) + { c = BOOST_NOWIDE_REPLACEMENT_CHARACTER; } size_t width = utf_traits::width(c); - if(buffer_size < width) { - rv=0; + if(buffer_size < width) + { + rv = 0; break; } - buffer = utf_traits::template encode(c,buffer); + buffer = utf_traits::template encode(c, buffer); buffer_size -= width; } *buffer++ = 0; @@ -50,27 +53,28 @@ namespace nowide { } /// - /// \brief Template function that converts a buffer of UTF sequences in range [source_begin,source_end) and returns a string containing converted value + /// \brief Template function that converts a buffer of UTF sequences in range [source_begin,source_end) and returns a string containing + /// converted value /// /// Any illegal sequences are replaced with U+FFFD substutution charracter /// - template - std::basic_string - basic_convert(CharIn const *begin,CharIn const *end) + template + std::basic_string basic_convert(CharIn const *begin, CharIn const *end) { - std::basic_string result; - result.reserve(end-begin); + result.reserve(end - begin); typedef std::back_insert_iterator > inserter_type; inserter_type inserter(result); using namespace detail::utf; code_point c; - while(begin!=end) { - c=utf_traits::template decode(begin,end); - if(c==illegal || c==incomplete) { - c=BOOST_NOWIDE_REPLACEMENT_CHARACTER; + while(begin != end) + { + c = utf_traits::template decode(begin, end); + if(c == illegal || c == incomplete) + { + c = BOOST_NOWIDE_REPLACEMENT_CHARACTER; } - utf_traits::template encode(c,inserter); + utf_traits::template encode(c, inserter); } return result; } @@ -87,34 +91,32 @@ namespace nowide { s++; return s; } - } + } // namespace details /// \endcond /// - /// \brief Template function that converts a string \a s from one type of UTF to another UTF and returns a string containing converted value + /// \brief Template function that converts a string \a s from one type of UTF to another UTF and returns a string containing converted + /// value /// /// Any illegal sequences are replaced with U+FFFD substutution charracter /// - template - std::basic_string - basic_convert(std::basic_string const &s) + template + std::basic_string basic_convert(std::basic_string const &s) { - return basic_convert(s.c_str(),s.c_str()+s.size()); + return basic_convert(s.c_str(), s.c_str() + s.size()); } /// - /// \brief Template function that converts a string \a s from one type of UTF to another UTF and returns a string containing converted value + /// \brief Template function that converts a string \a s from one type of UTF to another UTF and returns a string containing converted + /// value /// /// Any illegal sequences are replaced with U+FFFD substutution charracter /// - template - std::basic_string - basic_convert(CharIn const *s) + template + std::basic_string basic_convert(CharIn const *s) { - return basic_convert(s,details::basic_strend(s)); + return basic_convert(s, details::basic_strend(s)); } - - /// /// Convert NULL terminated UTF source string to NULL terminated \a output string of size at /// most output_size (including NULL) @@ -122,9 +124,9 @@ namespace nowide { /// In case of success output is returned, if the input sequence is illegal, /// or there is not enough room NULL is returned /// - inline char *narrow(char *output,size_t output_size,wchar_t const *source) + inline char *narrow(char *output, size_t output_size, wchar_t const *source) { - return basic_convert(output,output_size,source,details::basic_strend(source)); + return basic_convert(output, output_size, source, details::basic_strend(source)); } /// /// Convert UTF text in range [begin,end) to NULL terminated \a output string of size at @@ -133,9 +135,9 @@ namespace nowide { /// In case of success output is returned, if the input sequence is illegal, /// or there is not enough room NULL is returned /// - inline char *narrow(char *output,size_t output_size,wchar_t const *begin,wchar_t const *end) + inline char *narrow(char *output, size_t output_size, wchar_t const *begin, wchar_t const *end) { - return basic_convert(output,output_size,begin,end); + return basic_convert(output, output_size, begin, end); } /// /// Convert NULL terminated UTF source string to NULL terminated \a output string of size at @@ -144,9 +146,9 @@ namespace nowide { /// In case of success output is returned, if the input sequence is illegal, /// or there is not enough room NULL is returned /// - inline wchar_t *widen(wchar_t *output,size_t output_size,char const *source) + inline wchar_t *widen(wchar_t *output, size_t output_size, char const *source) { - return basic_convert(output,output_size,source,details::basic_strend(source)); + return basic_convert(output, output_size, source, details::basic_strend(source)); } /// /// Convert UTF text in range [begin,end) to NULL terminated \a output string of size at @@ -155,12 +157,11 @@ namespace nowide { /// In case of success output is returned, if the input sequence is illegal, /// or there is not enough room NULL is returned /// - inline wchar_t *widen(wchar_t *output,size_t output_size,char const *begin,char const *end) + inline wchar_t *widen(wchar_t *output, size_t output_size, char const *begin, char const *end) { - return basic_convert(output,output_size,begin,end); + return basic_convert(output, output_size, begin, end); } - /// /// Convert between Wide - UTF-16/32 string and UTF-8 string. /// @@ -190,7 +191,7 @@ namespace nowide { return basic_convert(s); } -} // nowide +} // namespace nowide } // namespace boost #endif diff --git a/include/boost/nowide/cstdio.hpp b/include/boost/nowide/cstdio.hpp index d3b5e84..70c6ded 100644 --- a/include/boost/nowide/cstdio.hpp +++ b/include/boost/nowide/cstdio.hpp @@ -8,17 +8,16 @@ #ifndef BOOST_NOWIDE_CSTDIO_H_INCLUDED #define BOOST_NOWIDE_CSTDIO_H_INCLUDED -#include -#include #include #include +#include +#include #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4996) +#pragma warning(push) +#pragma warning(disable : 4996) #endif - namespace boost { namespace nowide { #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) @@ -28,42 +27,42 @@ namespace nowide { using std::rename; #else -/// -/// \brief Same as freopen but file_name and mode are UTF-8 strings -/// -inline FILE *freopen(char const *file_name,char const *mode,FILE *stream) -{ - wstackstring wname(file_name); - wshort_stackstring wmode(mode); - return _wfreopen(wname.c_str(),wmode.c_str(),stream); -} -/// -/// \brief Same as fopen but file_name and mode are UTF-8 strings -/// -inline FILE *fopen(char const *file_name,char const *mode) -{ - wstackstring wname(file_name); - wshort_stackstring wmode(mode); - return _wfopen(wname.c_str(),wmode.c_str()); -} -/// -/// \brief Same as rename but old_name and new_name are UTF-8 strings -/// -inline int rename(char const *old_name,char const *new_name) -{ - wstackstring wold(old_name),wnew(new_name); - return _wrename(wold.c_str(),wnew.c_str()); -} -/// -/// \brief Same as rename but name is UTF-8 string -/// -inline int remove(char const *name) -{ - wstackstring wname(name); - return _wremove(wname.c_str()); -} + /// + /// \brief Same as freopen but file_name and mode are UTF-8 strings + /// + inline FILE *freopen(char const *file_name, char const *mode, FILE *stream) + { + wstackstring wname(file_name); + wshort_stackstring wmode(mode); + return _wfreopen(wname.c_str(), wmode.c_str(), stream); + } + /// + /// \brief Same as fopen but file_name and mode are UTF-8 strings + /// + inline FILE *fopen(char const *file_name, char const *mode) + { + wstackstring wname(file_name); + wshort_stackstring wmode(mode); + return _wfopen(wname.c_str(), wmode.c_str()); + } + /// + /// \brief Same as rename but old_name and new_name are UTF-8 strings + /// + inline int rename(char const *old_name, char const *new_name) + { + wstackstring wold(old_name), wnew(new_name); + return _wrename(wold.c_str(), wnew.c_str()); + } + /// + /// \brief Same as rename but name is UTF-8 string + /// + inline int remove(char const *name) + { + wstackstring wname(name); + return _wremove(wname.c_str()); + } #endif -} // nowide +} // namespace nowide } // namespace boost #ifdef BOOST_MSVC diff --git a/include/boost/nowide/detail/utf.hpp b/include/boost/nowide/detail/utf.hpp index 99130a7..6d57214 100644 --- a/include/boost/nowide/detail/utf.hpp +++ b/include/boost/nowide/detail/utf.hpp @@ -8,449 +8,448 @@ #ifndef BOOST_NOWIDE_UTF_HPP_INCLUDED #define BOOST_NOWIDE_UTF_HPP_INCLUDED -#include #include +#include namespace boost { namespace nowide { -namespace detail { -/// -/// \brief Namespace that holds basic operations on UTF encoded sequences -/// -/// All functions defined in this namespace do not require linking with Boost.Nowide library -/// Extracted from Boost.Locale -/// -namespace utf { + namespace detail { + /// + /// \brief Namespace that holds basic operations on UTF encoded sequences + /// + /// All functions defined in this namespace do not require linking with Boost.Nowide library + /// Extracted from Boost.Locale + /// + namespace utf { - /// - /// \brief The integral type that can hold a Unicode code point - /// - typedef uint32_t code_point; + /// + /// \brief The integral type that can hold a Unicode code point + /// + typedef uint32_t code_point; - /// - /// \brief Special constant that defines illegal code point - /// - static const code_point illegal = 0xFFFFFFFFu; + /// + /// \brief Special constant that defines illegal code point + /// + static const code_point illegal = 0xFFFFFFFFu; - /// - /// \brief Special constant that defines incomplete code point - /// - static const code_point incomplete = 0xFFFFFFFEu; + /// + /// \brief Special constant that defines incomplete code point + /// + static const code_point incomplete = 0xFFFFFFFEu; - /// - /// \brief the function checks if \a v is a valid code point - /// - inline bool is_valid_codepoint(code_point v) - { - if(v>0x10FFFF) - return false; - if(0xD800 <=v && v<= 0xDFFF) // surragates - return false; - return true; - } - - #ifdef BOOST_NOWIDE_DOXYGEN - /// - /// \brief UTF Traits class - functions to convert UTF sequences to and from Unicode code points - /// - template - struct utf_traits { - /// - /// The type of the character - /// - typedef CharType char_type; - /// - /// Read one code point from the range [p,e) and return it. - /// - /// - If the sequence that was read is incomplete sequence returns \ref incomplete, - /// - If illegal sequence detected returns \ref illegal - /// - /// Requirements - /// - /// - Iterator is valid input iterator - /// - /// Postconditions - /// - /// - p points to the last consumed character - /// - template - static code_point decode(Iterator &p,Iterator e); - - /// - /// Maximal width of valid sequence in the code units: - /// - /// - UTF-8 - 4 - /// - UTF-16 - 2 - /// - UTF-32 - 1 - /// - static const int max_width; - /// - /// The width of specific code point in the code units. - /// - /// Requirement: value is a valid Unicode code point - /// Returns value in range [1..max_width] - /// - static int width(code_point value); - - /// - /// Get the size of the trail part of variable length encoded sequence. - /// - /// Returns -1 if C is not valid lead character - /// - static int trail_length(char_type c); - /// - /// Returns true if c is trail code unit, always false for UTF-32 - /// - static bool is_trail(char_type c); - /// - /// Returns true if c is lead code unit, always true of UTF-32 - /// - static bool is_lead(char_type c); - - /// - /// Convert valid Unicode code point \a value to the UTF sequence. - /// - /// Requirements: - /// - /// - \a value is valid code point - /// - \a out is an output iterator should be able to accept at least width(value) units - /// - /// Returns the iterator past the last written code unit. - /// - template - static Iterator encode(code_point value,Iterator out); - /// - /// Decodes valid UTF sequence that is pointed by p into code point. - /// - /// If the sequence is invalid or points to end the behavior is undefined - /// - template - static code_point decode_valid(Iterator &p); - }; - - #else - - template - struct utf_traits; - - template - struct utf_traits { - - typedef CharType char_type; - - static int trail_length(char_type ci) - { - unsigned char c = ci; - if(c < 128) - return 0; - if(BOOST_UNLIKELY(c < 194)) - return -1; - if(c < 224) - return 1; - if(c < 240) - return 2; - if(BOOST_LIKELY(c <=244)) - return 3; - return -1; - } - - static const int max_width = 4; - - static int width(code_point value) - { - if(value <=0x7F) { - return 1; - } - else if(value <=0x7FF) { - return 2; - } - else if(BOOST_LIKELY(value <=0xFFFF)) { - return 3; - } - else { - return 4; - } - } - - static bool is_trail(char_type ci) - { - unsigned char c=ci; - return (c & 0xC0)==0x80; - } - - static bool is_lead(char_type ci) - { - return !is_trail(ci); - } - - template - static code_point decode(Iterator &p,Iterator e) - { - if(BOOST_UNLIKELY(p==e)) - return incomplete; - - unsigned char lead = *p++; - - // First byte is fully validated here - int trail_size = trail_length(lead); - - if(BOOST_UNLIKELY(trail_size < 0)) - return illegal; - - // - // Ok as only ASCII may be of size = 0 - // also optimize for ASCII text - // - if(trail_size == 0) - return lead; - - code_point c = lead & ((1<<(6-trail_size))-1); - - // Read the rest - unsigned char tmp; - switch(trail_size) { - case 3: - if(BOOST_UNLIKELY(p==e)) - return incomplete; - tmp = *p++; - if (!is_trail(tmp)) - return illegal; - c = (c << 6) | ( tmp & 0x3F); - BOOST_FALLTHROUGH; - case 2: - if(BOOST_UNLIKELY(p==e)) - return incomplete; - tmp = *p++; - if (!is_trail(tmp)) - return illegal; - c = (c << 6) | ( tmp & 0x3F); - BOOST_FALLTHROUGH; - case 1: - if(BOOST_UNLIKELY(p==e)) - return incomplete; - tmp = *p++; - if (!is_trail(tmp)) - return illegal; - c = (c << 6) | ( tmp & 0x3F); + /// + /// \brief the function checks if \a v is a valid code point + /// + inline bool is_valid_codepoint(code_point v) + { + if(v > 0x10FFFF) + return false; + if(0xD800 <= v && v <= 0xDFFF) // surragates + return false; + return true; } - // Check code point validity: no surrogates and - // valid range - if(BOOST_UNLIKELY(!is_valid_codepoint(c))) - return illegal; +#ifdef BOOST_NOWIDE_DOXYGEN + /// + /// \brief UTF Traits class - functions to convert UTF sequences to and from Unicode code points + /// + template + struct utf_traits + { + /// + /// The type of the character + /// + typedef CharType char_type; + /// + /// Read one code point from the range [p,e) and return it. + /// + /// - If the sequence that was read is incomplete sequence returns \ref incomplete, + /// - If illegal sequence detected returns \ref illegal + /// + /// Requirements + /// + /// - Iterator is valid input iterator + /// + /// Postconditions + /// + /// - p points to the last consumed character + /// + template + static code_point decode(Iterator &p, Iterator e); - // make sure it is the most compact representation - if(BOOST_UNLIKELY(width(c)!=trail_size + 1)) - return illegal; + /// + /// Maximal width of valid sequence in the code units: + /// + /// - UTF-8 - 4 + /// - UTF-16 - 2 + /// - UTF-32 - 1 + /// + static const int max_width; + /// + /// The width of specific code point in the code units. + /// + /// Requirement: value is a valid Unicode code point + /// Returns value in range [1..max_width] + /// + static int width(code_point value); - return c; + /// + /// Get the size of the trail part of variable length encoded sequence. + /// + /// Returns -1 if C is not valid lead character + /// + static int trail_length(char_type c); + /// + /// Returns true if c is trail code unit, always false for UTF-32 + /// + static bool is_trail(char_type c); + /// + /// Returns true if c is lead code unit, always true of UTF-32 + /// + static bool is_lead(char_type c); - } + /// + /// Convert valid Unicode code point \a value to the UTF sequence. + /// + /// Requirements: + /// + /// - \a value is valid code point + /// - \a out is an output iterator should be able to accept at least width(value) units + /// + /// Returns the iterator past the last written code unit. + /// + template + static Iterator encode(code_point value, Iterator out); + /// + /// Decodes valid UTF sequence that is pointed by p into code point. + /// + /// If the sequence is invalid or points to end the behavior is undefined + /// + template + static code_point decode_valid(Iterator &p); + }; - template - static code_point decode_valid(Iterator &p) - { - unsigned char lead = *p++; - if(lead < 192) - return lead; +#else - int trail_size; + template + struct utf_traits; - if(lead < 224) - trail_size = 1; - else if(BOOST_LIKELY(lead < 240)) // non-BMP rare - trail_size = 2; - else - trail_size = 3; + template + struct utf_traits + { + typedef CharType char_type; - code_point c = lead & ((1<<(6-trail_size))-1); + static int trail_length(char_type ci) + { + unsigned char c = ci; + if(c < 128) + return 0; + if(BOOST_UNLIKELY(c < 194)) + return -1; + if(c < 224) + return 1; + if(c < 240) + return 2; + if(BOOST_LIKELY(c <= 244)) + return 3; + return -1; + } - switch(trail_size) { - case 3: - c = (c << 6) | ( static_cast(*p++) & 0x3F); - BOOST_FALLTHROUGH; - case 2: - c = (c << 6) | ( static_cast(*p++) & 0x3F); - BOOST_FALLTHROUGH; - case 1: - c = (c << 6) | ( static_cast(*p++) & 0x3F); - } + static const int max_width = 4; - return c; - } + static int width(code_point value) + { + if(value <= 0x7F) + { + return 1; + } else if(value <= 0x7FF) + { + return 2; + } else if(BOOST_LIKELY(value <= 0xFFFF)) + { + return 3; + } else + { + return 4; + } + } + static bool is_trail(char_type ci) + { + unsigned char c = ci; + return (c & 0xC0) == 0x80; + } + static bool is_lead(char_type ci) + { + return !is_trail(ci); + } - template - static Iterator encode(code_point value,Iterator out) - { - if(value <= 0x7F) { - *out++ = static_cast(value); - } - else if(value <= 0x7FF) { - *out++ = static_cast((value >> 6) | 0xC0); - *out++ = static_cast((value & 0x3F) | 0x80); - } - else if(BOOST_LIKELY(value <= 0xFFFF)) { - *out++ = static_cast((value >> 12) | 0xE0); - *out++ = static_cast(((value >> 6) & 0x3F) | 0x80); - *out++ = static_cast((value & 0x3F) | 0x80); - } - else { - *out++ = static_cast((value >> 18) | 0xF0); - *out++ = static_cast(((value >> 12) & 0x3F) | 0x80); - *out++ = static_cast(((value >> 6) & 0x3F) | 0x80); - *out++ = static_cast((value & 0x3F) | 0x80); - } - return out; - } - }; // utf8 + template + static code_point decode(Iterator &p, Iterator e) + { + if(BOOST_UNLIKELY(p == e)) + return incomplete; - template - struct utf_traits { - typedef CharType char_type; + unsigned char lead = *p++; - // See RFC 2781 - static bool is_first_surrogate(uint16_t x) - { - return 0xD800 <=x && x<= 0xDBFF; - } - static bool is_second_surrogate(uint16_t x) - { - return 0xDC00 <=x && x<= 0xDFFF; - } - static code_point combine_surrogate(uint16_t w1,uint16_t w2) - { - return ((code_point(w1 & 0x3FF) << 10) | (w2 & 0x3FF)) + 0x10000; - } - static int trail_length(char_type c) - { - if(is_first_surrogate(c)) - return 1; - if(is_second_surrogate(c)) - return -1; - return 0; - } - /// - /// Returns true if c is trail code unit, always false for UTF-32 - /// - static bool is_trail(char_type c) - { - return is_second_surrogate(c); - } - /// - /// Returns true if c is lead code unit, always true of UTF-32 - /// - static bool is_lead(char_type c) - { - return !is_second_surrogate(c); - } + // First byte is fully validated here + int trail_size = trail_length(lead); - template - static code_point decode(It ¤t,It last) - { - if(BOOST_UNLIKELY(current == last)) - return incomplete; - uint16_t w1=*current++; - if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) { - return w1; - } - if(w1 > 0xDBFF) - return illegal; - if(current==last) - return incomplete; - uint16_t w2=*current++; - if(w2 < 0xDC00 || 0xDFFF < w2) - return illegal; - return combine_surrogate(w1,w2); - } - template - static code_point decode_valid(It ¤t) - { - uint16_t w1=*current++; - if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) { - return w1; - } - uint16_t w2=*current++; - return combine_surrogate(w1,w2); - } + if(BOOST_UNLIKELY(trail_size < 0)) + return illegal; - static const int max_width = 2; - static int width(code_point u) - { - return u>=0x10000 ? 2 : 1; - } - template - static It encode(code_point u,It out) - { - if(BOOST_LIKELY(u<=0xFFFF)) { - *out++ = static_cast(u); - } - else { - u -= 0x10000; - *out++ = static_cast(0xD800 | (u>>10)); - *out++ = static_cast(0xDC00 | (u & 0x3FF)); - } - return out; - } - }; // utf16; + // + // Ok as only ASCII may be of size = 0 + // also optimize for ASCII text + // + if(trail_size == 0) + return lead; + code_point c = lead & ((1 << (6 - trail_size)) - 1); - template - struct utf_traits { - typedef CharType char_type; - static int trail_length(char_type c) - { - if(is_valid_codepoint(c)) - return 0; - return -1; - } - static bool is_trail(char_type /*c*/) - { - return false; - } - static bool is_lead(char_type /*c*/) - { - return true; - } + // Read the rest + unsigned char tmp; + switch(trail_size) + { + case 3: + if(BOOST_UNLIKELY(p == e)) + return incomplete; + tmp = *p++; + if(!is_trail(tmp)) + return illegal; + c = (c << 6) | (tmp & 0x3F); + BOOST_FALLTHROUGH; + case 2: + if(BOOST_UNLIKELY(p == e)) + return incomplete; + tmp = *p++; + if(!is_trail(tmp)) + return illegal; + c = (c << 6) | (tmp & 0x3F); + BOOST_FALLTHROUGH; + case 1: + if(BOOST_UNLIKELY(p == e)) + return incomplete; + tmp = *p++; + if(!is_trail(tmp)) + return illegal; + c = (c << 6) | (tmp & 0x3F); + } - template - static code_point decode_valid(It ¤t) - { - return *current++; - } + // Check code point validity: no surrogates and + // valid range + if(BOOST_UNLIKELY(!is_valid_codepoint(c))) + return illegal; - template - static code_point decode(It ¤t,It last) - { - if(BOOST_UNLIKELY(current == last)) - return incomplete; - code_point c=*current++; - if(BOOST_UNLIKELY(!is_valid_codepoint(c))) - return illegal; - return c; - } - static const int max_width = 1; - static int width(code_point /*u*/) - { - return 1; - } - template - static It encode(code_point u,It out) - { - *out++ = static_cast(u); - return out; - } + // make sure it is the most compact representation + if(BOOST_UNLIKELY(width(c) != trail_size + 1)) + return illegal; - }; // utf32 + return c; + } - #endif + template + static code_point decode_valid(Iterator &p) + { + unsigned char lead = *p++; + if(lead < 192) + return lead; + int trail_size; -} // utf -} // detail -} // nowide -} // boost + if(lead < 224) + trail_size = 1; + else if(BOOST_LIKELY(lead < 240)) // non-BMP rare + trail_size = 2; + else + trail_size = 3; + code_point c = lead & ((1 << (6 - trail_size)) - 1); + + switch(trail_size) + { + case 3: c = (c << 6) | (static_cast(*p++) & 0x3F); BOOST_FALLTHROUGH; + case 2: c = (c << 6) | (static_cast(*p++) & 0x3F); BOOST_FALLTHROUGH; + case 1: c = (c << 6) | (static_cast(*p++) & 0x3F); + } + + return c; + } + + template + static Iterator encode(code_point value, Iterator out) + { + if(value <= 0x7F) + { + *out++ = static_cast(value); + } else if(value <= 0x7FF) + { + *out++ = static_cast((value >> 6) | 0xC0); + *out++ = static_cast((value & 0x3F) | 0x80); + } else if(BOOST_LIKELY(value <= 0xFFFF)) + { + *out++ = static_cast((value >> 12) | 0xE0); + *out++ = static_cast(((value >> 6) & 0x3F) | 0x80); + *out++ = static_cast((value & 0x3F) | 0x80); + } else + { + *out++ = static_cast((value >> 18) | 0xF0); + *out++ = static_cast(((value >> 12) & 0x3F) | 0x80); + *out++ = static_cast(((value >> 6) & 0x3F) | 0x80); + *out++ = static_cast((value & 0x3F) | 0x80); + } + return out; + } + }; // utf8 + + template + struct utf_traits + { + typedef CharType char_type; + + // See RFC 2781 + static bool is_first_surrogate(uint16_t x) + { + return 0xD800 <= x && x <= 0xDBFF; + } + static bool is_second_surrogate(uint16_t x) + { + return 0xDC00 <= x && x <= 0xDFFF; + } + static code_point combine_surrogate(uint16_t w1, uint16_t w2) + { + return ((code_point(w1 & 0x3FF) << 10) | (w2 & 0x3FF)) + 0x10000; + } + static int trail_length(char_type c) + { + if(is_first_surrogate(c)) + return 1; + if(is_second_surrogate(c)) + return -1; + return 0; + } + /// + /// Returns true if c is trail code unit, always false for UTF-32 + /// + static bool is_trail(char_type c) + { + return is_second_surrogate(c); + } + /// + /// Returns true if c is lead code unit, always true of UTF-32 + /// + static bool is_lead(char_type c) + { + return !is_second_surrogate(c); + } + + template + static code_point decode(It ¤t, It last) + { + if(BOOST_UNLIKELY(current == last)) + return incomplete; + uint16_t w1 = *current++; + if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) + { + return w1; + } + if(w1 > 0xDBFF) + return illegal; + if(current == last) + return incomplete; + uint16_t w2 = *current++; + if(w2 < 0xDC00 || 0xDFFF < w2) + return illegal; + return combine_surrogate(w1, w2); + } + template + static code_point decode_valid(It ¤t) + { + uint16_t w1 = *current++; + if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) + { + return w1; + } + uint16_t w2 = *current++; + return combine_surrogate(w1, w2); + } + + static const int max_width = 2; + static int width(code_point u) + { + return u >= 0x10000 ? 2 : 1; + } + template + static It encode(code_point u, It out) + { + if(BOOST_LIKELY(u <= 0xFFFF)) + { + *out++ = static_cast(u); + } else + { + u -= 0x10000; + *out++ = static_cast(0xD800 | (u >> 10)); + *out++ = static_cast(0xDC00 | (u & 0x3FF)); + } + return out; + } + }; // utf16; + + template + struct utf_traits + { + typedef CharType char_type; + static int trail_length(char_type c) + { + if(is_valid_codepoint(c)) + return 0; + return -1; + } + static bool is_trail(char_type /*c*/) + { + return false; + } + static bool is_lead(char_type /*c*/) + { + return true; + } + + template + static code_point decode_valid(It ¤t) + { + return *current++; + } + + template + static code_point decode(It ¤t, It last) + { + if(BOOST_UNLIKELY(current == last)) + return incomplete; + code_point c = *current++; + if(BOOST_UNLIKELY(!is_valid_codepoint(c))) + return illegal; + return c; + } + static const int max_width = 1; + static int width(code_point /*u*/) + { + return 1; + } + template + static It encode(code_point u, It out) + { + *out++ = static_cast(u); + return out; + } + + }; // utf32 + +#endif + + } // namespace utf + } // namespace detail +} // namespace nowide +} // namespace boost #endif diff --git a/include/boost/nowide/filebuf.hpp b/include/boost/nowide/filebuf.hpp index 5186b54..0cfd083 100644 --- a/include/boost/nowide/filebuf.hpp +++ b/include/boost/nowide/filebuf.hpp @@ -8,16 +8,16 @@ #ifndef BOOST_NOWIDE_FILEBUF_HPP #define BOOST_NOWIDE_FILEBUF_HPP -#include -#include #include -#include -#include +#include #include +#include +#include +#include #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4996 4244 4800) +#pragma warning(push) +#pragma warning(disable : 4996 4244 4800) #endif namespace boost { @@ -33,7 +33,7 @@ namespace nowide { /// it is implemented and specialized for CharType = char, it behaves /// implements std::filebuf over standard C I/O /// - template > + template > class basic_filebuf; /// @@ -43,44 +43,43 @@ namespace nowide { /// implements std::filebuf over standard C I/O /// template<> - class basic_filebuf : public std::basic_streambuf { + class basic_filebuf : public std::basic_streambuf + { public: /// /// Creates new filebuf /// - basic_filebuf() : - buffer_size_(4), - buffer_(0), - file_(0), - own_(true) + basic_filebuf() : buffer_size_(4), buffer_(0), file_(0), own_(true) { - setg(0,0,0); - setp(0,0); + setg(0, 0, 0); + setp(0, 0); } virtual ~basic_filebuf() { - if(file_) { + if(file_) + { ::fclose(file_); file_ = 0; } if(own_ && buffer_) - delete [] buffer_; + delete[] buffer_; } /// /// Same as std::filebuf::open but s is UTF-8 string /// - basic_filebuf *open(std::string const &s,std::ios_base::openmode mode) + basic_filebuf *open(std::string const &s, std::ios_base::openmode mode) { - return open(s.c_str(),mode); + return open(s.c_str(), mode); } /// /// Same as std::filebuf::open but s is UTF-8 string /// - basic_filebuf *open(char const *s,std::ios_base::openmode mode) + basic_filebuf *open(char const *s, std::ios_base::openmode mode) { - if(file_) { + if(file_) + { sync(); ::fclose(file_); file_ = 0; @@ -92,14 +91,15 @@ namespace nowide { if(!smode) return 0; wstackstring name(s); - #ifdef BOOST_NOWIDE_FSTREAM_TESTS - FILE *f = ::fopen(s,boost::nowide::narrow(smode).c_str()); - #else - FILE *f = ::_wfopen(name.c_str(),smode); - #endif +#ifdef BOOST_NOWIDE_FSTREAM_TESTS + FILE *f = ::fopen(s, boost::nowide::narrow(smode).c_str()); +#else + FILE *f = ::_wfopen(name.c_str(), smode); +#endif if(!f) return 0; - if(ate && fseek(f,0,SEEK_END)!=0) { + if(ate && fseek(f, 0, SEEK_END) != 0) + { fclose(f); return 0; } @@ -112,8 +112,9 @@ namespace nowide { basic_filebuf *close() { bool res = sync() == 0; - if(file_) { - if(::fclose(file_)!=0) + if(file_) + { + if(::fclose(file_) != 0) res = false; file_ = 0; } @@ -132,16 +133,18 @@ namespace nowide { { if(buffer_) return; - if(buffer_size_ > 0) { - buffer_ = new char [buffer_size_]; + if(buffer_size_ > 0) + { + buffer_ = new char[buffer_size_]; own_ = true; } } - protected: - virtual std::streambuf *setbuf(char *s,std::streamsize n) + protected: + virtual std::streambuf *setbuf(char *s, std::streamsize n) { - if(!buffer_ && n>=0) { + if(!buffer_ && n >= 0) + { buffer_ = s; buffer_size_ = n; own_ = false; @@ -158,27 +161,28 @@ namespace nowide { return EOF; size_t n = pptr() - pbase(); - if(n > 0) { - if(::fwrite(pbase(),1,n,file_) < n) + if(n > 0) + { + if(::fwrite(pbase(), 1, n, file_) < n) return -1; fflush(file_); } - if(buffer_size_ > 0) { + if(buffer_size_ > 0) + { make_buffer(); - setp(buffer_,buffer_+buffer_size_); - if(c!=EOF) + setp(buffer_, buffer_ + buffer_size_); + if(c != EOF) sputc(c); - } - else if(c!=EOF) { - if(::fputc(c,file_)==EOF) + } else if(c != EOF) + { + if(::fputc(c, file_) == EOF) return EOF; fflush(file_); } return 0; } - int sync() { return overflow(EOF); @@ -190,18 +194,20 @@ namespace nowide { return EOF; if(fixp() < 0) return EOF; - if(buffer_size_ == 0) { + if(buffer_size_ == 0) + { int c = ::fgetc(file_); - if(c==EOF) { + if(c == EOF) + { return EOF; } last_char_ = c; - setg(&last_char_,&last_char_,&last_char_ + 1); + setg(&last_char_, &last_char_, &last_char_ + 1); return c; } make_buffer(); - size_t n = ::fread(buffer_,1,buffer_size_,file_); - setg(buffer_,buffer_,buffer_+n); + size_t n = ::fread(buffer_, 1, buffer_size_, file_); + setg(buffer_, buffer_, buffer_ + n); if(n == 0) return EOF; return std::char_traits::to_int_type(*gptr()); @@ -209,55 +215,56 @@ namespace nowide { int pbackfail(int) { - return pubseekoff(-1,std::ios::cur); + return pubseekoff(-1, std::ios::cur); } - std::streampos seekoff(std::streamoff off, - std::ios_base::seekdir seekdir, - std::ios_base::openmode /*m*/) + std::streampos seekoff(std::streamoff off, std::ios_base::seekdir seekdir, std::ios_base::openmode /*m*/) { if(!file_) return EOF; if(fixp() < 0 || fixg() < 0) return EOF; - if(seekdir == std::ios_base::cur) { - if( ::fseek(file_,off,SEEK_CUR) < 0) + if(seekdir == std::ios_base::cur) + { + if(::fseek(file_, off, SEEK_CUR) < 0) return EOF; - } - else if(seekdir == std::ios_base::beg) { - if( ::fseek(file_,off,SEEK_SET) < 0) + } else if(seekdir == std::ios_base::beg) + { + if(::fseek(file_, off, SEEK_SET) < 0) return EOF; - } - else if(seekdir == std::ios_base::end) { - if( ::fseek(file_,off,SEEK_END) < 0) + } else if(seekdir == std::ios_base::end) + { + if(::fseek(file_, off, SEEK_END) < 0) return EOF; - } - else + } else return -1; return ftell(file_); } - std::streampos seekpos(std::streampos off,std::ios_base::openmode m) + std::streampos seekpos(std::streampos off, std::ios_base::openmode m) { - return seekoff(std::streamoff(off),std::ios_base::beg,m); + return seekoff(std::streamoff(off), std::ios_base::beg, m); } + private: int fixg() { - if(gptr()!=egptr()) { + if(gptr() != egptr()) + { std::streamsize off = gptr() - egptr(); - setg(0,0,0); - if(fseek(file_,off,SEEK_CUR) != 0) + setg(0, 0, 0); + if(fseek(file_, off, SEEK_CUR) != 0) return -1; } - setg(0,0,0); + setg(0, 0, 0); return 0; } int fixp() { - if(pptr()!=0) { + if(pptr() != 0) + { int r = sync(); - setp(0,0); + setp(0, 0); return r; } return 0; @@ -266,14 +273,14 @@ namespace nowide { void reset(FILE *f = 0) { sync(); - if(file_) { + if(file_) + { fclose(file_); file_ = 0; } file_ = f; } - static wchar_t const *get_mode(std::ios_base::openmode mode) { // @@ -333,16 +340,15 @@ namespace nowide { /// typedef basic_filebuf filebuf; - #endif // windows +#endif // windows -} // nowide +} // namespace nowide } // namespace boost #ifdef BOOST_MSVC -# pragma warning(pop) +#pragma warning(pop) #endif - #endif // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/include/boost/nowide/fstream.hpp b/include/boost/nowide/fstream.hpp index c27d0fe..c7c004b 100644 --- a/include/boost/nowide/fstream.hpp +++ b/include/boost/nowide/fstream.hpp @@ -8,13 +8,13 @@ #ifndef BOOST_NOWIDE_FSTREAM_INCLUDED_HPP #define BOOST_NOWIDE_FSTREAM_INCLUDED_HPP -#include -#include #include +#include +#include #include #include +#include #include -#include namespace boost { /// @@ -23,7 +23,7 @@ namespace boost { /// of std namespace (i.e. not on Windows) /// namespace nowide { -#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_FSTREAM_TESTS) && !defined(BOOST_NOWIDE_DOXYGEN) +#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_FSTREAM_TESTS) && !defined(BOOST_NOWIDE_DOXYGEN) using std::basic_ifstream; using std::basic_ofstream; @@ -36,47 +36,44 @@ namespace nowide { /// /// \brief Same as std::basic_ifstream but accepts UTF-8 strings under Windows /// - template > - class basic_ifstream : public std::basic_istream + template > + class basic_ifstream : public std::basic_istream { public: - typedef basic_filebuf internal_buffer_type; - typedef std::basic_istream internal_stream_type; + typedef basic_filebuf internal_buffer_type; + typedef std::basic_istream internal_stream_type; - basic_ifstream() : - internal_stream_type(0) + basic_ifstream() : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); } - explicit basic_ifstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::in) : - internal_stream_type(0) + explicit basic_ifstream(char const *file_name, std::ios_base::openmode mode = std::ios_base::in) : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); - open(file_name,mode); + open(file_name, mode); } - explicit basic_ifstream(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::in) : - internal_stream_type(0) + explicit basic_ifstream(std::string const &file_name, std::ios_base::openmode mode = std::ios_base::in) : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); - open(file_name,mode); + open(file_name, mode); } - - void open(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::in) + void open(std::string const &file_name, std::ios_base::openmode mode = std::ios_base::in) { - open(file_name.c_str(),mode); + open(file_name.c_str(), mode); } - void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in) + 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)) { + if(!buf_->open(file_name, mode | std::ios_base::in)) + { this->setstate(std::ios_base::failbit); - } - else { + } else + { this->clear(); } } @@ -113,43 +110,41 @@ namespace nowide { /// \brief Same as std::basic_ofstream but accepts UTF-8 strings under Windows /// - template > - class basic_ofstream : public std::basic_ostream + template > + class basic_ofstream : public std::basic_ostream { public: - typedef basic_filebuf internal_buffer_type; - typedef std::basic_ostream internal_stream_type; + typedef basic_filebuf internal_buffer_type; + typedef std::basic_ostream internal_stream_type; - basic_ofstream() : - internal_stream_type(0) + basic_ofstream() : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); } - explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) : - internal_stream_type(0) + explicit basic_ofstream(char const *file_name, std::ios_base::openmode mode = std::ios_base::out) : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); - open(file_name,mode); + open(file_name, mode); } - explicit basic_ofstream(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out) : - internal_stream_type(0) + explicit basic_ofstream(std::string const &file_name, std::ios_base::openmode mode = std::ios_base::out) : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); - open(file_name,mode); + open(file_name, mode); } - void open(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out) + void open(std::string const &file_name, std::ios_base::openmode mode = std::ios_base::out) { - open(file_name.c_str(),mode); + open(file_name.c_str(), mode); } - void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) + 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)) { + if(!buf_->open(file_name, mode | std::ios_base::out)) + { this->setstate(std::ios_base::failbit); - } - else { + } else + { this->clear(); } } @@ -183,49 +178,49 @@ namespace nowide { }; #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4250) // : inherits via dominance +#pragma warning(push) +#pragma warning(disable : 4250) // : inherits via dominance #endif /// /// \brief Same as std::basic_fstream but accepts UTF-8 strings under Windows /// - template > - class basic_fstream : public std::basic_iostream + template > + class basic_fstream : public std::basic_iostream { public: - typedef basic_filebuf internal_buffer_type; - typedef std::basic_iostream internal_stream_type; + typedef basic_filebuf internal_buffer_type; + typedef std::basic_iostream internal_stream_type; - basic_fstream() : - internal_stream_type(0) + basic_fstream() : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); } - explicit basic_fstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::in) : + explicit basic_fstream(char const *file_name, std::ios_base::openmode mode = std::ios_base::out | std::ios_base::in) : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); - open(file_name,mode); + open(file_name, mode); } - explicit basic_fstream(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::in) : + explicit basic_fstream(std::string const &file_name, std::ios_base::openmode mode = std::ios_base::out | std::ios_base::in) : internal_stream_type(0) { buf_.reset(new internal_buffer_type()); std::ios::rdbuf(buf_.get()); - open(file_name,mode); + open(file_name, mode); } - void open(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::out) + void open(std::string const &file_name, std::ios_base::openmode mode = std::ios_base::out | std::ios_base::out) { - open(file_name.c_str(),mode); + open(file_name.c_str(), mode); } - void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::out) + void open(char const *file_name, std::ios_base::openmode mode = std::ios_base::out | std::ios_base::out) { - if(!buf_->open(file_name,mode)) { + if(!buf_->open(file_name, mode)) + { this->setstate(std::ios_base::failbit); - } - else { + } else + { this->clear(); } } @@ -258,7 +253,7 @@ namespace nowide { boost::scoped_ptr buf_; }; #ifdef BOOST_MSVC -# pragma warning(pop) +#pragma warning(pop) #endif /// @@ -279,10 +274,8 @@ namespace nowide { typedef basic_fstream fstream; #endif -} // nowide +} // namespace nowide } // namespace boost - - #endif // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/include/boost/nowide/integration/filesystem.hpp b/include/boost/nowide/integration/filesystem.hpp index 5eb4590..3e1cd1d 100644 --- a/include/boost/nowide/integration/filesystem.hpp +++ b/include/boost/nowide/integration/filesystem.hpp @@ -8,23 +8,23 @@ #ifndef BOOST_NOWIDE_INTEGRATION_FILESYSTEM_HPP_INCLUDED #define BOOST_NOWIDE_INTEGRATION_FILESYSTEM_HPP_INCLUDED -# if (defined(__GNUC__) && __GNUC__ < 5) -# pragma GCC diagnostic ignored "-Wunused-parameter" -# endif -#include +#if(defined(__GNUC__) && __GNUC__ < 5) +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif #include +#include namespace boost { - namespace nowide { - /// - /// Instal utf8_codecvt facet into boost::filesystem::path such all char strings are interpreted as utf-8 strings - /// - inline void nowide_filesystem() - { - std::locale tmp = std::locale(std::locale(),new boost::nowide::utf8_codecvt()); - boost::filesystem::path::imbue(tmp); - } - } // nowide -} // boost +namespace nowide { + /// + /// Instal utf8_codecvt facet into boost::filesystem::path such all char strings are interpreted as utf-8 strings + /// + inline void nowide_filesystem() + { + std::locale tmp = std::locale(std::locale(), new boost::nowide::utf8_codecvt()); + boost::filesystem::path::imbue(tmp); + } +} // namespace nowide +} // namespace boost #endif /// diff --git a/include/boost/nowide/iostream.hpp b/include/boost/nowide/iostream.hpp index 0bc8643..62027c1 100644 --- a/include/boost/nowide/iostream.hpp +++ b/include/boost/nowide/iostream.hpp @@ -11,52 +11,56 @@ #include #include #include -#include #include +#include #include // must be the last #include #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251) +#pragma warning(push) +#pragma warning(disable : 4251) #endif - namespace boost { namespace nowide { - #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) +#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) using std::cout; using std::cerr; using std::cin; using std::clog; - #else +#else /// \cond INTERNAL namespace details { class console_output_buffer; class console_input_buffer; - class BOOST_NOWIDE_DECL winconsole_ostream : public std::ostream { + class BOOST_NOWIDE_DECL winconsole_ostream : public std::ostream + { winconsole_ostream(winconsole_ostream const &); void operator=(winconsole_ostream const &); + public: winconsole_ostream(int fd); ~winconsole_ostream(); + private: boost::scoped_ptr d; }; - class BOOST_NOWIDE_DECL winconsole_istream : public std::istream { + class BOOST_NOWIDE_DECL winconsole_istream : public std::istream + { winconsole_istream(winconsole_istream const &); void operator=(winconsole_istream const &); - public: + public: winconsole_istream(); ~winconsole_istream(); + private: boost::scoped_ptr d; }; - } // details + } // namespace details /// \endcond @@ -85,13 +89,13 @@ namespace nowide { /// extern BOOST_NOWIDE_DECL details::winconsole_ostream clog; - #endif +#endif -} // nowide +} // namespace nowide } // namespace boost #ifdef BOOST_MSVC -# pragma warning(pop) +#pragma warning(pop) #endif #include // pops abi_prefix.hpp pragmas diff --git a/include/boost/nowide/stackstring.hpp b/include/boost/nowide/stackstring.hpp index f201d4e..c83d3cf 100644 --- a/include/boost/nowide/stackstring.hpp +++ b/include/boost/nowide/stackstring.hpp @@ -13,139 +13,141 @@ namespace boost { namespace nowide { -/// -/// \brief A class that allows to create a temporary wide or narrow UTF strings from -/// wide or narrow UTF source. -/// -/// It uses on stack buffer of the string is short enough -/// and allocated a buffer on the heap if the size of the buffer is too small -/// -/// If invalid UTF charracters are detected they are replaced with U+FFFD substutution charracter -/// -template -class basic_stackstring { -public: - - static const size_t buffer_size = BufferSize; - typedef CharOut output_char; - typedef CharIn input_char; - - basic_stackstring(basic_stackstring const &other) : - mem_buffer_(0) + /// + /// \brief A class that allows to create a temporary wide or narrow UTF strings from + /// wide or narrow UTF source. + /// + /// It uses on stack buffer of the string is short enough + /// and allocated a buffer on the heap if the size of the buffer is too small + /// + /// If invalid UTF charracters are detected they are replaced with U+FFFD substutution charracter + /// + template + class basic_stackstring { - clear(); - if(other.mem_buffer_) { - size_t len = 0; - while(other.mem_buffer_[len]) - len ++; - mem_buffer_ = new output_char[len + 1]; - std::memcpy(mem_buffer_,other.mem_buffer_,sizeof(output_char) * (len+1)); + public: + static const size_t buffer_size = BufferSize; + typedef CharOut output_char; + typedef CharIn input_char; + + basic_stackstring(basic_stackstring const &other) : mem_buffer_(0) + { + clear(); + if(other.mem_buffer_) + { + size_t len = 0; + while(other.mem_buffer_[len]) + len++; + mem_buffer_ = new output_char[len + 1]; + std::memcpy(mem_buffer_, other.mem_buffer_, sizeof(output_char) * (len + 1)); + } else + { + std::memcpy(buffer_, other.buffer_, buffer_size * sizeof(output_char)); + } } - else { - std::memcpy(buffer_,other.buffer_,buffer_size * sizeof(output_char)); + + void swap(basic_stackstring &other) + { + std::swap(mem_buffer_, other.mem_buffer_); + for(size_t i = 0; i < buffer_size; i++) + std::swap(buffer_[i], other.buffer_[i]); } - } - - void swap(basic_stackstring &other) - { - std::swap(mem_buffer_,other.mem_buffer_); - for(size_t i=0;i wstackstring; -/// -/// Convinience typedef -/// -typedef basic_stackstring stackstring; -/// -/// Convinience typedef -/// -typedef basic_stackstring wshort_stackstring; -/// -/// Convinience typedef -/// -typedef basic_stackstring short_stackstring; + private: + static size_t get_space(size_t insize, size_t outsize, size_t in) + { + if(insize <= outsize) + return in; + else if(insize == 2 && outsize == 1) + return 3 * in; + else if(insize == 4 && outsize == 1) + return 4 * in; + else // if(insize == 4 && outsize == 2) + return 2 * in; + } + output_char buffer_[buffer_size]; + output_char *mem_buffer_; + }; // basic_stackstring + /// + /// Convinience typedef + /// + typedef basic_stackstring wstackstring; + /// + /// Convinience typedef + /// + typedef basic_stackstring stackstring; + /// + /// Convinience typedef + /// + typedef basic_stackstring wshort_stackstring; + /// + /// Convinience typedef + /// + typedef basic_stackstring short_stackstring; -} // nowide +} // namespace nowide } // namespace boost #endif diff --git a/include/boost/nowide/system.hpp b/include/boost/nowide/system.hpp index 0a29759..40e16a8 100644 --- a/include/boost/nowide/system.hpp +++ b/include/boost/nowide/system.hpp @@ -8,30 +8,30 @@ #ifndef BOOST_NOWIDE_CSTDLIB_HPP #define BOOST_NOWIDE_CSTDLIB_HPP -#include #include +#include namespace boost { namespace nowide { #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) -using std::system; + using std::system; #else // Windows -/// -/// Same as std::system but cmd is UTF-8. -/// -inline int system(char const *cmd) -{ - if(!cmd) - return _wsystem(0); - wstackstring wcmd(cmd); - return _wsystem(wcmd.c_str()); -} + /// + /// Same as std::system but cmd is UTF-8. + /// + inline int system(char const *cmd) + { + if(!cmd) + return _wsystem(0); + wstackstring wcmd(cmd); + return _wsystem(wcmd.c_str()); + } #endif -} // nowide +} // namespace nowide } // namespace boost #endif diff --git a/include/boost/nowide/utf8_codecvt.hpp b/include/boost/nowide/utf8_codecvt.hpp index 5536dd4..445dd9c 100644 --- a/include/boost/nowide/utf8_codecvt.hpp +++ b/include/boost/nowide/utf8_codecvt.hpp @@ -8,392 +8,398 @@ #ifndef BOOST_NOWIDE_UTF8_CODECVT_HPP #define BOOST_NOWIDE_UTF8_CODECVT_HPP -#include #include #include +#include #include #include namespace boost { namespace nowide { -// -// Make sure that mbstate can keep 16 bit of UTF-16 sequence -// -BOOST_STATIC_ASSERT(sizeof(std::mbstate_t)>=2); + // + // Make sure that mbstate can keep 16 bit of UTF-16 sequence + // + BOOST_STATIC_ASSERT(sizeof(std::mbstate_t) >= 2); #if defined _MSC_VER && _MSC_VER < 1700 // MSVC do_length is non-standard it counts wide characters instead of narrow and does not change mbstate #define BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST #endif -template -class utf8_codecvt; + template + class utf8_codecvt; -template -class utf8_codecvt : public std::codecvt -{ -public: - BOOST_STATIC_ASSERT_MSG(sizeof(CharType) >= 2, "CharType must be able to store UTF16 code point"); - - utf8_codecvt(size_t refs = 0) : std::codecvt(refs) + template + class utf8_codecvt : public std::codecvt { - } -protected: + public: + BOOST_STATIC_ASSERT_MSG(sizeof(CharType) >= 2, "CharType must be able to store UTF16 code point"); - typedef CharType uchar; + utf8_codecvt(size_t refs = 0) : std::codecvt(refs) + {} - virtual std::codecvt_base::result do_unshift(std::mbstate_t &s,char *from,char * /*to*/,char *&next) const - { - boost::uint16_t &state = *reinterpret_cast(&s); - if(state != 0) - return std::codecvt_base::error; - next=from; - return std::codecvt_base::ok; - } - virtual int do_encoding() const throw() - { - return 0; - } - virtual int do_max_length() const throw() - { - return 4; - } - virtual bool do_always_noconv() const throw() - { - return false; - } + protected: + typedef CharType uchar; - virtual int - do_length( std::mbstate_t - #ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST - const - #endif - &std_state, - char const *from, - char const *from_end, - size_t max) const - { - #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST - char const *save_from = from; - boost::uint16_t &state = *reinterpret_cast(&std_state); - #else - size_t save_max = max; - boost::uint16_t state = *reinterpret_cast(&std_state); - #endif - while(max > 0 && from < from_end){ - char const *prev_from = from; - boost::uint32_t ch=detail::utf::utf_traits::decode(from,from_end); - if(ch==detail::utf::illegal) { - ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; - } - else if(ch==detail::utf::incomplete) { - from = prev_from; - break; - } - max --; - if(ch > 0xFFFF) { - if(state == 0) { - from = prev_from; - state = 1; - } - else { - state = 0; - } - } - } - #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST - return static_cast(from - save_from); - #else - return static_cast(save_max - max); - #endif - } - - - virtual std::codecvt_base::result - do_in( std::mbstate_t &std_state, - char const *from, - char const *from_end, - char const *&from_next, - uchar *to, - uchar *to_end, - uchar *&to_next) const - { - std::codecvt_base::result r=std::codecvt_base::ok; - - // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT()) - // according to standard. We use it to keep a flag 0/1 for surrogate pair writing - // - // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observerd - // and first pair is written, but no input consumed - boost::uint16_t &state = *reinterpret_cast(&std_state); - while(to < to_end && from < from_end) + virtual std::codecvt_base::result do_unshift(std::mbstate_t &s, char *from, char * /*to*/, char *&next) const { - char const *from_saved = from; - - uint32_t ch=detail::utf::utf_traits::decode(from,from_end); - - if(ch==detail::utf::illegal) { - ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; - } - else if(ch==detail::utf::incomplete) { - from = from_saved; - r=std::codecvt_base::partial; - break; - } - // Normal codepoints go direcly to stream - if(ch <= 0xFFFF) { - *to++=static_cast(ch); - } - else { - // for other codepoints we do following - // - // 1. We can't consume our input as we may find ourselfs - // in state where all input consumed but not all output written,i.e. only - // 1st pair is written - // 2. We only write first pair and mark this in the state, we also revert back - // the from pointer in order to make sure this codepoint would be read - // once again and then we would consume our input together with writing - // second surrogate pair - ch-=0x10000; - boost::uint16_t vh = static_cast(ch >> 10); - boost::uint16_t vl = ch & 0x3FF; - boost::uint16_t w1 = vh + 0xD800; - boost::uint16_t w2 = vl + 0xDC00; - if(state == 0) { - from = from_saved; - *to++ = static_cast(w1); - state = 1; - } - else { - *to++ = static_cast(w2); - state = 0; - } - } + boost::uint16_t &state = *reinterpret_cast(&s); + if(state != 0) + return std::codecvt_base::error; + next = from; + return std::codecvt_base::ok; } - from_next=from; - to_next=to; - if(r == std::codecvt_base::ok && (from!=from_end || state!=0)) - r = std::codecvt_base::partial; - return r; - } - - virtual std::codecvt_base::result - do_out( std::mbstate_t &std_state, - uchar const *from, - uchar const *from_end, - uchar const *&from_next, - char *to, - char *to_end, - char *&to_next) const - { - std::codecvt_base::result r=std::codecvt_base::ok; - // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT()) - // according to standard. We assume that sizeof(mbstate_t) >=2 in order - // to be able to store first observerd surrogate pair - // - // State: state!=0 - a first surrogate pair was observerd (state = first pair), - // we expect the second one to come and then zero the state - /// - boost::uint16_t &state = *reinterpret_cast(&std_state); - while(to < to_end && from < from_end) + virtual int do_encoding() const throw() { - boost::uint32_t ch=0; - if(state != 0) { - // if the state idecates that 1st surrogate pair was written - // we should make sure that the second one that comes is actually - // second surrogate - boost::uint16_t w1 = state; - boost::uint16_t w2 = *from; - // we don't forward from as writing may fail to incomplete or - // partial conversion - if(0xDC00 <= w2 && w2<=0xDFFF) { - boost::uint16_t vh = w1 - 0xD800; - boost::uint16_t vl = w2 - 0xDC00; - ch=((uint32_t(vh) << 10) | vl) + 0x10000; - } - else { - ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; - } - } - else { - ch = *from; - if(0xD800 <= ch && ch<=0xDBFF) { - // if this is a first surrogate pair we put - // it into the state and consume it, note we don't - // go forward as it should be illegal so we increase - // the from pointer manually - state = static_cast(ch); - from++; - continue; - } - else if(0xDC00 <= ch && ch<=0xDFFF) { - // if we observe second surrogate pair and - // first only may be expected we should break from the loop with error - // as it is illegal input - ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; - } - } - if(!detail::utf::is_valid_codepoint(ch)) { - r=std::codecvt_base::error; - break; - } - int len = detail::utf::utf_traits::width(ch); - if(to_end - to < len) { - r=std::codecvt_base::partial; - break; - } - to = detail::utf::utf_traits::encode(ch,to); - state = 0; - from++; + return 0; + } + virtual int do_max_length() const throw() + { + return 4; + } + virtual bool do_always_noconv() const throw() + { + return false; } - from_next=from; - to_next=to; - if(r==std::codecvt_base::ok && from!=from_end) - r = std::codecvt_base::partial; - return r; - } -}; - -template -class utf8_codecvt : public std::codecvt -{ -public: - utf8_codecvt(size_t refs = 0) : std::codecvt(refs) - { - } -protected: - - typedef CharType uchar; - - virtual std::codecvt_base::result do_unshift(std::mbstate_t &/*s*/,char *from,char * /*to*/,char *&next) const - { - next=from; - return std::codecvt_base::ok; - } - virtual int do_encoding() const throw() - { - return 0; - } - virtual int do_max_length() const throw() - { - return 4; - } - virtual bool do_always_noconv() const throw() - { - return false; - } - - virtual int - do_length( std::mbstate_t - #ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST - const - #endif - &/*state*/, - char const *from, - char const *from_end, - size_t max) const - { - #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST - char const *start_from = from; - #else - size_t save_max = max; - #endif - - while(max > 0 && from < from_end){ + virtual int do_length(std::mbstate_t +#ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST + const +#endif + &std_state, + char const *from, + char const *from_end, + size_t max) const + { +#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST char const *save_from = from; - boost::uint32_t ch=detail::utf::utf_traits::decode(from,from_end); - if(ch==detail::utf::incomplete) { - from = save_from; - break; + boost::uint16_t &state = *reinterpret_cast(&std_state); +#else + size_t save_max = max; + boost::uint16_t state = *reinterpret_cast(&std_state); +#endif + while(max > 0 && from < from_end) + { + char const *prev_from = from; + boost::uint32_t ch = detail::utf::utf_traits::decode(from, from_end); + if(ch == detail::utf::illegal) + { + ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + } else if(ch == detail::utf::incomplete) + { + from = prev_from; + break; + } + max--; + if(ch > 0xFFFF) + { + if(state == 0) + { + from = prev_from; + state = 1; + } else + { + state = 0; + } + } } - else if(ch == detail::utf::illegal) { - ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; - } - max--; +#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST + return static_cast(from - save_from); +#else + return static_cast(save_max - max); +#endif } - #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST - return from - start_from; - #else - return save_max - max; - #endif - } - - virtual std::codecvt_base::result - do_in( std::mbstate_t &/*state*/, - char const *from, - char const *from_end, - char const *&from_next, - uchar *to, - uchar *to_end, - uchar *&to_next) const - { - std::codecvt_base::result r=std::codecvt_base::ok; - - // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT()) - // according to standard. We use it to keep a flag 0/1 for surrogate pair writing - // - // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observerd - // and first pair is written, but no input consumed - while(to < to_end && from < from_end) + virtual std::codecvt_base::result do_in(std::mbstate_t &std_state, + char const *from, + char const *from_end, + char const *&from_next, + uchar *to, + uchar *to_end, + uchar *&to_next) const { - char const *from_saved = from; + std::codecvt_base::result r = std::codecvt_base::ok; - uint32_t ch=detail::utf::utf_traits::decode(from,from_end); + // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT()) + // according to standard. We use it to keep a flag 0/1 for surrogate pair writing + // + // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observerd + // and first pair is written, but no input consumed + boost::uint16_t &state = *reinterpret_cast(&std_state); + while(to < to_end && from < from_end) + { + char const *from_saved = from; - if(ch==detail::utf::illegal) { - ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + uint32_t ch = detail::utf::utf_traits::decode(from, from_end); + + if(ch == detail::utf::illegal) + { + ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + } else if(ch == detail::utf::incomplete) + { + from = from_saved; + r = std::codecvt_base::partial; + break; + } + // Normal codepoints go direcly to stream + if(ch <= 0xFFFF) + { + *to++ = static_cast(ch); + } else + { + // for other codepoints we do following + // + // 1. We can't consume our input as we may find ourselfs + // in state where all input consumed but not all output written,i.e. only + // 1st pair is written + // 2. We only write first pair and mark this in the state, we also revert back + // the from pointer in order to make sure this codepoint would be read + // once again and then we would consume our input together with writing + // second surrogate pair + ch -= 0x10000; + boost::uint16_t vh = static_cast(ch >> 10); + boost::uint16_t vl = ch & 0x3FF; + boost::uint16_t w1 = vh + 0xD800; + boost::uint16_t w2 = vl + 0xDC00; + if(state == 0) + { + from = from_saved; + *to++ = static_cast(w1); + state = 1; + } else + { + *to++ = static_cast(w2); + state = 0; + } + } } - else if(ch==detail::utf::incomplete) { - r=std::codecvt_base::partial; - from=from_saved; - break; - } - *to++=ch; + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && (from != from_end || state != 0)) + r = std::codecvt_base::partial; + return r; } - from_next=from; - to_next=to; - if(r == std::codecvt_base::ok && from!=from_end) - r = std::codecvt_base::partial; - return r; - } - virtual std::codecvt_base::result - do_out( std::mbstate_t &/*std_state*/, - uchar const *from, - uchar const *from_end, - uchar const *&from_next, - char *to, - char *to_end, - char *&to_next) const - { - std::codecvt_base::result r=std::codecvt_base::ok; - while(to < to_end && from < from_end) + virtual std::codecvt_base::result do_out(std::mbstate_t &std_state, + uchar const *from, + uchar const *from_end, + uchar const *&from_next, + char *to, + char *to_end, + char *&to_next) const { - boost::uint32_t ch=0; - ch = *from; - if(!detail::utf::is_valid_codepoint(ch)) { - ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + std::codecvt_base::result r = std::codecvt_base::ok; + // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT()) + // according to standard. We assume that sizeof(mbstate_t) >=2 in order + // to be able to store first observerd surrogate pair + // + // State: state!=0 - a first surrogate pair was observerd (state = first pair), + // we expect the second one to come and then zero the state + /// + boost::uint16_t &state = *reinterpret_cast(&std_state); + while(to < to_end && from < from_end) + { + boost::uint32_t ch = 0; + if(state != 0) + { + // if the state idecates that 1st surrogate pair was written + // we should make sure that the second one that comes is actually + // second surrogate + boost::uint16_t w1 = state; + boost::uint16_t w2 = *from; + // we don't forward from as writing may fail to incomplete or + // partial conversion + if(0xDC00 <= w2 && w2 <= 0xDFFF) + { + boost::uint16_t vh = w1 - 0xD800; + boost::uint16_t vl = w2 - 0xDC00; + ch = ((uint32_t(vh) << 10) | vl) + 0x10000; + } else + { + ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + } + } else + { + ch = *from; + if(0xD800 <= ch && ch <= 0xDBFF) + { + // if this is a first surrogate pair we put + // it into the state and consume it, note we don't + // go forward as it should be illegal so we increase + // the from pointer manually + state = static_cast(ch); + from++; + continue; + } else if(0xDC00 <= ch && ch <= 0xDFFF) + { + // if we observe second surrogate pair and + // first only may be expected we should break from the loop with error + // as it is illegal input + ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + } + } + if(!detail::utf::is_valid_codepoint(ch)) + { + r = std::codecvt_base::error; + break; + } + int len = detail::utf::utf_traits::width(ch); + if(to_end - to < len) + { + r = std::codecvt_base::partial; + break; + } + to = detail::utf::utf_traits::encode(ch, to); + state = 0; + from++; } - int len = detail::utf::utf_traits::width(ch); - if(to_end - to < len) { - r=std::codecvt_base::partial; - break; - } - to = detail::utf::utf_traits::encode(ch,to); - from++; + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && from != from_end) + r = std::codecvt_base::partial; + return r; } - from_next=from; - to_next=to; - if(r==std::codecvt_base::ok && from!=from_end) - r = std::codecvt_base::partial; - return r; - } -}; + }; -} // nowide + template + class utf8_codecvt : public std::codecvt + { + public: + utf8_codecvt(size_t refs = 0) : std::codecvt(refs) + {} + + protected: + typedef CharType uchar; + + virtual std::codecvt_base::result do_unshift(std::mbstate_t & /*s*/, char *from, char * /*to*/, char *&next) const + { + next = from; + return std::codecvt_base::ok; + } + virtual int do_encoding() const throw() + { + return 0; + } + virtual int do_max_length() const throw() + { + return 4; + } + virtual bool do_always_noconv() const throw() + { + return false; + } + + virtual int do_length(std::mbstate_t +#ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST + const +#endif + & /*state*/, + char const *from, + char const *from_end, + size_t max) const + { +#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST + char const *start_from = from; +#else + size_t save_max = max; +#endif + + while(max > 0 && from < from_end) + { + char const *save_from = from; + boost::uint32_t ch = detail::utf::utf_traits::decode(from, from_end); + if(ch == detail::utf::incomplete) + { + from = save_from; + break; + } else if(ch == detail::utf::illegal) + { + ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + } + max--; + } +#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST + return from - start_from; +#else + return save_max - max; +#endif + } + + virtual std::codecvt_base::result do_in(std::mbstate_t & /*state*/, + char const *from, + char const *from_end, + char const *&from_next, + uchar *to, + uchar *to_end, + uchar *&to_next) const + { + std::codecvt_base::result r = std::codecvt_base::ok; + + // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT()) + // according to standard. We use it to keep a flag 0/1 for surrogate pair writing + // + // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observerd + // and first pair is written, but no input consumed + while(to < to_end && from < from_end) + { + char const *from_saved = from; + + uint32_t ch = detail::utf::utf_traits::decode(from, from_end); + + if(ch == detail::utf::illegal) + { + ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + } else if(ch == detail::utf::incomplete) + { + r = std::codecvt_base::partial; + from = from_saved; + break; + } + *to++ = ch; + } + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && from != from_end) + r = std::codecvt_base::partial; + return r; + } + + virtual std::codecvt_base::result do_out(std::mbstate_t & /*std_state*/, + uchar const *from, + uchar const *from_end, + uchar const *&from_next, + char *to, + char *to_end, + char *&to_next) const + { + std::codecvt_base::result r = std::codecvt_base::ok; + while(to < to_end && from < from_end) + { + boost::uint32_t ch = 0; + ch = *from; + if(!detail::utf::is_valid_codepoint(ch)) + { + ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + } + int len = detail::utf::utf_traits::width(ch); + if(to_end - to < len) + { + r = std::codecvt_base::partial; + break; + } + to = detail::utf::utf_traits::encode(ch, to); + from++; + } + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && from != from_end) + r = std::codecvt_base::partial; + return r; + } + }; + +} // namespace nowide } // namespace boost #endif diff --git a/include/boost/nowide/windows.hpp b/include/boost/nowide/windows.hpp index 5af688f..fb7e26d 100644 --- a/include/boost/nowide/windows.hpp +++ b/include/boost/nowide/windows.hpp @@ -17,21 +17,18 @@ // extern "C" { -__declspec(dllimport) wchar_t* __stdcall GetEnvironmentStringsW(void); -__declspec(dllimport) int __stdcall FreeEnvironmentStringsW(wchar_t *); -__declspec(dllimport) wchar_t* __stdcall GetCommandLineW(void); -__declspec(dllimport) wchar_t** __stdcall CommandLineToArgvW(wchar_t const *,int *); -__declspec(dllimport) unsigned long __stdcall GetLastError(); -__declspec(dllimport) void* __stdcall LocalFree(void *); -__declspec(dllimport) int __stdcall SetEnvironmentVariableW(wchar_t const *,wchar_t const *); -__declspec(dllimport) unsigned long __stdcall GetEnvironmentVariableW(wchar_t const *,wchar_t *,unsigned long); - +__declspec(dllimport) wchar_t *__stdcall GetEnvironmentStringsW(void); +__declspec(dllimport) int __stdcall FreeEnvironmentStringsW(wchar_t *); +__declspec(dllimport) wchar_t *__stdcall GetCommandLineW(void); +__declspec(dllimport) wchar_t **__stdcall CommandLineToArgvW(wchar_t const *, int *); +__declspec(dllimport) unsigned long __stdcall GetLastError(); +__declspec(dllimport) void *__stdcall LocalFree(void *); +__declspec(dllimport) int __stdcall SetEnvironmentVariableW(wchar_t const *, wchar_t const *); +__declspec(dllimport) unsigned long __stdcall GetEnvironmentVariableW(wchar_t const *, wchar_t *, unsigned long); } #endif - - #endif /// // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/src/iostream.cpp b/src/iostream.cpp index ec9235b..af93570 100644 --- a/src/iostream.cpp +++ b/src/iostream.cpp @@ -12,9 +12,10 @@ namespace boost { namespace nowide { - BOOST_NOWIDE_DECL void dummy_exported_function(){} -} -} + BOOST_NOWIDE_DECL void dummy_exported_function() + {} +} // namespace nowide +} // namespace boost #else @@ -23,248 +24,248 @@ namespace nowide { #include #ifndef NOMINMAX -# define NOMINMAX +#define NOMINMAX #endif - #include namespace boost { namespace nowide { -namespace details { + namespace details { + + namespace { + bool is_atty_handle(HANDLE h) + { + if(h) + { + DWORD dummy; + return GetConsoleMode(h, &dummy) == TRUE; + } + return false; + } + } // namespace + + class console_output_buffer : public std::streambuf + { + public: + console_output_buffer(HANDLE h) : handle_(h) + {} + + protected: + int sync() + { + return overflow(traits_type::eof()); + } + int overflow(int c) + { + if(!handle_) + return -1; + int n = static_cast(pptr() - pbase()); + int r = 0; + + if(n > 0 && (r = write(pbase(), n)) < 0) + return -1; + if(r < n) + { + std::memmove(pbase(), pbase() + r, n - r); + } + setp(buffer_, buffer_ + buffer_size); + pbump(n - r); + if(c != traits_type::eof()) + sputc(traits_type::to_char_type(c)); + return 0; + } + + private: + int write(char const *p, int n) + { + namespace uf = detail::utf; + char const *b = p; + char const *e = p + n; + DWORD size = 0; + 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::incomplete) + { + if(c == uf::illegal) + c = BOOST_NOWIDE_REPLACEMENT_CHARACTER; + out = uf::utf_traits::encode(c, out); + decoded = p - b; + } + if(!WriteConsoleW(handle_, wbuffer_, static_cast(out - wbuffer_), &size, 0)) + return -1; + return static_cast(decoded); + } + + static const int buffer_size = 1024; + char buffer_[buffer_size]; + wchar_t wbuffer_[buffer_size]; // for null + HANDLE handle_; + }; + + class console_input_buffer : public std::streambuf + { + public: + console_input_buffer(HANDLE h) : handle_(h), wsize_(0) + {} + + protected: + int pbackfail(int c) + { + if(c == traits_type::eof()) + return traits_type::eof(); + + if(gptr() != eback()) + { + gbump(-1); + *gptr() = traits_type::to_char_type(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() = traits_type::to_char_type(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 = traits_type::to_char_type(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 traits_type::eof(); + return std::char_traits::to_int_type(*gptr()); + } + + private: + size_t read() + { + namespace uf = detail::utf; + DWORD read_wchars = 0; + size_t n = wbuffer_size - wsize_; + if(!ReadConsoleW(handle_, wbuffer_, static_cast(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 = 0; + 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 0; + + if(c == uf::incomplete) + { + std::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_; + size_t 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; + } + if(is_atty_handle(h)) + { + d.reset(new console_output_buffer(h)); + std::ostream::rdbuf(d.get()); + } else + { + std::ostream::rdbuf(fd == 1 ? std::cout.rdbuf() : std::cerr.rdbuf()); + } + } + winconsole_ostream::~winconsole_ostream() + { + try + { + flush(); + } catch(...) + {} + } + + winconsole_istream::winconsole_istream() : std::istream(0) + { + HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if(is_atty_handle(h)) + { + d.reset(new console_input_buffer(h)); + std::istream::rdbuf(d.get()); + } else + { + std::istream::rdbuf(std::cin.rdbuf()); + } + } + + winconsole_istream::~winconsole_istream() + {} + + } // namespace details + + details::winconsole_istream cin; + details::winconsole_ostream cout(1); + details::winconsole_ostream cerr(2); + details::winconsole_ostream clog(2); namespace { - bool is_atty_handle(HANDLE h) + struct initialize { - if(h) { - DWORD dummy; - return GetConsoleMode(h,&dummy) == TRUE; + initialize() + { + boost::nowide::cin.tie(&boost::nowide::cout); + boost::nowide::cerr.tie(&boost::nowide::cout); + boost::nowide::clog.tie(&boost::nowide::cout); } - return false; - } - } + } inst; + } // namespace - class console_output_buffer : public std::streambuf { - public: - console_output_buffer(HANDLE h) : - handle_(h) - { - } - protected: - int sync() - { - return overflow(traits_type::eof()); - } - int overflow(int c) - { - if(!handle_) - return -1; - int n = static_cast(pptr() - pbase()); - int r = 0; - - if(n > 0 && (r=write(pbase(),n)) < 0) - return -1; - if(r < n) { - std::memmove(pbase(),pbase() + r,n-r); - } - setp(buffer_, buffer_ + buffer_size); - pbump(n-r); - if(c!=traits_type::eof()) - sputc(traits_type::to_char_type(c)); - return 0; - } - private: - - int write(char const *p,int n) - { - namespace uf = detail::utf; - char const *b = p; - char const *e = p+n; - DWORD size=0; - 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::incomplete) { - if(c == uf::illegal) - c = BOOST_NOWIDE_REPLACEMENT_CHARACTER; - out = uf::utf_traits::encode(c,out); - decoded = p-b; - } - if(!WriteConsoleW(handle_,wbuffer_,static_cast(out - wbuffer_),&size,0)) - return -1; - return static_cast(decoded); - } - - static const int buffer_size = 1024; - char buffer_[buffer_size]; - wchar_t wbuffer_[buffer_size]; // for null - HANDLE handle_; - }; - - class console_input_buffer: public std::streambuf { - public: - console_input_buffer(HANDLE h) : - handle_(h), - wsize_(0) - { - } - - protected: - int pbackfail(int c) - { - if(c==traits_type::eof()) - return traits_type::eof(); - - if(gptr()!=eback()) { - gbump(-1); - *gptr() = traits_type::to_char_type(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() = traits_type::to_char_type(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 = traits_type::to_char_type(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 traits_type::eof(); - return std::char_traits::to_int_type(*gptr()); - } - - private: - - size_t read() - { - namespace uf = detail::utf; - DWORD read_wchars = 0; - size_t n = wbuffer_size - wsize_; - if(!ReadConsoleW(handle_,wbuffer_,static_cast(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 = 0; - 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 0; - - - if(c==uf::incomplete) { - std::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_; - size_t 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; - } - if(is_atty_handle(h)) { - d.reset(new console_output_buffer(h)); - std::ostream::rdbuf(d.get()); - } - else { - std::ostream::rdbuf( fd == 1 ? std::cout.rdbuf() : std::cerr.rdbuf() ); - } - } - winconsole_ostream::~winconsole_ostream() - { - try { - flush(); - } - catch(...){} - } - - winconsole_istream::winconsole_istream() : std::istream(0) - { - HANDLE h = GetStdHandle(STD_INPUT_HANDLE); - if(is_atty_handle(h)) { - d.reset(new console_input_buffer(h)); - std::istream::rdbuf(d.get()); - } - else { - std::istream::rdbuf(std::cin.rdbuf()); - } - } - - winconsole_istream::~winconsole_istream() - { - } - -} // details - -details::winconsole_istream cin; -details::winconsole_ostream cout(1); -details::winconsole_ostream cerr(2); -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 nowide } // namespace boost #endif diff --git a/standalone/config.hpp b/standalone/config.hpp index b8aca3e..6cb9628 100644 --- a/standalone/config.hpp +++ b/standalone/config.hpp @@ -8,8 +8,7 @@ #ifndef NOWIDE_CONFIG_H_INCLUDED #define NOWIDE_CONFIG_H_INCLUDED - -#if (defined(__WIN32) || defined(_WIN32) || defined(WIN32)) && !defined(__CYGWIN__) +#if(defined(__WIN32) || defined(_WIN32) || defined(WIN32)) && !defined(__CYGWIN__) #define NOWIDE_WINDOWS #endif @@ -18,20 +17,19 @@ #endif #ifdef NOWIDE_WINDOWS -# if defined(DLL_EXPORT) || defined(NOWIDE_EXPORT) -# ifdef NOWIDE_SOURCE -# define NOWIDE_DECL __declspec(dllexport) -# else -# define NOWIDE_DECL __declspec(dllimport) -# endif //NOWIDE_SOURCE -# endif // DYN_LINK +#if defined(DLL_EXPORT) || defined(NOWIDE_EXPORT) +#ifdef NOWIDE_SOURCE +#define NOWIDE_DECL __declspec(dllexport) +#else +#define NOWIDE_DECL __declspec(dllimport) +#endif // NOWIDE_SOURCE +#endif // DYN_LINK #endif #ifndef NOWIDE_DECL -# define NOWIDE_DECL +#define NOWIDE_DECL #endif - #endif /// // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/standalone/scoped_ptr.hpp b/standalone/scoped_ptr.hpp index 497fa1f..cde55ab 100644 --- a/standalone/scoped_ptr.hpp +++ b/standalone/scoped_ptr.hpp @@ -14,80 +14,75 @@ #include -namespace nowide -{ +namespace nowide { // scoped_ptr mimics a built-in pointer except that it guarantees deletion // of the object pointed to, either on destruction of the scoped_ptr or via // an explicit reset(). scoped_ptr is a simple solution for simple needs; // use shared_ptr or std::auto_ptr if your needs are more complex. -template class scoped_ptr // noncopyable +template +class scoped_ptr // noncopyable { private: - - T * px; + T *px; scoped_ptr(scoped_ptr const &); - scoped_ptr & operator=(scoped_ptr const &); + scoped_ptr &operator=(scoped_ptr const &); typedef scoped_ptr this_type; - void operator==( scoped_ptr const& ) const; - void operator!=( scoped_ptr const& ) const; + void operator==(scoped_ptr const &) const; + void operator!=(scoped_ptr const &) const; public: - typedef T element_type; - explicit scoped_ptr( T * p = 0 ): px( p ) // never throws - { - } + explicit scoped_ptr(T *p = 0) : px(p) // never throws + {} ~scoped_ptr() // never throws { delete px; } - void reset(T * p = 0) // never throws + void reset(T *p = 0) // never throws { - assert( p == 0 || p != px ); // catch self-reset errors + assert(p == 0 || p != px); // catch self-reset errors this_type(p).swap(*this); } - T & operator*() const // never throws + T &operator*() const // never throws { - assert( px != 0 ); + assert(px != 0); return *px; } - T * operator->() const // never throws + T *operator->() const // never throws { - assert( px != 0 ); + assert(px != 0); return px; } - T * get() const // never throws + T *get() const // never throws { return px; } operator bool() const { - return px!=0; + return px != 0; } - void swap(scoped_ptr & b) // never throws + void swap(scoped_ptr &b) // never throws { - T * tmp = b.px; + T *tmp = b.px; b.px = px; px = tmp; } }; - } // namespace nowide #endif // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 - diff --git a/test/test.hpp b/test/test.hpp index 775364b..6d9007c 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -10,18 +10,19 @@ #if 0 -#include -#include #include +#include +#include -#define TEST(x) do { \ - if(x) \ - break; \ - std::ostringstream ss; \ - ss<< "Error " #x " in " << __FILE__ \ - <<':'<<__LINE__<<" "<< __FUNCTION__; \ - throw std::runtime_error(ss.str()); \ -}while(0) +#define TEST(x) \ + do \ + { \ + if(x) \ + break; \ + std::ostringstream ss; \ + ss << "Error " #x " in " << __FILE__ << ':' << __LINE__ << " " << __FUNCTION__; \ + throw std::runtime_error(ss.str()); \ + } while(0) namespace boost { @@ -39,7 +40,9 @@ int report_errors() #include #define TEST BOOST_TEST -#define BOOST_NOWIDE_TEST_RETURN_FAILURE BOOST_TEST(false); return boost::report_errors() +#define BOOST_NOWIDE_TEST_RETURN_FAILURE \ + BOOST_TEST(false); \ + return boost::report_errors() #endif diff --git a/test/test_codecvt.cpp b/test/test_codecvt.cpp index 5d8179f..73c6d6d 100644 --- a/test/test_codecvt.cpp +++ b/test/test_codecvt.cpp @@ -6,35 +6,35 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include -#include -#include -#include -#include -#include -#include #include "test.hpp" #include "test_sets.hpp" +#include +#include +#include +#include +#include +#include +#include -static char const * utf8_name = "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt"; +static char const *utf8_name = "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt"; static const std::wstring wide_name_str = boost::nowide::widen(utf8_name); -static wchar_t const * wide_name = wide_name_str.c_str(); +static wchar_t const *wide_name = wide_name_str.c_str(); char const *res(std::codecvt_base::result r) { - switch(r){ + switch(r) + { case std::codecvt_base::ok: return "ok"; case std::codecvt_base::partial: return "partial"; case std::codecvt_base::error: return "error"; case std::codecvt_base::noconv: return "noconv"; - default: - return "error"; + default: return "error"; } } -typedef std::codecvt cvt_type; +typedef std::codecvt cvt_type; -void test_codecvt_in_n_m(cvt_type const &cvt,int n,int m) +void test_codecvt_in_n_m(cvt_type const &cvt, int n, int m) { wchar_t const *wptr = wide_name; size_t wlen = std::wcslen(wide_name); @@ -43,9 +43,11 @@ void test_codecvt_in_n_m(cvt_type const &cvt,int n,int m) char const *end = from; char const *real_end = utf8_name + u8len; char const *from_next = from; - std::mbstate_t mb=std::mbstate_t(); - while(from_next < real_end) { - if(from == end) { + std::mbstate_t mb = std::mbstate_t(); + while(from_next < real_end) + { + if(from == end) + { end = from + n; if(end > real_end) end = real_end; @@ -56,50 +58,50 @@ void test_codecvt_in_n_m(cvt_type const &cvt,int n,int m) wchar_t *to_end = to + m; wchar_t *to_next = to; - std::mbstate_t mb2 = mb; - std::codecvt_base::result r = cvt.in(mb,from,end,from_next,to,to_end,to_next); - //std::cout << "In from_size=" << (end-from) << " from move=" << (from_next - from) << " to move= " << to_next - to << " state = " << res(r) << std::endl; + std::codecvt_base::result r = cvt.in(mb, from, end, from_next, to, to_end, to_next); + // std::cout << "In from_size=" << (end-from) << " from move=" << (from_next - from) << " to move= " << to_next - to << " state = " + // << res(r) << std::endl; - int count = cvt.length(mb2,from,end,to_end - to); - #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST - TEST(std::memcmp(&mb,&mb2,sizeof(mb))==0); - if(count != from_next - from) { + int count = cvt.length(mb2, from, end, to_end - to); +#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST + TEST(std::memcmp(&mb, &mb2, sizeof(mb)) == 0); + if(count != from_next - from) + { std::cout << count << " " << from_next - from << std::endl; } TEST(count == from_next - from); - #else +#else TEST(count == to_next - to); - #endif +#endif - - if(r == cvt_type::partial) { - end+=n; + if(r == cvt_type::partial) + { + end += n; if(end > real_end) end = real_end; - } - else + } else TEST(r == cvt_type::ok); - while(to!=to_next) { + while(to != to_next) + { TEST(*wptr == *to); wptr++; to++; } - to=to_next; + to = to_next; from = from_next; } TEST(wptr == wide_name + wlen); TEST(from == real_end); - } -void test_codecvt_out_n_m(cvt_type const &cvt,int n,int m) +void test_codecvt_out_n_m(cvt_type const &cvt, int n, int m) { char const *nptr = utf8_name; size_t wlen = std::wcslen(wide_name); size_t u8len = std::strlen(utf8_name); - std::mbstate_t mb=std::mbstate_t(); + std::mbstate_t mb = std::mbstate_t(); wchar_t const *from_next = wide_name; wchar_t const *real_from_end = wide_name + wlen; @@ -110,28 +112,33 @@ void test_codecvt_out_n_m(cvt_type const &cvt,int n,int m) char *to_end = to + n; char *real_to_end = buf + sizeof(buf); - while(from_next < real_from_end) { + while(from_next < real_from_end) + { wchar_t const *from = from_next; wchar_t const *from_end = from + m; if(from_end > real_from_end) from_end = real_from_end; - if(to_end == to) { - to_end = to+n; + if(to_end == to) + { + to_end = to + n; } - std::codecvt_base::result r = cvt.out(mb,from,from_end,from_next,to,to_end,to_next); - //std::cout << "In from_size=" << (end-from) << " from move=" << (from_next - from) << " to move= " << to_next - to << " state = " << res(r) << std::endl; - if(r == cvt_type::partial) { + std::codecvt_base::result r = cvt.out(mb, from, from_end, from_next, to, to_end, to_next); + // std::cout << "In from_size=" << (end-from) << " from move=" << (from_next - from) << " to move= " << to_next - to << " state = " + // << res(r) << std::endl; + if(r == cvt_type::partial) + { TEST(to_end - to_next < cvt.max_length()); to_end += n; if(to_end > real_to_end) to_end = real_to_end; - } - else { + } else + { TEST(r == cvt_type::ok); } - while(to!=to_next) { + while(to != to_next) + { TEST(*nptr == *to); nptr++; to++; @@ -140,27 +147,28 @@ void test_codecvt_out_n_m(cvt_type const &cvt,int n,int m) } TEST(nptr == utf8_name + u8len); TEST(from_next == real_from_end); - TEST(cvt.unshift(mb,to,to+n,to_next)==cvt_type::ok); + TEST(cvt.unshift(mb, to, to + n, to_next) == cvt_type::ok); TEST(to_next == to); - } - void test_codecvt_conv() { std::cout << "Conversions " << std::endl; - std::locale l(std::locale::classic(),new boost::nowide::utf8_codecvt()); + std::locale l(std::locale::classic(), new boost::nowide::utf8_codecvt()); cvt_type const &cvt = std::use_facet(l); - for(int i=1;i<=(int)std::strlen(utf8_name)+1;i++) { - for(int j=1;j<=(int)std::wcslen(wide_name)+1;j++) { - try { - test_codecvt_in_n_m(cvt,i,j); - test_codecvt_out_n_m(cvt,i,j); - } - catch(...) { - std::cerr << "Wlen=" <()); + std::locale l(std::locale::classic(), new boost::nowide::utf8_codecvt()); cvt_type const &cvt = std::use_facet(l); std::cout << "- UTF-8" << std::endl; { - wchar_t buf[4]; - wchar_t * const to=buf; - wchar_t * const to_end = buf+4; - wchar_t * to_next = to; - char const *err_utf="1\xFF\xFF\xd7\xa9"; + wchar_t *const to = buf; + wchar_t *const to_end = buf + 4; + wchar_t *to_next = to; + char const *err_utf = "1\xFF\xFF\xd7\xa9"; { - std::mbstate_t mb=std::mbstate_t(); - char const *from=err_utf; + std::mbstate_t mb = std::mbstate_t(); + char const *from = err_utf; char const *from_end = from + std::strlen(from); char const *from_next = from; to_next = to; - TEST(cvt.in(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::ok); - TEST(from_next == from+5); + TEST(cvt.in(mb, from, from_end, from_next, to, to_end, to_next) == cvt_type::ok); + TEST(from_next == from + 5); TEST(to_next == to + 4); TEST(std::wstring(to, to_end) == boost::nowide::widen(err_utf)); } @@ -197,92 +204,87 @@ void test_codecvt_err() std::cout << "- UTF-16/32" << std::endl; { - char buf[32]; - char *to=buf; - char *to_end = buf+32; + char *to = buf; + char *to_end = buf + 32; char *to_next = to; - wchar_t err_buf[3] = { '1' , 0xDC9E, 0 }; // second surrogate not works both for UTF-16 and 32 + wchar_t err_buf[3] = {'1', 0xDC9E, 0}; // second surrogate not works both for UTF-16 and 32 wchar_t const *err_utf = err_buf; { - std::mbstate_t mb=std::mbstate_t(); - wchar_t const *from=err_utf; + std::mbstate_t mb = std::mbstate_t(); + wchar_t const *from = err_utf; wchar_t const *from_end = from + std::wcslen(from); wchar_t const *from_next = from; - TEST(cvt.out(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::ok); - TEST(from_next == from+2); + TEST(cvt.out(mb, from, from_end, from_next, to, to_end, to_next) == cvt_type::ok); + TEST(from_next == from + 2); TEST(to_next == to + 4); - TEST(std::memcmp(to,"1\xEF\xBF\xBD",4)==0); + TEST(std::memcmp(to, "1\xEF\xBF\xBD", 4) == 0); } } - } std::wstring codecvt_to_wide(std::string const &s) { - std::locale l(std::locale::classic(),new boost::nowide::utf8_codecvt()); + std::locale l(std::locale::classic(), new boost::nowide::utf8_codecvt()); cvt_type const &cvt = std::use_facet(l); - std::vector output(s.size()+1); + std::vector output(s.size() + 1); - std::mbstate_t mb=std::mbstate_t(); - char const *from=s.c_str(); + std::mbstate_t mb = std::mbstate_t(); + char const *from = s.c_str(); char const *from_end = from + s.size(); char const *from_next = from; - std::vector buf(s.size()+1); - wchar_t *to=&buf[0]; + std::vector buf(s.size() + 1); + wchar_t *to = &buf[0]; wchar_t *to_end = to + buf.size(); wchar_t *to_next = to; - TEST(cvt.in(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::ok); + TEST(cvt.in(mb, from, from_end, from_next, to, to_end, to_next) == cvt_type::ok); - std::wstring res(to,to_next); + std::wstring res(to, to_next); return res; - } - std::string codecvt_to_narrow(std::wstring const &s) { - std::locale l(std::locale::classic(),new boost::nowide::utf8_codecvt()); + std::locale l(std::locale::classic(), new boost::nowide::utf8_codecvt()); cvt_type const &cvt = std::use_facet(l); - std::vector output(s.size()+1); + std::vector output(s.size() + 1); - std::mbstate_t mb=std::mbstate_t(); - wchar_t const *from=s.c_str(); + std::mbstate_t mb = std::mbstate_t(); + wchar_t const *from = s.c_str(); wchar_t const *from_end = from + s.size(); wchar_t const *from_next = from; std::vector buf(s.size() * 4 + 1); - char *to=&buf[0]; + char *to = &buf[0]; char *to_end = to + buf.size(); char *to_next = to; - TEST(cvt.out(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::ok); + TEST(cvt.out(mb, from, from_end, from_next, to, to_end, to_next) == cvt_type::ok); - std::string res(to,to_next); + std::string res(to, to_next); return res; - } - void test_codecvt_subst() { std::cout << "Substitutions " << std::endl; - run_all(codecvt_to_wide,codecvt_to_narrow); + run_all(codecvt_to_wide, codecvt_to_narrow); } int main() { - try { + try + { test_codecvt_conv(); test_codecvt_err(); test_codecvt_subst(); - } - catch(std::exception const &e) { + } catch(std::exception const &e) + { std::cerr << "Failed : " << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } diff --git a/test/test_convert.cpp b/test/test_convert.cpp index 0da2046..510662c 100644 --- a/test/test_convert.cpp +++ b/test/test_convert.cpp @@ -6,20 +6,21 @@ // http://www.boost.org/LICENSE_1_0.txt) // +#include "test.hpp" +#include "test_sets.hpp" #include #include #include -#include "test.hpp" -#include "test_sets.hpp" #include #if BOOST_WORKAROUND(BOOST_MSVC, < 1700) -# pragma warning(disable: 4428) // universal-character-name encountered in source +#pragma warning(disable : 4428) // universal-character-name encountered in source #endif int main() { - try { + try + { std::string hello = "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d"; std::wstring whello = L"\u05e9\u05dc\u05d5\u05dd"; std::wstring whello_3e = L"\u05e9\u05dc\u05d5\ufffd"; @@ -30,99 +31,98 @@ int main() std::cout << "- boost::nowide::widen" << std::endl; { - char const *b=hello.c_str(); - char const *e=b+8; - wchar_t buf[6] = { 0,0,0,0,0,1 }; - TEST(boost::nowide::widen(buf,5,b,e)==buf); + char const *b = hello.c_str(); + char const *e = b + 8; + wchar_t buf[6] = {0, 0, 0, 0, 0, 1}; + TEST(boost::nowide::widen(buf, 5, b, e) == buf); TEST(buf == whello); TEST(buf[5] == 1); - TEST(boost::nowide::widen(buf,4,b,e)==0); - TEST(boost::nowide::widen(buf,5,b,e-1)==buf); + TEST(boost::nowide::widen(buf, 4, b, e) == 0); + TEST(boost::nowide::widen(buf, 5, b, e - 1) == buf); TEST(buf == whello_3e); - TEST(boost::nowide::widen(buf,5,b,e-2)==buf); + TEST(boost::nowide::widen(buf, 5, b, e - 2) == buf); TEST(buf == whello_3); - TEST(boost::nowide::widen(buf,5,b,b)==buf && buf[0]==0); - TEST(boost::nowide::widen(buf,5,b,b+2)==buf && buf[1]==0 && buf[0]==whello[0]); - b="\xFF\xFF"; - e=b+2; - TEST(boost::nowide::widen(buf,5,b,e)==buf); + TEST(boost::nowide::widen(buf, 5, b, b) == buf && buf[0] == 0); + TEST(boost::nowide::widen(buf, 5, b, b + 2) == buf && buf[1] == 0 && buf[0] == whello[0]); + b = "\xFF\xFF"; + e = b + 2; + TEST(boost::nowide::widen(buf, 5, b, e) == buf); TEST(buf == std::wstring(L"\ufffd\ufffd")); - b="\xd7\xa9\xFF"; - e=b+3; - TEST(boost::nowide::widen(buf,5,b,e)==buf); + b = "\xd7\xa9\xFF"; + e = b + 3; + TEST(boost::nowide::widen(buf, 5, b, e) == buf); TEST(buf == std::wstring(L"\u05e9\ufffd")); - TEST(boost::nowide::widen(buf,5,b,b+1)==buf); + TEST(boost::nowide::widen(buf, 5, b, b + 1) == buf); TEST(buf == std::wstring(L"\ufffd")); - b="\xFF\xd7\xa9"; - e=b+3; - TEST(boost::nowide::widen(buf,5,b,e)==buf); + b = "\xFF\xd7\xa9"; + e = b + 3; + TEST(boost::nowide::widen(buf, 5, b, e) == buf); TEST(buf == std::wstring(L"\ufffd\u05e9")); TEST(boost::nowide::widen(example) == wexample); } std::cout << "- boost::nowide::narrow" << std::endl; { - wchar_t const *b=whello.c_str(); - wchar_t const *e=b+4; + wchar_t const *b = whello.c_str(); + wchar_t const *e = b + 4; char buf[10] = {0}; - buf[9]=1; - TEST(boost::nowide::narrow(buf,9,b,e)==buf); + buf[9] = 1; + TEST(boost::nowide::narrow(buf, 9, b, e) == buf); TEST(buf == hello); TEST(buf[9] == 1); - TEST(boost::nowide::narrow(buf,8,b,e)==0); - TEST(boost::nowide::narrow(buf,7,b,e-1)==buf); - TEST(buf==hello.substr(0,6)); - wchar_t tmp[3] = { 0xDC01,0x05e9,0 }; + TEST(boost::nowide::narrow(buf, 8, b, e) == 0); + TEST(boost::nowide::narrow(buf, 7, b, e - 1) == buf); + TEST(buf == hello.substr(0, 6)); + wchar_t tmp[3] = {0xDC01, 0x05e9, 0}; b = tmp; - TEST(boost::nowide::narrow(buf,10,b,b+2)==buf); + TEST(boost::nowide::narrow(buf, 10, b, b + 2) == buf); TEST(buf == std::string("\xEF\xBF\xBD\xd7\xa9")); - wchar_t tmp2[3] = { 0x05e9, 0xD800,0 }; + wchar_t tmp2[3] = {0x05e9, 0xD800, 0}; b = tmp2; - TEST(boost::nowide::narrow(buf,10,b,b+2)==buf); + TEST(boost::nowide::narrow(buf, 10, b, b + 2) == buf); TEST(buf == std::string("\xd7\xa9\xEF\xBF\xBD")); TEST(boost::nowide::narrow(wexample) == example); } { char buf[3]; wchar_t wbuf[3]; - TEST(boost::nowide::narrow(buf,3,L"xy")==std::string("xy")); - TEST(boost::nowide::widen(wbuf,3,"xy")==std::wstring(L"xy")); + TEST(boost::nowide::narrow(buf, 3, L"xy") == std::string("xy")); + TEST(boost::nowide::widen(wbuf, 3, "xy") == std::wstring(L"xy")); } std::cout << "- boost::nowide::stackstring" << std::endl; { { - boost::nowide::basic_stackstring sw; + boost::nowide::basic_stackstring sw; TEST(sw.convert(hello.c_str())); TEST(sw.c_str() == whello); - TEST(sw.convert(hello.c_str(),hello.c_str()+hello.size())); + TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size())); TEST(sw.c_str() == whello); } { - boost::nowide::basic_stackstring sw; + boost::nowide::basic_stackstring sw; TEST(sw.convert(hello.c_str())); TEST(sw.c_str() == whello); - TEST(sw.convert(hello.c_str(),hello.c_str()+hello.size())); + TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size())); TEST(sw.c_str() == whello); } { - boost::nowide::basic_stackstring sw; + boost::nowide::basic_stackstring sw; TEST(sw.convert(whello.c_str())); TEST(sw.c_str() == hello); - TEST(sw.convert(whello.c_str(),whello.c_str()+whello.size())); + TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size())); TEST(sw.c_str() == hello); } { - boost::nowide::basic_stackstring sw; + boost::nowide::basic_stackstring sw; TEST(sw.convert(whello.c_str())); TEST(sw.c_str() == hello); - TEST(sw.convert(whello.c_str(),whello.c_str()+whello.size())); + TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size())); TEST(sw.c_str() == hello); } std::cout << "- Substitutions" << std::endl; - run_all(boost::nowide::widen,boost::nowide::narrow); - + run_all(boost::nowide::widen, boost::nowide::narrow); } - } - catch(std::exception const &e) { + } catch(std::exception const &e) + { std::cerr << "Failed :" << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } @@ -130,6 +130,5 @@ int main() return boost::report_errors(); } - /// // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/test/test_env.cpp b/test/test_env.cpp index fd49bf9..0036ffb 100644 --- a/test/test_env.cpp +++ b/test/test_env.cpp @@ -7,7 +7,7 @@ // #ifdef _MSC_VER -# define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS #endif #include @@ -21,34 +21,35 @@ int main() { - try { + try + { std::string example = "\xd7\xa9-\xd0\xbc-\xce\xbd"; char penv[256] = {0}; - strncpy(penv,("BOOST_TEST2=" + example + "x").c_str(),sizeof(penv)-1); + strncpy(penv, ("BOOST_TEST2=" + example + "x").c_str(), sizeof(penv) - 1); - TEST(boost::nowide::setenv("BOOST_TEST1",example.c_str(),1)==0); + TEST(boost::nowide::setenv("BOOST_TEST1", example.c_str(), 1) == 0); TEST(boost::nowide::getenv("BOOST_TEST1")); - TEST(boost::nowide::getenv("BOOST_TEST1")==example); - TEST(boost::nowide::setenv("BOOST_TEST1","xx",0)==0); - TEST(boost::nowide::getenv("BOOST_TEST1")==example); - TEST(boost::nowide::putenv(penv)==0); + TEST(boost::nowide::getenv("BOOST_TEST1") == example); + TEST(boost::nowide::setenv("BOOST_TEST1", "xx", 0) == 0); + TEST(boost::nowide::getenv("BOOST_TEST1") == example); + TEST(boost::nowide::putenv(penv) == 0); TEST(boost::nowide::getenv("BOOST_TEST2")); - TEST(boost::nowide::getenv("BOOST_TEST_INVALID")==0); - TEST(boost::nowide::getenv("BOOST_TEST2")==example + "x"); + TEST(boost::nowide::getenv("BOOST_TEST_INVALID") == 0); + TEST(boost::nowide::getenv("BOOST_TEST2") == example + "x"); #ifdef BOOST_WINDOWS // Passing a variable without an equals sign (before \0) is an error // But GLIBC has an extension that unsets the env var instead char penv2[256] = {0}; - const char* sPenv2 = "BOOST_TEST1SOMEGARBAGE="; + const char *sPenv2 = "BOOST_TEST1SOMEGARBAGE="; strncpy(penv2, sPenv2, sizeof(penv2) - 1); // End the string before the equals sign -> Expect fail penv2[strlen("BOOST_TEST1")] = '\0'; - TEST(boost::nowide::putenv(penv2)==-1); + TEST(boost::nowide::putenv(penv2) == -1); TEST(boost::nowide::getenv("BOOST_TEST1")); - TEST(boost::nowide::getenv("BOOST_TEST1")==example); + TEST(boost::nowide::getenv("BOOST_TEST1") == example); #endif - } - catch(std::exception const &e) { + } catch(std::exception const &e) + { std::cerr << "Failed " << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } diff --git a/test/test_fs.cpp b/test/test_fs.cpp index 926f7e9..16ab6bc 100644 --- a/test/test_fs.cpp +++ b/test/test_fs.cpp @@ -7,12 +7,12 @@ // #ifdef _MSC_VER -# define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS #endif -#include -#include #include +#include +#include #include #include #include @@ -21,11 +21,12 @@ int main() { - try { + try + { boost::nowide::nowide_filesystem(); - const std::string prefix = boost::filesystem::unique_path( "nowide-%%%%-%%%%-" ).string(); - const std::string utf8_name = prefix + - "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt"; + const std::string prefix = boost::filesystem::unique_path("nowide-%%%%-%%%%-").string(); + const std::string utf8_name = + prefix + "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt"; boost::nowide::ofstream f(utf8_name.c_str()); TEST(f); @@ -39,8 +40,8 @@ int main() TEST(!boost::filesystem::is_regular_file(boost::nowide::widen(utf8_name))); TEST(!boost::filesystem::is_regular_file(utf8_name)); - } - catch(std::exception const &e) { + } catch(std::exception const &e) + { std::cerr << "Failed : " << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } diff --git a/test/test_fstream.cpp b/test/test_fstream.cpp index 004fe50..71fae2e 100644 --- a/test/test_fstream.cpp +++ b/test/test_fstream.cpp @@ -7,64 +7,66 @@ // #ifdef _MSC_VER -# define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS #endif -#include -#include -#include #include "test.hpp" +#include +#include +#include - -int main(int, char** argv) +int main(int, char **argv) { const std::string prefix = argv[0]; - std::string example_str = prefix + "\xd7\xa9-\xd0\xbc-\xce\xbd" ".txt"; + std::string example_str = prefix + + "\xd7\xa9-\xd0\xbc-\xce\xbd" + ".txt"; - char const * example = example_str.c_str(); + char const *example = example_str.c_str(); - try { - namespace nw=boost::nowide; + try + { + namespace nw = boost::nowide; std::cout << "Testing fstream" << std::endl; { nw::ofstream fo; fo.open(example); TEST(fo); - fo<<"test"<> tmp; - TEST(tmp=="test"); + fi >> tmp; + TEST(tmp == "test"); fi.close(); } { nw::ifstream fi(example); TEST(fi); std::string tmp; - fi >> tmp; - TEST(tmp=="test"); + fi >> tmp; + TEST(tmp == "test"); fi.close(); } - #if defined(BOOST_WINDOWS) || defined(BOOST_NOWIDE_FSTREAM_TESTS) +#if defined(BOOST_WINDOWS) || defined(BOOST_NOWIDE_FSTREAM_TESTS) // C++11 interfaces aren't enabled at all platforms so need to skip // for std::*fstream { @@ -72,8 +74,8 @@ int main(int, char** argv) nw::ifstream fi(name); TEST(fi); std::string tmp; - fi >> tmp; - TEST(tmp=="test"); + fi >> tmp; + TEST(tmp == "test"); fi.close(); } { @@ -81,17 +83,17 @@ int main(int, char** argv) fi.open(std::string(example)); TEST(fi); std::string tmp; - fi >> tmp; - TEST(tmp=="test"); + fi >> tmp; + TEST(tmp == "test"); fi.close(); } - #endif +#endif { - nw::ifstream fi(example,std::ios::binary); + nw::ifstream fi(example, std::ios::binary); TEST(fi); std::string tmp; - fi >> tmp; - TEST(tmp=="test"); + fi >> tmp; + TEST(tmp == "test"); fi.close(); } @@ -102,20 +104,20 @@ int main(int, char** argv) TEST(!fi); } { - nw::fstream f(example,nw::fstream::in | nw::fstream::out | nw::fstream::trunc | nw::fstream::binary); + nw::fstream f(example, nw::fstream::in | nw::fstream::out | nw::fstream::trunc | nw::fstream::binary); TEST(f); - f << "test2" ; + f << "test2"; std::string tmp; f.seekg(0); - f>> tmp; - TEST(tmp=="test2"); + f >> tmp; + TEST(tmp == "test2"); f.close(); } { - nw::ifstream fi(example,nw::fstream::ate | nw::fstream::binary); + nw::ifstream fi(example, nw::fstream::ate | nw::fstream::binary); TEST(fi); - TEST(fi.tellg()==std::streampos(5)); - fi.seekg(-2,std::ios_base::cur); + TEST(fi.tellg() == std::streampos(5)); + fi.seekg(-2, std::ios_base::cur); std::string tmp; fi >> tmp; TEST(tmp == "t2"); @@ -124,16 +126,17 @@ int main(int, char** argv) nw::remove(example); } - for(int i=-1;i<16;i++) { + for(int i = -1; i < 16; i++) + { std::cout << "Complex io with buffer = " << i << std::endl; char buf[16]; nw::fstream f; - if(i==0) - f.rdbuf()->pubsetbuf(0,0); - else if (i > 0) - f.rdbuf()->pubsetbuf(buf,i); + if(i == 0) + f.rdbuf()->pubsetbuf(0, 0); + else if(i > 0) + f.rdbuf()->pubsetbuf(buf, i); - f.open(example,nw::fstream::in | nw::fstream::out | nw::fstream::trunc | nw::fstream::binary); + f.open(example, nw::fstream::in | nw::fstream::out | nw::fstream::trunc | nw::fstream::binary); f.put('a'); f.put('b'); f.put('c'); @@ -142,37 +145,37 @@ int main(int, char** argv) f.put('f'); f.put('g'); f.seekg(0); - TEST(f.get()=='a'); - f.seekg(1,std::ios::cur); - TEST(f.get()=='c'); - f.seekg(-1,std::ios::cur); - TEST(f.get()=='c'); + TEST(f.get() == 'a'); + f.seekg(1, std::ios::cur); + TEST(f.get() == 'c'); + f.seekg(-1, std::ios::cur); + TEST(f.get() == 'c'); TEST(f.seekg(1)); f.put('B'); TEST(f.flush()); // Flush or seek needed when changing out->in - TEST(f.get()=='c'); + TEST(f.get() == 'c'); TEST(f.seekg(1)); TEST(f.get() == 'B'); f.seekg(2); f.put('C'); TEST(f.seekg(3)); // Flush or seek needed when changing out->in - TEST(f.get()=='d'); + TEST(f.get() == 'd'); f.seekg(0); - TEST(f.get()=='a'); - TEST(f.get()=='B'); - TEST(f.get()=='C'); - TEST(f.get()=='d'); - TEST(f.get()=='e'); + TEST(f.get() == 'a'); + TEST(f.get() == 'B'); + TEST(f.get() == 'C'); + TEST(f.get() == 'd'); + TEST(f.get() == 'e'); TEST(f.putback('e')); TEST(f.putback('d')); - TEST(f.get()=='d'); - TEST(f.get()=='e'); - TEST(f.get()=='f'); - TEST(f.get()=='g'); - TEST(f.get()==EOF); + TEST(f.get() == 'd'); + TEST(f.get() == 'e'); + TEST(f.get() == 'f'); + TEST(f.get() == 'g'); + TEST(f.get() == EOF); f.clear(); f.seekg(1); - TEST(f.get()=='B'); + TEST(f.get() == 'B'); TEST(f.putback('B')); #if !defined(_LIBCPP_VERSION) // libc++ fails this putback @@ -180,11 +183,10 @@ int main(int, char** argv) TEST(!f.putback('x')); #endif f.close(); - TEST(boost::nowide::remove(example)==0); - + TEST(boost::nowide::remove(example) == 0); } - } - catch(std::exception const &e) { + } catch(std::exception const &e) + { std::cerr << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } diff --git a/test/test_iostream.cpp b/test/test_iostream.cpp index 9682d85..95701ee 100644 --- a/test/test_iostream.cpp +++ b/test/test_iostream.cpp @@ -6,16 +6,18 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include #include +#include #include #include #include "test.hpp" -bool isValidUTF8(const std::string& s){ +bool isValidUTF8(const std::string &s) +{ using namespace boost::nowide::detail::utf; - for(std::string::const_iterator it = s.begin(); it != s.end();){ + for(std::string::const_iterator it = s.begin(); it != s.end();) + { code_point c = utf_traits::decode(it, s.end()); if(!is_valid_codepoint(c)) return false; @@ -23,34 +25,38 @@ bool isValidUTF8(const std::string& s){ return true; } -int main(int argc,char **argv) +int main(int argc, char **argv) { - char const *example = "Basic letters: \xd7\xa9-\xd0\xbc-\xce\xbd\n" "East Asian Letters: \xe5\x92\x8c\xe5\xb9\xb3\n" "Non-BMP letters: \xf0\x9d\x84\x9e\n" - "Invalid UTF-8: `\xFF' `\xd7\xFF' `\xe5\xFF\x8c' `\xf0\x9d\x84\xFF' \n" - "\n" - ; + "Invalid UTF-8: `\xFF' `\xd7\xFF' `\xe5\xFF\x8c' `\xf0\x9d\x84\xFF' \n" + "\n"; - try { + try + { // If we are using the standard rdbuf we can only put back 1 char - if(boost::nowide::cin.rdbuf() == std::cin.rdbuf()) { + if(boost::nowide::cin.rdbuf() == std::cin.rdbuf()) + { std::cout << "Using std::cin" << std::endl; int maxval = 15000; - for(int i = 0; i < maxval; i++) { + for(int i = 0; i < maxval; i++) + { char c = i % 96 + ' '; TEST(boost::nowide::cin.putback(c)); int ci = i % 96 + ' '; TEST(boost::nowide::cin.get() == ci); } - } else { + } else + { int maxval = 15000; - for(int i = 0; i < maxval; i++) { + for(int i = 0; i < maxval; i++) + { char c = i % 96 + ' '; TEST(boost::nowide::cin.putback(c)); } - for(int i = maxval - 1; i >= 0; i--) { + for(int i = maxval - 1; i >= 0; i--) + { int c = i % 96 + ' '; TEST(boost::nowide::cin.get() == c); } @@ -61,25 +67,27 @@ int main(int argc,char **argv) boost::nowide::cout << "Flushing each character:" << std::endl; - for(char const *s=example;*s;s++) { + for(char const *s = example; *s; s++) + { boost::nowide::cout << *s << std::flush; TEST(boost::nowide::cout); } TEST(boost::nowide::cout); TEST(boost::nowide::cerr); - if(argc==2 && argv[1]==std::string("-i")) { + if(argc == 2 && argv[1] == std::string("-i")) + { std::string v1, v2; boost::nowide::cin >> v1 >> v2; TEST(boost::nowide::cin); TEST(isValidUTF8(v1)); TEST(isValidUTF8(v2)); - boost::nowide::cout << "First: "<< v1 << std::endl; - boost::nowide::cout << "Second: "<< v2 << std::endl; + boost::nowide::cout << "First: " << v1 << std::endl; + boost::nowide::cout << "Second: " << v2 << std::endl; TEST(boost::nowide::cout); } - } - catch(std::exception const &e) { + } catch(std::exception const &e) + { std::cerr << "Fail: " << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } diff --git a/test/test_sets.hpp b/test/test_sets.hpp index 0bb4f55..e979048 100644 --- a/test/test_sets.hpp +++ b/test/test_sets.hpp @@ -11,152 +11,103 @@ #include #include -struct utf8_to_wide { +struct utf8_to_wide +{ char const *utf8; wchar_t const *wide; }; -struct wide_to_utf8 { +struct wide_to_utf8 +{ wchar_t const *wide; char const *utf8; }; #if BOOST_WORKAROUND(BOOST_MSVC, < 1700) -# pragma warning(push) -# pragma warning(disable: 4428) // universal-character-name encountered in source +#pragma warning(push) +#pragma warning(disable : 4428) // universal-character-name encountered in source #endif -utf8_to_wide n2w_tests[] = { - { - "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", - L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt" - }, - { - "\xFF\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82", - L"\uFFFD\u043F\u0440\u0438\u0432\u0435\u0442" - }, - { - "\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\xFF", - L"\u043F\u0440\u0438\u0432\u0435\u0442\uFFFD" - }, - { - "\xE3\x82\xFF\xE3\x81\x82", - L"\ufffd\u3042" - }, - { - "\xE3\xFF\x84\xE3\x81\x82", - L"\ufffd\ufffd\u3042" - } -}; - -utf8_to_wide u2w_tests[] = { - { - "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", - L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt" - }, - { - "\xFF\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82", - L"\uFFFD\u043F\u0440\u0438\u0432\u0435\u0442" - }, - { - "\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\xFF", - L"\u043F\u0440\u0438\u0432\u0435\u0442\uFFFD" - }, - { - "\xE3\x82\xFF\xE3\x81\x82", - L"\ufffd\u3042" - }, - { - "\xE3\xFF\x84\xE3\x81\x82", - L"\ufffd\ufffd\u3042" - } -}; +utf8_to_wide n2w_tests[] = {{"\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", + L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt"}, + {"\xFF\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82", L"\uFFFD\u043F\u0440\u0438\u0432\u0435\u0442"}, + {"\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\xFF", L"\u043F\u0440\u0438\u0432\u0435\u0442\uFFFD"}, + {"\xE3\x82\xFF\xE3\x81\x82", L"\ufffd\u3042"}, + {"\xE3\xFF\x84\xE3\x81\x82", L"\ufffd\ufffd\u3042"}}; +utf8_to_wide u2w_tests[] = {{"\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", + L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt"}, + {"\xFF\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82", L"\uFFFD\u043F\u0440\u0438\u0432\u0435\u0442"}, + {"\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\xFF", L"\u043F\u0440\u0438\u0432\u0435\u0442\uFFFD"}, + {"\xE3\x82\xFF\xE3\x81\x82", L"\ufffd\u3042"}, + {"\xE3\xFF\x84\xE3\x81\x82", L"\ufffd\ufffd\u3042"}}; wide_to_utf8 w2n_tests_utf16[] = { - { - L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt", - "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", - }, - { - L"\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xEF\xBF\xBD\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - }, - { - L"\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - }, - { - L"\u3084\u3042\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - }, - { - L"\u3084\u3042\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - } -}; - + { + L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt", + "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", + }, + {L"\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xEF\xBF\xBD\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}, + {L"\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}, + {L"\u3084\u3042\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}, + {L"\u3084\u3042\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}}; wide_to_utf8 w2n_tests_utf32[] = { - { - L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt", - "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", - }, - { - L"\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - }, - { - L"\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - }, - { - L"\u3084\u3042\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - }, - { - L"\u3084\u3042\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", - "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82" - } -}; + { + L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt", + "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt", + }, + {L"\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}, + {L"\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}, + {L"\u3084\u3042\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}, + {L"\u3084\u3042\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042", + "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"}}; #if BOOST_WORKAROUND(BOOST_MSVC, < 1700) -# pragma warning(pop) +#pragma warning(pop) #endif #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4127) // Constant expression detected +#pragma warning(push) +#pragma warning(disable : 4127) // Constant expression detected #endif -void run_all(std::wstring (*to_wide)(std::string const &),std::string (*to_narrow)(std::wstring const &)) +void run_all(std::wstring (*to_wide)(std::string const &), std::string (*to_narrow)(std::wstring const &)) { - for(size_t i=0;i -#include #include +#include #include "test.hpp" -int main(int, char** argv) +int main(int, char **argv) { const std::string prefix = argv[0]; const std::string example = prefix + "\xd7\xa9-\xd0\xbc-\xce\xbd.txt"; - try { - #ifdef BOOST_WINDOWS - FILE *f=_wfopen(boost::nowide::widen(example).c_str(),L"w"); - #else - FILE *f=std::fopen(example.c_str(),"w"); - #endif + try + { +#ifdef BOOST_WINDOWS + FILE *f = _wfopen(boost::nowide::widen(example).c_str(), L"w"); +#else + FILE *f = std::fopen(example.c_str(), "w"); +#endif TEST(f); - std::fprintf(f,"test\n"); + std::fprintf(f, "test\n"); std::fclose(f); - f=0; + f = 0; - TEST((f=boost::nowide::fopen(example.c_str(),"r"))!=0); + TEST((f = boost::nowide::fopen(example.c_str(), "r")) != 0); char buf[16]; - TEST(std::fgets(buf,16,f)!=0); - TEST(std::strcmp(buf,"test\n")==0); - TEST((f=boost::nowide::freopen(example.c_str(),"r+",f))!=0); + TEST(std::fgets(buf, 16, f) != 0); + TEST(std::strcmp(buf, "test\n") == 0); + TEST((f = boost::nowide::freopen(example.c_str(), "r+", f)) != 0); std::fclose(f); - f=0; + f = 0; - TEST(boost::nowide::rename(example.c_str(),(example+".1").c_str())==0); - TEST(boost::nowide::remove(example.c_str())<0); - TEST((f=boost::nowide::fopen((example+".1").c_str(),"r"))!=0); + TEST(boost::nowide::rename(example.c_str(), (example + ".1").c_str()) == 0); + TEST(boost::nowide::remove(example.c_str()) < 0); + TEST((f = boost::nowide::fopen((example + ".1").c_str(), "r")) != 0); std::fclose(f); - f=0; - TEST(boost::nowide::remove(example.c_str())<0); - TEST(boost::nowide::remove((example+".1").c_str())==0); - } - catch(std::exception const &e) { + f = 0; + TEST(boost::nowide::remove(example.c_str()) < 0); + TEST(boost::nowide::remove((example + ".1").c_str()) == 0); + } catch(std::exception const &e) + { std::cerr << "Failed " << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } diff --git a/test/test_system.cpp b/test/test_system.cpp index db6746c..3e085ac 100644 --- a/test/test_system.cpp +++ b/test/test_system.cpp @@ -6,32 +6,35 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include #include #include +#include #include #include "test.hpp" -int main(int argc,char **argv,char **env) +int main(int argc, char **argv, char **env) { - try { + try + { std::string example = "\xd7\xa9-\xd0\xbc-\xce\xbd"; - boost::nowide::args a(argc,argv,env); - if(argc==2 && argv[1][0]!='-') { - TEST(argv[1]==example); + boost::nowide::args a(argc, argv, env); + if(argc == 2 && argv[1][0] != '-') + { + TEST(argv[1] == example); TEST(argv[2] == 0); TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST")); TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST_NONE") == 0); - TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST")==example); + TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST") == example); std::string sample = "BOOST_NOWIDE_TEST=" + example; bool found = false; - for(char **e=env;*e!=0;e++) { + for(char **e = env; *e != 0; e++) + { char *eptr = *e; - //printf("%s\n",eptr); - char *key_end = strchr(eptr,'='); + // printf("%s\n",eptr); + char *key_end = strchr(eptr, '='); TEST(key_end); - std::string key = std::string(eptr,key_end); + std::string key = std::string(eptr, key_end); std::string value = key_end + 1; TEST(boost::nowide::getenv(key.c_str())); TEST(boost::nowide::getenv(key.c_str()) == value); @@ -40,48 +43,45 @@ int main(int argc,char **argv,char **env) } TEST(found); std::cout << "Subprocess ok" << std::endl; - } - else if(argc==2 && argv[1][0]=='-') { - switch(argv[1][1]) { - case 'w': - { - #ifdef BOOST_WINDOWS - std::wstring env_var = L"BOOST_NOWIDE_TEST=" + boost::nowide::widen(example); - TEST(_wputenv(env_var.c_str()) == 0); - std::wstring wcommand = boost::nowide::widen(argv[0]); - wcommand += L" "; - wcommand += boost::nowide::widen(example); - TEST(_wsystem(wcommand.c_str()) == 0); - std::cout << "Wide Parent ok" << std::endl; - #else - std::cout << "Wide API is irrelevant" << std::endl; - #endif - } - break; - case 'n': - { - TEST(boost::nowide::setenv("BOOST_NOWIDE_TEST",example.c_str(),1) == 0); - TEST(boost::nowide::setenv("BOOST_NOWIDE_TEST_NONE",example.c_str(),1) == 0); - TEST(boost::nowide::unsetenv("BOOST_NOWIDE_TEST_NONE") == 0); - std::string command = "\""; - command += argv[0]; - command += "\" "; - command += example; - TEST(boost::nowide::system(command.c_str()) == 0); - std::cout << "Parent ok" << std::endl; - } - break; - default: - std::cout << "Invalid parameters expected '-n/-w'" << std::endl; - BOOST_NOWIDE_TEST_RETURN_FAILURE; + } else if(argc == 2 && argv[1][0] == '-') + { + switch(argv[1][1]) + { + case 'w': { +#ifdef BOOST_WINDOWS + std::wstring env_var = L"BOOST_NOWIDE_TEST=" + boost::nowide::widen(example); + TEST(_wputenv(env_var.c_str()) == 0); + std::wstring wcommand = boost::nowide::widen(argv[0]); + wcommand += L" "; + wcommand += boost::nowide::widen(example); + TEST(_wsystem(wcommand.c_str()) == 0); + std::cout << "Wide Parent ok" << std::endl; +#else + std::cout << "Wide API is irrelevant" << std::endl; +#endif } - } - else { + break; + case 'n': { + TEST(boost::nowide::setenv("BOOST_NOWIDE_TEST", example.c_str(), 1) == 0); + TEST(boost::nowide::setenv("BOOST_NOWIDE_TEST_NONE", example.c_str(), 1) == 0); + TEST(boost::nowide::unsetenv("BOOST_NOWIDE_TEST_NONE") == 0); + std::string command = "\""; + command += argv[0]; + command += "\" "; + command += example; + TEST(boost::nowide::system(command.c_str()) == 0); + std::cout << "Parent ok" << std::endl; + } + break; + default: std::cout << "Invalid parameters expected '-n/-w'" << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; + } + } else + { std::cerr << "Invalid parameters" << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; } - } - catch(std::exception const &e) { + } catch(std::exception const &e) + { std::cerr << "Failed " << e.what() << std::endl; BOOST_NOWIDE_TEST_RETURN_FAILURE; }