From f771f12027176f14818fe75c9129e78598efa684 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 15 Mar 2021 19:23:49 +0100 Subject: [PATCH 01/67] renamed: std::wstring Toa(...) -> std::wstring to_str(...) added: std::string to_str(...) --- convert/inttostr.cpp | 84 ++++++++++++++++++++++++++++++++++++-------- convert/inttostr.h | 25 ++++++++----- 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/convert/inttostr.cpp b/convert/inttostr.cpp index b4ae639..948ce15 100644 --- a/convert/inttostr.cpp +++ b/convert/inttostr.cpp @@ -41,8 +41,64 @@ namespace PT { +std::string to_str(unsigned long long value, int base) +{ + std::string res; + Toa(value, res, false, base); -std::wstring Toa(unsigned long long value, int base) + return res; +} + + +std::string to_str(long long value, int base) +{ + std::string res; + Toa(value, res, false, base); + + return res; +} + + +std::string to_str(unsigned long value, int base) +{ + return to_str(static_cast(value), base); +} + + +std::string to_str(long value, int base) +{ + return to_str(static_cast(value), base); +} + + +std::string to_str(unsigned int value, int base) +{ + return to_str(static_cast(value), base); +} + + +std::string to_str(int value, int base) +{ + return to_str(static_cast(value), base); +} + + +std::string to_str(unsigned short value, int base) +{ + return to_str(static_cast(value), base); +} + + +std::string to_str(short value, int base) +{ + return to_str(static_cast(value), base); +} + + + + + +std::wstring to_wstr(unsigned long long value, int base) { std::wstring res; Toa(value, res, false, base); @@ -51,7 +107,7 @@ std::wstring Toa(unsigned long long value, int base) } -std::wstring Toa(long long value, int base) +std::wstring to_wstr(long long value, int base) { std::wstring res; Toa(value, res, false, base); @@ -60,39 +116,39 @@ std::wstring Toa(long long value, int base) } -std::wstring Toa(unsigned long value, int base) +std::wstring to_wstr(unsigned long value, int base) { - return Toa(static_cast(value), base); + return to_wstr(static_cast(value), base); } -std::wstring Toa(long value, int base) +std::wstring to_wstr(long value, int base) { - return Toa(static_cast(value), base); + return to_wstr(static_cast(value), base); } -std::wstring Toa(unsigned int value, int base) +std::wstring to_wstr(unsigned int value, int base) { - return Toa(static_cast(value), base); + return to_wstr(static_cast(value), base); } -std::wstring Toa(int value, int base) +std::wstring to_wstr(int value, int base) { - return Toa(static_cast(value), base); + return to_wstr(static_cast(value), base); } -std::wstring Toa(unsigned short value, int base) +std::wstring to_wstr(unsigned short value, int base) { - return Toa(static_cast(value), base); + return to_wstr(static_cast(value), base); } -std::wstring Toa(short value, int base) +std::wstring to_wstr(short value, int base) { - return Toa(static_cast(value), base); + return to_wstr(static_cast(value), base); } diff --git a/convert/inttostr.h b/convert/inttostr.h index 78e7d58..27e2496 100644 --- a/convert/inttostr.h +++ b/convert/inttostr.h @@ -270,14 +270,23 @@ void Toa(short value, StringType & res, bool clear_string = true, int base = 10) -std::wstring Toa(unsigned long long value, int base = 10); -std::wstring Toa(long long value, int base = 10); -std::wstring Toa(unsigned long value, int base = 10); -std::wstring Toa(long value, int base = 10); -std::wstring Toa(unsigned int value, int base = 10); -std::wstring Toa(int value, int base = 10); -std::wstring Toa(unsigned short value, int base = 10); -std::wstring Toa(short value, int base = 10); +std::string to_str(unsigned long long value, int base = 10); +std::string to_str(long long value, int base = 10); +std::string to_str(unsigned long value, int base = 10); +std::string to_str(long value, int base = 10); +std::string to_str(unsigned int value, int base = 10); +std::string to_str(int value, int base = 10); +std::string to_str(unsigned short value, int base = 10); +std::string to_str(short value, int base = 10); + +std::wstring to_wstr(unsigned long long value, int base = 10); +std::wstring to_wstr(long long value, int base = 10); +std::wstring to_wstr(unsigned long value, int base = 10); +std::wstring to_wstr(long value, int base = 10); +std::wstring to_wstr(unsigned int value, int base = 10); +std::wstring to_wstr(int value, int base = 10); +std::wstring to_wstr(unsigned short value, int base = 10); +std::wstring to_wstr(short value, int base = 10); From df88d4c0fca312c0a576bd89b20351049cfb2e29 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 15 Mar 2021 19:25:04 +0100 Subject: [PATCH 02/67] temporarily blocked for compilation: mainspaceparser, jsontospaceparser, spaceparser, spacetojson --- mainspaceparser/mainspaceparser.cpp | 3 +++ mainspaceparser/mainspaceparser.h | 3 +++ space/jsontospaceparser.cpp | 3 ++- space/jsontospaceparser.h | 3 +++ space/spaceparser.cpp | 3 +++ space/spaceparser.h | 3 +++ space/spacetojson.cpp | 4 +++- space/spacetojson.h | 4 +++- 8 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mainspaceparser/mainspaceparser.cpp b/mainspaceparser/mainspaceparser.cpp index 59bae06..e86d491 100644 --- a/mainspaceparser/mainspaceparser.cpp +++ b/mainspaceparser/mainspaceparser.cpp @@ -47,6 +47,8 @@ namespace PT { +#ifdef nonexisting_value + MainSpaceParser::MainSpaceParser() { @@ -290,6 +292,7 @@ size_t MainSpaceParser::RequireOption(const std::wstring & arg) return res; } +#endif } // namespace diff --git a/mainspaceparser/mainspaceparser.h b/mainspaceparser/mainspaceparser.h index 6148179..bddc4bf 100644 --- a/mainspaceparser/mainspaceparser.h +++ b/mainspaceparser/mainspaceparser.h @@ -46,6 +46,8 @@ namespace PT { +#ifdef nonexisting_value + /* a very little parser for main(int argc, char ** argv) parameters @@ -93,6 +95,7 @@ private: }; +#endif } // namespace diff --git a/space/jsontospaceparser.cpp b/space/jsontospaceparser.cpp index 0799054..a69f820 100644 --- a/space/jsontospaceparser.cpp +++ b/space/jsontospaceparser.cpp @@ -44,6 +44,7 @@ namespace PT { +#ifdef nonexisting_value JSONToSpaceParser::JSONToSpaceParser() @@ -861,7 +862,7 @@ int JSONToSpaceParser::ReadChar() return lastc; } - +#endif } // namespace diff --git a/space/jsontospaceparser.h b/space/jsontospaceparser.h index 385aced..6691fbc 100644 --- a/space/jsontospaceparser.h +++ b/space/jsontospaceparser.h @@ -46,6 +46,7 @@ namespace PT { +#ifdef nonexisting_value class JSONToSpaceParser @@ -353,6 +354,8 @@ private: }; +#endif + } // namespace diff --git a/space/spaceparser.cpp b/space/spaceparser.cpp index 8415f88..392c9ce 100644 --- a/space/spaceparser.cpp +++ b/space/spaceparser.cpp @@ -44,6 +44,7 @@ namespace PT { +#ifdef nonexisting_value SpaceParser::SpaceParser() @@ -667,6 +668,8 @@ return lastc; } +#endif + } // namespace diff --git a/space/spaceparser.h b/space/spaceparser.h index 2cff901..bba03e6 100644 --- a/space/spaceparser.h +++ b/space/spaceparser.h @@ -46,6 +46,7 @@ namespace PT { +#ifdef nonexisting_value class SpaceParser @@ -318,6 +319,8 @@ private: }; +#endif + } // namespace diff --git a/space/spacetojson.cpp b/space/spacetojson.cpp index b8b46ae..64d09f8 100644 --- a/space/spacetojson.cpp +++ b/space/spacetojson.cpp @@ -41,6 +41,8 @@ namespace PT { +#ifdef nonexisting_value + void SpaceToJSON::Clear() { @@ -107,7 +109,7 @@ bool SpaceToJSON::IsTable(const std::wstring & name) return i != table.end(); } - +#endif diff --git a/space/spacetojson.h b/space/spacetojson.h index f18ac3f..6338e06 100644 --- a/space/spacetojson.h +++ b/space/spacetojson.h @@ -48,6 +48,8 @@ namespace PT { +#ifdef nonexisting_value + class SpaceToJSON { @@ -262,7 +264,7 @@ void SpaceToJSON::Serialize(Space & space, Stream & out, bool use_indents) Serialize(space, out, use_indents, 0, false, treat_as_table, true); } - +#endif } // namespace From effe9be0a30f71909226528b762123c3ac3088e2 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 15 Mar 2021 19:27:03 +0100 Subject: [PATCH 03/67] added: typedef with char_type to TextStreamBase --- textstream/textstream.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/textstream/textstream.h b/textstream/textstream.h index 523f638..35f02cf 100644 --- a/textstream/textstream.h +++ b/textstream/textstream.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2012-2013, Tomasz Sowa + * Copyright (c) 2012-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,17 +60,20 @@ namespace PT StringType can be either std::string or std::wstring this class doesn't use UTF-8 in any kind */ -template +template class TextStreamBase { public: TextStreamBase(); + typedef CharT char_type; + typedef MemBuffer buffer_type; typedef typename buffer_type::iterator iterator; typedef typename buffer_type::const_iterator const_iterator; + void clear(); bool empty() const; size_t size() const; From fac3a7eb7189e40e396649b73a075baa43ec1f07 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 15 Mar 2021 19:34:51 +0100 Subject: [PATCH 04/67] reorganization in utf8 - utf8 auxiliary functions moved to utf8_private.h file - in utf8.h are shown only functions available for consumers - template functions has been moved to utf8_template.h (in utf8.h are only declarations) utf8_template.h is included at the end of utf8.h - functions which take std::ostream changed to template (the stream is a template argument now) --- utf8/utf8.cpp | 406 ++---------------------------------------- utf8/utf8.h | 268 ++++++---------------------- utf8/utf8_private.cpp | 286 +++++++++++++++++++++++++++++ utf8/utf8_private.h | 220 +++++++++++++++++++++++ utf8/utf8_templates.h | 271 ++++++++++++++++++++++++++++ 5 files changed, 845 insertions(+), 606 deletions(-) create mode 100644 utf8/utf8_private.cpp create mode 100644 utf8/utf8_private.h create mode 100644 utf8/utf8_templates.h diff --git a/utf8/utf8.cpp b/utf8/utf8.cpp index cfb20e5..b804e1f 100644 --- a/utf8/utf8.cpp +++ b/utf8/utf8.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2010-2018, Tomasz Sowa + * Copyright (c) 2010-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ */ #include "utf8.h" +#include "utf8_private.h" @@ -44,48 +45,6 @@ namespace PT -/*! - an auxiliary function for converting from UTF-8 string -*/ -static bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res) -{ - for(len=0 ; (uz & 0x80) != 0 ; ++len) - uz <<= 1; - - if( len == 1 ) - return false; - - res = uz; - - if( len > 0 ) - res >>= len; - - if( res == 0 ) - return false; - - if( len == 0 ) - len = 1; - -return true; -} - - - -/*! - an auxiliary function for converting from UTF-8 string -*/ -static bool UTF8ToInt_AddNextOctet(unsigned char uz, int & res) -{ - if( (uz & 0xc0) != 0x80 ) - return false; - - res <<= 6; - res |= (uz & 0x3F); - -return true; -} - - /*! @@ -126,15 +85,17 @@ size_t i, len; if( utf8_len == 0 ) return 0; - if( !UTF8ToInt_FirstOctet(utf8[0], len, res) ) + if( !private_namespace::UTF8ToInt_FirstOctet(utf8[0], len, res) ) return 1; if( utf8_len < len ) return utf8_len; for(i=1 ; i(*wide_string); - correct = true; - - if( sizeof(wchar_t) == 2 && (z>=0xD800 && z<=0xDFFF) ) - { - if( z>=0xD800 && z<=0xDBFF && string_len>1 ) - { - int z2 = *(wide_string+1); - - if( z2>=0xDC00 && z2<=0xDFFF ) - { - z = 0x10000 + (((z & 0x3FF) << 10) | (z2 & 0x3FF)); - return 2; - } - else - { - correct = false; - return 2; - } - } - else - { - correct = false; - return 1; - } - } - else - { - correct = UTF8_CheckRange(z); - return 1; - } -} - - - -/* - an auxiliary function for converting from wide characters to UTF-8 - converting a wide character into one int - - returns how many wide characters were used - if wide_string has at least one character then the return value is always greater than zero too -*/ -static size_t WideToInt(const wchar_t * wide_string, int & z, bool & correct) -{ -size_t min_str_len = 1; - - if( *wide_string == 0 ) - { - z = 0; - correct = false; - return 0; - } - - if( *(wide_string+1) != 0 ) - min_str_len = 2; - -return WideToInt(wide_string, min_str_len, z, correct); -} - - - -/*! - an auxiliary function for converting from wide characters to UTF-8 - - returns how many wide characters were used - if string_len is greater than 0 then the return value is always greater than zero too - - utf8_written - how many characters were saved in the utf8 string (the string doesn't have - a null terminating character) - it can be equal to zero if the utf8 buffer is too small or there was an incorrect wide character read - was_utf8_buf_too_small - will be true if the utf8 buffer is too small - if this flag is true then utf8_written is equal to zero - was_error - will be true if there is an error when converting (there was an incorrect wide character) - (was_error will not be true if the utf8 buffer is too small) -*/ -static size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, - size_t & utf8_written, bool & was_utf8_buf_too_small, bool & was_error, int mode) -{ -int z; -bool correct; -size_t chars; - - utf8_written = 0; - was_utf8_buf_too_small = false; - chars = WideToInt(wide_string, string_len, z, correct); - - if( correct ) - { - utf8_written = IntToUTF8(z, utf8, utf8_len); - - if( utf8_written == 0 ) - was_utf8_buf_too_small = true; - } - else - { - if( mode == 1 ) - { - utf8_written = IntToUTF8(0xFFFD, utf8, utf8_len); // U+FFFD "replacement character" - - if( utf8_written == 0 ) - was_utf8_buf_too_small = true; - } - - was_error = true; - } - -return chars; -} - - - -/*! - an auxiliary function for converting from wide characters to UTF-8 - - returns how many wide characters were used - if string_len is greater than 0 then the return value is always greater than zero too -*/ -static size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode) -{ -int z; -bool correct; -size_t chars; - - chars = WideToInt(wide_string, string_len, z, correct); - - if( correct ) - correct = IntToUTF8(z, utf8, false) != 0; - - if( !correct ) - { - if( mode == 1 ) - IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character" - - was_error = true; - } - -return chars; -} - - - -/*! - an auxiliary function for converting from wide characters to UTF-8 - - returns how many wide characters were used - if wide_string has at least one character then the return value is always greater than zero too -*/ -static size_t WideOneToUTF8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode) -{ -int z; -bool correct; -size_t chars; - - chars = WideToInt(wide_string, z, correct); - - if( correct ) - correct = IntToUTF8(z, utf8, false) != 0; - - if( !correct ) - { - if( mode == 1 ) - IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character" - - was_error = true; - } - -return chars; -} - - - -/*! - an auxiliary function for converting from wide characters to UTF-8 - - returns how many wide characters were used - if string_len is greater than 0 then the return value is always greater than zero too -*/ -static size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::ostream & utf8, bool & was_error, int mode) -{ -int z; -bool correct; -size_t chars; - - chars = WideToInt(wide_string, string_len, z, correct); - - if( correct ) - correct = IntToUTF8(z, utf8) != 0; - - if( !correct ) - { - if( mode == 1 ) - IntToUTF8(0xFFFD, utf8); // U+FFFD "replacement character" - - was_error = true; - } - -return chars; -} - - - -/*! - an auxiliary function for converting from wide characters to UTF-8 -*/ -static size_t WideOneToUTF8(const wchar_t * wide_string, std::ostream & utf8, bool & was_error, int mode) -{ -size_t min_str_len = 1; - - if( *wide_string == 0 ) - return 0; - - if( *(wide_string+1) != 0 ) - min_str_len = 2; - -return WideOneToUTF8(wide_string, min_str_len, utf8, was_error, mode); -} - - - /*! this function converts a wide string into UTF-8 string @@ -772,7 +471,7 @@ size_t chars; while( string_len > 0 ) { - chars = WideOneToUTF8(wide_string, string_len, utf8, was_error, mode); + chars = private_namespace::WideOneToUTF8(wide_string, string_len, utf8, was_error, mode); wide_string += chars; string_len -= chars; } @@ -804,7 +503,7 @@ bool was_error = false; utf8.clear(); while( *wide_string ) - wide_string += WideOneToUTF8(wide_string, utf8, was_error, mode); + wide_string += private_namespace::WideOneToUTF8(wide_string, utf8, was_error, mode); return !was_error; } @@ -832,83 +531,6 @@ bool WideToUTF8(const std::wstring & wide_string, std::string & utf8, bool clear -/*! - this function converts a wide string into UTF-8 stream - - input: - wide_string - a wide string for converting - string_len - size of the string - mode - what to do with errors when converting - 0: skip an invalid character - 1: put U+FFFD "replacement character" istead of the invalid character (default) - - output: - utf8 - a UTF-8 stream for the output sequence - - this function returns false if there were some errors when converting -*/ -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::ostream & utf8, int mode) -{ -bool was_error = false; -size_t chars; - - while( string_len > 0 ) - { - chars = WideOneToUTF8(wide_string, string_len, utf8, was_error, mode); - wide_string += chars; - string_len -= chars; - } - -return !was_error; -} - - - -/*! - this function converts a wide string into UTF-8 stream - - input: - wide_string - a null terminated wide string for converting - mode - what to do with errors when converting - 0: skip an invalid character - 1: put U+FFFD "replacement character" istead of the invalid character (default) - - output: - utf8 - a UTF-8 stream for the output sequence - - this function returns false if there were some errors when converting -*/ -bool WideToUTF8(const wchar_t * wide_string, std::ostream & utf8, int mode) -{ -bool was_error = false; - - while( *wide_string ) - wide_string += WideOneToUTF8(wide_string, utf8, was_error, mode); - -return !was_error; -} - - - -/*! - this function converts a wide string (std::wstring) into UTF-8 stream - - input: - wide_string - a wide string for converting - mode - what to do with errors when converting - 0: skip an invalid character - 1: put U+FFFD "replacement character" istead of the invalid character (default) - - output: - utf8 - a UTF-8 stream for the output sequence - - this function returns false if there were some errors when converting -*/ -bool WideToUTF8(const std::wstring & wide_string, std::ostream & utf8, int mode) -{ - return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, mode); -} - /*! @@ -942,7 +564,7 @@ size_t chars, utf8_saved; while( string_len > 0 ) { - chars = WideOneToUTF8(wide_string, string_len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); + chars = private_namespace::WideOneToUTF8(wide_string, string_len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); if( was_buffer_to_small ) { @@ -1089,7 +711,7 @@ size_t len; while( *wide_string ) { len = (*(wide_string+1) == 0) ? 1 : 2; - chars = WideOneToUTF8(wide_string, len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); + chars = private_namespace::WideOneToUTF8(wide_string, len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); if( was_buffer_to_small ) { diff --git a/utf8/utf8.h b/utf8/utf8.h index c33a68d..2cd5b72 100644 --- a/utf8/utf8.h +++ b/utf8/utf8.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2010-2018, Tomasz Sowa + * Copyright (c) 2010-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,7 +38,6 @@ #ifndef headerfile_picotools_utf8_utf8 #define headerfile_picotools_utf8_utf8 -#include #include #include "textstream/textstream.h" @@ -46,8 +45,6 @@ namespace PT { - - /*! UTF-8, a transformation format of ISO 10646 http://tools.ietf.org/html/rfc3629 @@ -68,6 +65,16 @@ bool UTF8_CheckRange(int c); +/* + * + * + * + * convertions from UTF-8 + * + * + * + */ + /*! converting one character from UTF-8 to an int */ @@ -85,25 +92,40 @@ bool UTF8ToWide(const char * utf8, std::wstring & res, bool cle bool UTF8ToWide(const std::string & utf8, std::wstring & res, bool clear = true, int mode = 1); bool UTF8ToWide(std::istream & utf8, std::wstring & res, bool clear = true, int mode = 1); +template +bool UTF8ToWide(const char * utf8, size_t utf8_len, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested + +template +bool UTF8ToWide(const char * utf8, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested + +template +bool UTF8ToWide(const std::string & utf8, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested + +template +bool UTF8ToWide(std::istream & utf8, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested + + -/*! - converting UTF-8 string to a WTextStream stream - (need to be tested) -*/ /* - implemented as templates below -bool UTF8ToWide(const char * utf8, size_t utf8_len, WTextStream & res, bool clear = true, int mode = 1); -bool UTF8ToWide(const char * utf8, WTextStream & res, bool clear = true, int mode = 1); -bool UTF8ToWide(const std::string & utf8, WTextStream & res, bool clear = true, int mode = 1); -bool UTF8ToWide(std::istream & utf8, WTextStream & res, bool clear = true, int mode = 1); -*/ + * + * + * + * convertions to UTF-8 + * + * + * + */ + /*! converting one int character to UTF-8 */ size_t IntToUTF8(int z, char * utf8, size_t utf8_max_len); -size_t IntToUTF8(int z, std::string & utf8, bool clear = true ); -size_t IntToUTF8(int z, std::ostream & utf8); +size_t IntToUTF8(int z, std::string & utf8, bool clear = true); + +template +size_t IntToUTF8(int z, StreamType & utf8); + /*! @@ -113,216 +135,32 @@ bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::string & ut bool WideToUTF8(const wchar_t * wide_string, std::string & utf8, bool clear = true, int mode = 1); bool WideToUTF8(const std::wstring & wide_string, std::string & utf8, bool clear = true, int mode = 1); -// implemented as a template below -//void WideToUTF8(PT::WTextStream & buffer, std::string & utf8, bool clear = true, int mode = 1);// not tested +template +bool WideToUTF8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, int mode = 1); + +template +bool WideToUTF8(const wchar_t * wide_string, StreamType & utf8, int mode = 1); + +template +bool WideToUTF8(const std::wstring & wide_string, StreamType & utf8, int mode = 1); -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::ostream & utf8, int mode = 1); -bool WideToUTF8(const wchar_t * wide_string, std::ostream & utf8, int mode = 1); -bool WideToUTF8(const std::wstring & wide_string, std::ostream & utf8, int mode = 1); -// implemented as a template below -//void WideToUTF8(PT::WTextStream & buffer, std::ostream & utf8, int mode = 1);// not tested bool WideToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); bool WideToUTF8(const wchar_t * wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); -// implement void WideToUTF8(PT::WTextStream & buffer, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); +// implement template bool WideToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, int mode = 1); bool WideToUTF8(const wchar_t * wide_string, char * utf8, size_t utf8_len, int mode = 1); bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, int mode = 1); -// implement void WideToUTF8(PT::WTextStream & buffer, char * utf8, size_t utf8_len, int mode = 1); - - - -namespace private_namespace -{ -template -bool UTF8ToWideGeneric(const char * utf8, size_t utf8_len, int mode, function_type convert_function) -{ -int z; -size_t len; -bool correct, was_error = false; - - while( utf8_len > 0 ) - { - if( (unsigned char)*utf8 <= 0x7f ) - { - // small optimization - len = 1; - correct = true; - z = static_cast(*utf8); - } - else - { - len = UTF8ToInt(utf8, utf8_len, z, correct); // the len will be different from zero - } - - if( !correct ) - { - if( mode == 1 ) - convert_function(0xFFFD); // U+FFFD "replacement character" - - was_error = true; - } - else - { - convert_function(z); - } - - utf8 += len; - utf8_len -= len; - } - -return !was_error; -} - - - -template -void IntToWide(int c, TextStreamBase & res) -{ - if( sizeof(wchar_t)==2 && c>0xffff ) - { - // UTF16 surrogate pairs - c -= 0x10000; - res << static_cast(((c >> 10) & 0x3FF) + 0xD800); - res << static_cast((c & 0x3FF) + 0xDC00); - } - else - { - res << static_cast(c); - } -} - - -// not tested -// FIX ME it is not using surrogate pairs from input stream -// and mode parameter -template -void WideToUTF8Generic(TextStreamBase & buffer, int mode, function_type write_function) -{ - char utf8_buffer[256]; - std::size_t buffer_len = sizeof(utf8_buffer) / sizeof(char); - std::size_t utf8_sequence_max_length = 10; - std::size_t index = 0; - - typename TextStreamBase::const_iterator i = buffer.begin(); - - while( i != buffer.end() ) - { - if( index + utf8_sequence_max_length > buffer_len ) - { - write_function(utf8_buffer, index); - index = 0; - } - - index += PT::IntToUTF8(*i, utf8_buffer + index, buffer_len - index); - ++i; - } - - if( index > 0 ) - { - write_function(utf8_buffer, index); - } -} - - -} // namespace - - - - -// need to be tested -template -bool UTF8ToWide(const char * utf8, size_t utf8_len, TextStreamBase & res, bool clear = true, int mode = 1) -{ - if( clear ) - res.clear(); - - bool status = private_namespace::UTF8ToWideGeneric(utf8, utf8_len, mode, [&res](int c) { - private_namespace::IntToWide(c, res); - }); - - return status; -} - - -// need to be tested -template -bool UTF8ToWide(const char * utf8, TextStreamBase & res, bool clear = true, int mode = 1) -{ -size_t utf8_len = 0; - - while( utf8[utf8_len] != 0 ) - utf8_len += 1; - -return UTF8ToWide(utf8, utf8_len, res, clear, mode); -} - - -// need to be tested -template -bool UTF8ToWide(const std::string & utf8, TextStreamBase & res, bool clear = true, int mode = 1) -{ - return UTF8ToWide(utf8.c_str(), utf8.size(), res, clear, mode); -} - - -// need to be tested -template -bool UTF8ToWide(std::istream & utf8, TextStreamBase & res, bool clear = true, int mode = 1) -{ -int z; -bool correct, was_error = false; - - if( clear ) - res.clear(); - - while( UTF8ToInt(utf8, z, correct) > 0 ) - { - if( !correct ) - { - if( mode == 1 ) - res << 0xFFFD; // U+FFFD "replacement character" - - was_error = true; - } - else - { - private_namespace::IntToWide(z, res); - } - } - -return !was_error; -} - - - - -// not tested -template -void WideToUTF8(TextStreamBase & buffer, std::string & utf8, bool clear = true, int mode = 1) -{ - if( clear ) - utf8.clear(); - - private_namespace::WideToUTF8Generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ - utf8.append(utf8_buffer, buffer_len); - }); -} - - -// not tested -template -void WideToUTF8(TextStreamBase & buffer, std::ostream & utf8, int mode = 1) -{ - private_namespace::WideToUTF8Generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ - utf8.write(utf8_buffer, buffer_len); - }); -} +// implement template +template +void WideToUTF8(TextStreamBase & buffer, std::string & utf8, bool clear = true, int mode = 1); // not tested +template +void WideToUTF8(TextStreamBase & buffer, std::ostream & utf8, int mode = 1); // not tested @@ -330,5 +168,7 @@ void WideToUTF8(TextStreamBase & buffer, } // namespace +#include "utf8/utf8_templates.h" + #endif diff --git a/utf8/utf8_private.cpp b/utf8/utf8_private.cpp new file mode 100644 index 0000000..cba2dfe --- /dev/null +++ b/utf8/utf8_private.cpp @@ -0,0 +1,286 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "utf8_private.h" + + +namespace PT +{ + +namespace private_namespace +{ + +/*! + an auxiliary function for converting from UTF-8 string +*/ +bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res) +{ + for(len=0 ; (uz & 0x80) != 0 ; ++len) + uz <<= 1; + + if( len == 1 ) + return false; + + res = uz; + + if( len > 0 ) + res >>= len; + + if( res == 0 ) + return false; + + if( len == 0 ) + len = 1; + +return true; +} + + + +/*! + an auxiliary function for converting from UTF-8 string +*/ +bool UTF8ToInt_AddNextOctet(unsigned char uz, int & res) +{ + if( (uz & 0xc0) != 0x80 ) + return false; + + res <<= 6; + res |= (uz & 0x3F); + +return true; +} + + + + + +/* + an auxiliary function for converting from wide characters to UTF-8 + converting a wide character into one int + + returns how many wide characters were used + if string_len is greater than 0 then the return value is always greater than zero too +*/ +size_t WideToInt(const wchar_t * wide_string, size_t string_len, int & z, bool & correct) +{ + if( string_len == 0 ) + { + z = 0; + correct = false; + return 0; + } + + z = static_cast(*wide_string); + correct = true; + + if( sizeof(wchar_t) == 2 && (z>=0xD800 && z<=0xDFFF) ) + { + if( z>=0xD800 && z<=0xDBFF && string_len>1 ) + { + int z2 = *(wide_string+1); + + if( z2>=0xDC00 && z2<=0xDFFF ) + { + z = 0x10000 + (((z & 0x3FF) << 10) | (z2 & 0x3FF)); + return 2; + } + else + { + correct = false; + return 2; + } + } + else + { + correct = false; + return 1; + } + } + else + { + correct = UTF8_CheckRange(z); + return 1; + } +} + + + +/* + an auxiliary function for converting from wide characters to UTF-8 + converting a wide character into one int + + returns how many wide characters were used + if wide_string has at least one character then the return value is always greater than zero too +*/ +size_t WideToInt(const wchar_t * wide_string, int & z, bool & correct) +{ +size_t min_str_len = 1; + + if( *wide_string == 0 ) + { + z = 0; + correct = false; + return 0; + } + + if( *(wide_string+1) != 0 ) + min_str_len = 2; + +return WideToInt(wide_string, min_str_len, z, correct); +} + + + +/*! + an auxiliary function for converting from wide characters to UTF-8 + + returns how many wide characters were used + if string_len is greater than 0 then the return value is always greater than zero too + + utf8_written - how many characters were saved in the utf8 string (the string doesn't have + a null terminating character) + it can be equal to zero if the utf8 buffer is too small or there was an incorrect wide character read + was_utf8_buf_too_small - will be true if the utf8 buffer is too small + if this flag is true then utf8_written is equal to zero + was_error - will be true if there is an error when converting (there was an incorrect wide character) + (was_error will not be true if the utf8 buffer is too small) +*/ +size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, + size_t & utf8_written, bool & was_utf8_buf_too_small, bool & was_error, int mode) +{ +int z; +bool correct; +size_t chars; + + utf8_written = 0; + was_utf8_buf_too_small = false; + chars = WideToInt(wide_string, string_len, z, correct); + + if( correct ) + { + utf8_written = IntToUTF8(z, utf8, utf8_len); + + if( utf8_written == 0 ) + was_utf8_buf_too_small = true; + } + else + { + if( mode == 1 ) + { + utf8_written = IntToUTF8(0xFFFD, utf8, utf8_len); // U+FFFD "replacement character" + + if( utf8_written == 0 ) + was_utf8_buf_too_small = true; + } + + was_error = true; + } + +return chars; +} + + + +/*! + an auxiliary function for converting from wide characters to UTF-8 + + returns how many wide characters were used + if string_len is greater than 0 then the return value is always greater than zero too +*/ +size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode) +{ +int z; +bool correct; +size_t chars; + + chars = WideToInt(wide_string, string_len, z, correct); + + if( correct ) + correct = IntToUTF8(z, utf8, false) != 0; + + if( !correct ) + { + if( mode == 1 ) + IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character" + + was_error = true; + } + +return chars; +} + + + +/*! + an auxiliary function for converting from wide characters to UTF-8 + + returns how many wide characters were used + if wide_string has at least one character then the return value is always greater than zero too +*/ +size_t WideOneToUTF8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode) +{ +int z; +bool correct; +size_t chars; + + chars = WideToInt(wide_string, z, correct); + + if( correct ) + correct = IntToUTF8(z, utf8, false) != 0; + + if( !correct ) + { + if( mode == 1 ) + IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character" + + was_error = true; + } + +return chars; +} + + + + + +} // namespace private_namespace + +} // namespace PT + + + diff --git a/utf8/utf8_private.h b/utf8/utf8_private.h new file mode 100644 index 0000000..d28e525 --- /dev/null +++ b/utf8/utf8_private.h @@ -0,0 +1,220 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_utf8_utf8_private +#define headerfile_picotools_utf8_utf8_private + +#include "textstream/textstream.h" + + +namespace PT +{ + +bool UTF8_CheckRange(int c); +size_t IntToUTF8(int z, char * utf8, size_t utf8_max_len); +size_t IntToUTF8(int z, std::string & utf8, bool clear); +size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct); + + +namespace private_namespace +{ +bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res); +bool UTF8ToInt_AddNextOctet(unsigned char uz, int & res); + +size_t WideToInt(const wchar_t * wide_string, size_t string_len, int & z, bool & correct); +size_t WideToInt(const wchar_t * wide_string, int & z, bool & correct); + +size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, + size_t & utf8_written, bool & was_utf8_buf_too_small, bool & was_error, int mode); + +size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode); + +size_t WideOneToUTF8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode); + + +/*! + an auxiliary function for converting from wide characters to UTF-8 + + returns how many wide characters were used + if string_len is greater than 0 then the return value is always greater than zero too +*/ +template +static size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, bool & was_error, int mode) +{ +int z; +bool correct; +size_t chars; + + chars = WideToInt(wide_string, string_len, z, correct); + + if( correct ) + correct = IntToUTF8(z, utf8) != 0; + + if( !correct ) + { + if( mode == 1 ) + IntToUTF8(0xFFFD, utf8); // U+FFFD "replacement character" + + was_error = true; + } + +return chars; +} + + +/*! + an auxiliary function for converting from wide characters to UTF-8 +*/ +template +static size_t WideOneToUTF8(const wchar_t * wide_string, StreamType & utf8, bool & was_error, int mode) +{ + size_t min_str_len = 1; + + if( *wide_string == 0 ) + return 0; + + if( *(wide_string+1) != 0 ) + min_str_len = 2; + +return WideOneToUTF8(wide_string, min_str_len, utf8, was_error, mode); +} + + + +// declared in utf8.h, defined in utf8.cpp +size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct); + + + +template +bool UTF8ToWideGeneric(const char * utf8, size_t utf8_len, int mode, function_type convert_function) +{ +int z; +size_t len; +bool correct, was_error = false; + + while( utf8_len > 0 ) + { + if( (unsigned char)*utf8 <= 0x7f ) + { + // small optimization + len = 1; + correct = true; + z = static_cast(*utf8); + } + else + { + len = PT::UTF8ToInt(utf8, utf8_len, z, correct); // the len will be different from zero + } + + if( !correct ) + { + if( mode == 1 ) + convert_function(0xFFFD); // U+FFFD "replacement character" + + was_error = true; + } + else + { + convert_function(z); + } + + utf8 += len; + utf8_len -= len; + } + +return !was_error; +} + + + +template +void IntToWide(int c, TextStreamBase & res) +{ + if( sizeof(wchar_t)==2 && c>0xffff ) + { + // UTF16 surrogate pairs + c -= 0x10000; + res << static_cast(((c >> 10) & 0x3FF) + 0xD800); + res << static_cast((c & 0x3FF) + 0xDC00); + } + else + { + res << static_cast(c); + } +} + + +// not tested +// FIX ME it is not using surrogate pairs from input stream +// and mode parameter +template +void WideToUTF8Generic(TextStreamBase & buffer, int mode, function_type write_function) +{ + char utf8_buffer[256]; + std::size_t buffer_len = sizeof(utf8_buffer) / sizeof(char); + std::size_t utf8_sequence_max_length = 10; + std::size_t index = 0; + + typename TextStreamBase::const_iterator i = buffer.begin(); + + while( i != buffer.end() ) + { + if( index + utf8_sequence_max_length > buffer_len ) + { + write_function(utf8_buffer, index); + index = 0; + } + + index += IntToUTF8(*i, utf8_buffer + index, buffer_len - index); + ++i; + } + + if( index > 0 ) + { + write_function(utf8_buffer, index); + } +} + + + + +} // namespace private_namespace + +} // namespace PT + +#endif diff --git a/utf8/utf8_templates.h b/utf8/utf8_templates.h new file mode 100644 index 0000000..bbf9ceb --- /dev/null +++ b/utf8/utf8_templates.h @@ -0,0 +1,271 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_utf8_utf8_templates +#define headerfile_picotools_utf8_utf8_templates + +// this file is included at the end of utf8.h + +#include "utf8_private.h" + + +namespace PT +{ + + +/*! + converting UTF-8 string to a TextStreamBase stream + (need to be tested) +*/ +// need to be tested +template +bool UTF8ToWide(const char * utf8, size_t utf8_len, TextStreamBase & res, bool clear, int mode) +{ + if( clear ) + res.clear(); + + bool status = private_namespace::UTF8ToWideGeneric(utf8, utf8_len, mode, [&res](int c) { + private_namespace::IntToWide(c, res); + }); + + return status; +} + + + + +template +bool UTF8ToWide(const char * utf8, TextStreamBase & res, bool clear, int mode) +{ +size_t utf8_len = 0; + + while( utf8[utf8_len] != 0 ) + utf8_len += 1; + +return UTF8ToWide(utf8, utf8_len, res, clear, mode); +} + + + +template +bool UTF8ToWide(const std::string & utf8, TextStreamBase & res, bool clear, int mode) +{ + return UTF8ToWide(utf8.c_str(), utf8.size(), res, clear, mode); +} + + + +// need to be tested +template +bool UTF8ToWide(std::istream & utf8, TextStreamBase & res, bool clear, int mode) +{ +int z; +bool correct, was_error = false; + + if( clear ) + res.clear(); + + while( UTF8ToInt(utf8, z, correct) > 0 ) + { + if( !correct ) + { + if( mode == 1 ) + res << 0xFFFD; // U+FFFD "replacement character" + + was_error = true; + } + else + { + private_namespace::IntToWide(z, res); + } + } + +return !was_error; +} + + + + + + + + +/*! + this function converts one wide character into UTF-8 stream + + input: + z - wide character + + output: + utf8 - a UTF-8 stream for the output sequence + + the function returns how many characters have been written to the utf8 stream, + zero means that 'z' is an incorrect unicode character +*/ +template +size_t IntToUTF8(int z, StreamType & utf8) +{ + char buf[10]; + + size_t len = IntToUTF8(z, buf, sizeof(buf)/sizeof(char)); + + if( len > 0 ) + utf8.write(buf, len); + + return len; +} + + + + + +/*! + this function converts a wide string into UTF-8 stream + + input: + wide_string - a wide string for converting + string_len - size of the string + mode - what to do with errors when converting + 0: skip an invalid character + 1: put U+FFFD "replacement character" istead of the invalid character (default) + + output: + utf8 - a UTF-8 stream for the output sequence + + this function returns false if there were some errors when converting +*/ +template +bool WideToUTF8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, int mode) +{ +bool was_error = false; +size_t chars; + + while( string_len > 0 ) + { + chars = private_namespace::WideOneToUTF8(wide_string, string_len, utf8, was_error, mode); + wide_string += chars; + string_len -= chars; + } + +return !was_error; +} + + + + + +/*! + this function converts a wide string into UTF-8 stream + + input: + wide_string - a null terminated wide string for converting + mode - what to do with errors when converting + 0: skip an invalid character + 1: put U+FFFD "replacement character" istead of the invalid character (default) + + output: + utf8 - a UTF-8 stream for the output sequence + + this function returns false if there were some errors when converting +*/ +template +bool WideToUTF8(const wchar_t * wide_string, StreamType & utf8, int mode) +{ +bool was_error = false; + + while( *wide_string ) + wide_string += private_namespace::WideOneToUTF8(wide_string, utf8, was_error, mode); + +return !was_error; +} + + + +/*! + this function converts a wide string (std::wstring) into UTF-8 stream + + input: + wide_string - a wide string for converting + mode - what to do with errors when converting + 0: skip an invalid character + 1: put U+FFFD "replacement character" istead of the invalid character (default) + + output: + utf8 - a UTF-8 stream for the output sequence + + this function returns false if there were some errors when converting +*/ +template +bool WideToUTF8(const std::wstring & wide_string, StreamType & utf8, int mode) +{ + return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, mode); +} + + + + +template +void WideToUTF8(TextStreamBase & buffer, std::string & utf8, bool clear, int mode) +{ + if( clear ) + utf8.clear(); + + private_namespace::WideToUTF8Generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ + utf8.append(utf8_buffer, buffer_len); + }); +} + + +// not tested +template +void WideToUTF8(TextStreamBase & buffer, std::ostream & utf8, int mode) +{ + private_namespace::WideToUTF8Generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ + utf8.write(utf8_buffer, buffer_len); + }); +} + + + + + +} // namespace PT + +#endif + + + From 7ccd435e2c2848eed1909b27407879a330129b9d Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 15 Mar 2021 19:36:04 +0100 Subject: [PATCH 05/67] make depend --- log/Makefile.dep | 7 ++++--- mainspaceparser/Makefile.dep | 7 ++++--- space/Makefile.dep | 30 +++++++++++++++++++----------- space/Makefile.o.dep | 2 +- utf8/Makefile.dep | 6 +++++- utf8/Makefile.o.dep | 2 +- 6 files changed, 34 insertions(+), 20 deletions(-) diff --git a/log/Makefile.dep b/log/Makefile.dep index 1a14a56..a409558 100644 --- a/log/Makefile.dep +++ b/log/Makefile.dep @@ -1,9 +1,10 @@ # DO NOT DELETE filelog.o: filelog.h ../textstream/textstream.h ../space/space.h -filelog.o: ../textstream/types.h ../date/date.h ../convert/inttostr.h +filelog.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h filelog.o: ../membuffer/membuffer.h ../textstream/types.h ../utf8/utf8.h +filelog.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h log.o: log.h ../textstream/textstream.h ../space/space.h -log.o: ../textstream/types.h ../date/date.h ../convert/inttostr.h +log.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h log.o: ../membuffer/membuffer.h ../textstream/types.h filelog.h -log.o: ../utf8/utf8.h +log.o: ../utf8/utf8.h ../utf8/utf8_templates.h ../utf8/utf8_private.h diff --git a/mainspaceparser/Makefile.dep b/mainspaceparser/Makefile.dep index ed0b0f8..733d32a 100644 --- a/mainspaceparser/Makefile.dep +++ b/mainspaceparser/Makefile.dep @@ -1,6 +1,7 @@ # DO NOT DELETE mainspaceparser.o: mainspaceparser.h ../space/space.h ../textstream/types.h -mainspaceparser.o: ../utf8/utf8.h ../textstream/textstream.h ../date/date.h -mainspaceparser.o: ../convert/inttostr.h ../membuffer/membuffer.h -mainspaceparser.o: ../textstream/types.h +mainspaceparser.o: ../convert/inttostr.h ../utf8/utf8.h +mainspaceparser.o: ../textstream/textstream.h ../date/date.h +mainspaceparser.o: ../membuffer/membuffer.h ../textstream/types.h +mainspaceparser.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h diff --git a/space/Makefile.dep b/space/Makefile.dep index 23c03ed..2bfdb26 100644 --- a/space/Makefile.dep +++ b/space/Makefile.dep @@ -1,17 +1,25 @@ # DO NOT DELETE jsontospaceparser.o: jsontospaceparser.h space.h ../textstream/types.h -jsontospaceparser.o: ../utf8/utf8.h ../textstream/textstream.h -jsontospaceparser.o: ../space/space.h ../date/date.h ../convert/inttostr.h -jsontospaceparser.o: ../membuffer/membuffer.h ../textstream/types.h -space.o: space.h ../textstream/types.h ../utf8/utf8.h +jsontospaceparser.o: ../convert/inttostr.h ../utf8/utf8.h +jsontospaceparser.o: ../textstream/textstream.h ../space/space.h +jsontospaceparser.o: ../date/date.h ../membuffer/membuffer.h +jsontospaceparser.o: ../textstream/types.h ../utf8/utf8_templates.h +jsontospaceparser.o: ../utf8/utf8_private.h +main.o: space.h ../textstream/types.h ../convert/inttostr.h ../utf8/utf8.h +main.o: ../textstream/textstream.h ../space/space.h ../date/date.h +main.o: ../membuffer/membuffer.h ../textstream/types.h +main.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h +space.o: space.h ../textstream/types.h ../convert/inttostr.h ../utf8/utf8.h space.o: ../textstream/textstream.h ../space/space.h ../date/date.h -space.o: ../convert/inttostr.h ../membuffer/membuffer.h ../textstream/types.h -space.o: ../convert/convert.h ../convert/inttostr.h -space.o: ../convert/patternreplacer.h ../convert/strtoint.h ../convert/text.h -space.o: ../convert/misc.h -spaceparser.o: spaceparser.h space.h ../textstream/types.h ../utf8/utf8.h +space.o: ../membuffer/membuffer.h ../textstream/types.h +space.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h ../convert/convert.h +space.o: ../convert/inttostr.h ../convert/patternreplacer.h +space.o: ../convert/strtoint.h ../convert/text.h ../convert/misc.h +spaceparser.o: spaceparser.h space.h ../textstream/types.h +spaceparser.o: ../convert/inttostr.h ../utf8/utf8.h spaceparser.o: ../textstream/textstream.h ../space/space.h ../date/date.h -spaceparser.o: ../convert/inttostr.h ../membuffer/membuffer.h -spaceparser.o: ../textstream/types.h +spaceparser.o: ../membuffer/membuffer.h ../textstream/types.h +spaceparser.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h spacetojson.o: spacetojson.h space.h ../textstream/types.h +spacetojson.o: ../convert/inttostr.h diff --git a/space/Makefile.o.dep b/space/Makefile.o.dep index c773c04..0b7ca32 100644 --- a/space/Makefile.o.dep +++ b/space/Makefile.o.dep @@ -1 +1 @@ -o = jsontospaceparser.o space.o spaceparser.o spacetojson.o \ No newline at end of file +o = jsontospaceparser.o main.o space.o spaceparser.o spacetojson.o \ No newline at end of file diff --git a/utf8/Makefile.dep b/utf8/Makefile.dep index 9d53a86..3808a63 100644 --- a/utf8/Makefile.dep +++ b/utf8/Makefile.dep @@ -1,5 +1,9 @@ # DO NOT DELETE +utf8_private.o: utf8_private.h ../textstream/textstream.h ../space/space.h +utf8_private.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h +utf8_private.o: ../membuffer/membuffer.h ../textstream/types.h utf8.o: utf8.h ../textstream/textstream.h ../space/space.h -utf8.o: ../textstream/types.h ../date/date.h ../convert/inttostr.h +utf8.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h utf8.o: ../membuffer/membuffer.h ../textstream/types.h +utf8.o: ../utf8/utf8_templates.h utf8_private.h diff --git a/utf8/Makefile.o.dep b/utf8/Makefile.o.dep index 25d2b0d..b58ce53 100644 --- a/utf8/Makefile.o.dep +++ b/utf8/Makefile.o.dep @@ -1 +1 @@ -o = utf8.o \ No newline at end of file +o = utf8_private.o utf8.o \ No newline at end of file From f65d934e8cf012769a23e5b6238518acf87e1b20 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 15 Mar 2021 19:36:49 +0100 Subject: [PATCH 06/67] start working on a new version of Space struct - better support for JSON format now we have a correct model, some methods for setting/getting values and serialization to json (no serialization to Space yet) --- space/space.cpp | 1812 ++++++++++++++++++++++++----------------------- space/space.h | 957 +++++++++++++++---------- 2 files changed, 1513 insertions(+), 1256 deletions(-) diff --git a/space/space.cpp b/space/space.cpp index 0798dd5..203eca2 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008-2018, Tomasz Sowa + * Copyright (c) 2008-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,1047 +37,1075 @@ //#include #include +#include #include "space.h" +//#include "textstream/textstream.h" #include "utf8/utf8.h" -#include "textstream/textstream.h" #include "convert/convert.h" namespace PT { - - Space::Space() { - parent = nullptr; + type = type_null; +} + + +Space::Space(const Space & space) +{ + copy_value_from(space); +} + +Space & Space::operator=(const Space & space) +{ + copy_value_from(space); + return *this; } Space::~Space() { - Clear(); + remove_value(); } -Space::Space(const Space & s) + +Space::Space(bool val) { - operator=(s); + set(val); +} + +Space::Space(short val) +{ + set(val); +} + +Space::Space(int val) +{ + set(val); +} + +Space::Space(long val) +{ + set(val); } -Space & Space::operator=(const Space & s) +Space::Space(long long val) { - Clear(); + set(val); +} - name = s.name; - table = s.table; - parent = s.parent; +Space::Space(unsigned short val) +{ + set(val); +} - for(size_t i=0 ; i(val)); +} + +void Space::set(int val) +{ + set(static_cast(val)); +} + +void Space::set(long val) +{ + set(static_cast(val)); +} + +void Space::set(long long val) +{ + initialize_value_long_if_needed(); + value.value_long = val; +} + +void Space::set(unsigned short val) +{ + set(static_cast(val)); +} + +void Space::set(unsigned int val) +{ + set(static_cast(val)); +} + +void Space::set(unsigned long val) +{ + set(static_cast(val)); +} + +void Space::set(unsigned long long val) +{ + set(static_cast(val)); +} + +void Space::set(float val) +{ + initialize_value_float_if_needed(); + value.value_float = val; +} + +void Space::set(double val) +{ + initialize_value_double_if_needed(); + value.value_double = val; +} + + +void Space::set(const char * str) +{ + initialize_value_string_if_needed(); + value.value_string = str; +} + +void Space::set(const wchar_t * str) +{ + initialize_value_wstring_if_needed(); + value.value_wstring = str; +} + +void Space::set(const std::string & str) +{ + initialize_value_string_if_needed(); + value.value_string = str; +} + +void Space::set(const std::wstring & str) +{ + initialize_value_wstring_if_needed(); + value.value_wstring = str; +} + + +void Space::set(const Space * space) +{ + if( space == nullptr ) { - Space * pspace = new Space(*s.spaces[i]); - pspace->parent = this; - spaces.push_back(pspace); - } - -return *this; -} - - - - - - -void Space::Clear() -{ - name.clear(); - table.clear(); - - for(size_t i=0 ; isecond; + copy_value_from(*space); } } -const Space::Value * Space::GetValue(const wchar_t * name) const +Space & Space::add(bool val) { - tmp_name = name; - return GetValue(tmp_name); + return add_generic(val); +} + +Space & Space::add(short val) +{ + return add_generic(val); +} + +Space & Space::add(int val) +{ + return add_generic(val); +} + +Space & Space::add(long val) +{ + return add_generic(val); +} + +Space & Space::add(long long val) +{ + return add_generic(val); +} + +Space & Space::add(unsigned short val) +{ + return add_generic(val); +} + +Space & Space::add(unsigned int val) +{ + return add_generic(val); +} + +Space & Space::add(unsigned long val) +{ + return add_generic(val); +} + +Space & Space::add(unsigned long long val) +{ + return add_generic(val); +} + +Space & Space::add(float val) +{ + return add_generic(val); +} + +Space & Space::add(double val) +{ + return add_generic(val); +} + +Space & Space::add(const char * val) +{ + return add_generic(val); +} + +Space & Space::add(const wchar_t * val) +{ + return add_generic(val); +} + +Space & Space::add(const std::string & val) +{ + return add_generic(val); +} + +Space & Space::add(const std::wstring & val) +{ + return add_generic(val); +} + +Space & Space::add(const Space * space) +{ + return add_generic(space); } -const Space::Value * Space::GetValue(const std::wstring & name) const -{ - Table::const_iterator t = table.find(name); - if( t == table.cend() ) + + +Space & Space::add(const wchar_t * field, bool val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, short val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, int val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, long long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, unsigned short val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, unsigned int val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, unsigned long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, unsigned long long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, float val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, double val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, const char * val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, const wchar_t * val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, const std::string & val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, const std::wstring & val) +{ + return add_generic(field, val); +} + +Space & Space::add(const wchar_t * field, const Space * space) +{ + return add_generic(field, space); +} + +Space & Space::add_empty_space(const wchar_t * field) +{ + return add_generic(field, static_cast(nullptr)); +} + + + +bool Space::is_null() const +{ + return type == type_null; +} + +bool Space::is_bool() const +{ + return type == type_bool; +} + +bool Space::is_llong() const +{ + return is_long_long(); +} + +bool Space::is_long_long() const +{ + return type == type_long; +} + +bool Space::is_float() const +{ + return type == type_float; +} + +bool Space::is_double() const +{ + return type == type_double; +} + +bool Space::is_numeric() const +{ + return is_long_long() || is_float() || is_double(); +} + +bool Space::is_str() const +{ + return type == type_string; +} + +bool Space::is_wstr() const +{ + return type == type_wstring; +} + +bool Space::is_text() const +{ + return is_str() || is_wstr(); +} + +bool Space::is_object() const +{ + return type == type_object; +} + +bool Space::is_table() const +{ + return type == type_table; +} + + +bool Space::to_bool() const +{ + long long val = to_long_long(); + return (val != 0) ? true : false; +} + +short Space::to_short() const +{ + return to_generic_numeric_signed_value(); +} + +int Space::to_int() const +{ + return to_generic_numeric_signed_value(); +} + +long Space::to_long() const +{ + return to_generic_numeric_signed_value(); + +} + +long long Space::to_llong() const +{ + return to_long_long(); +} + +long long Space::to_long_long() const +{ + switch(type) { - return nullptr; + case type_null: + case type_object: + case type_table: + return 0; + + case type_bool: + return value.value_bool ? 1 : 0; + + case type_long: + return value.value_long; + + case type_float: + return static_cast(value.value_float); + + case type_double: + return static_cast(value.value_double); + + case type_string: + return convert_string_to_long_long(); + + case type_wstring: + return convert_wstring_to_long_long(); } - else + + return 0; +} + + +unsigned long long Space::to_ullong() const +{ + return to_ulong_long(); +} + + + +long long Space::convert_string_to_long_long() const +{ + bool was_overflow = false; + const char * after_str; + long long val = Toll(value.value_string.c_str(), 10, &after_str, &was_overflow, true); + + return was_overflow ? 0 : val; +} + + +long long Space::convert_wstring_to_long_long() const +{ + bool was_overflow = false; + const wchar_t * after_str; + long long val = Toll(value.value_wstring.c_str(), 10, &after_str, &was_overflow, true); + + return was_overflow ? 0 : val; +} + + +unsigned long long Space::convert_string_to_ulong_long() const +{ + bool was_overflow = false; + const char * after_str; + unsigned long long val = Toull(value.value_string.c_str(), 10, &after_str, &was_overflow, true); + + return was_overflow ? 0 : val; +} + + +unsigned long long Space::convert_wstring_to_ulong_long() const +{ + bool was_overflow = false; + const wchar_t * after_str; + unsigned long long val = Toull(value.value_wstring.c_str(), 10, &after_str, &was_overflow, true); + + return was_overflow ? 0 : val; +} + + +unsigned short Space::to_ushort() const +{ + return to_generic_numeric_unsigned_value(); +} + +unsigned int Space::to_uint() const +{ + return to_generic_numeric_unsigned_value(); +} + +unsigned long Space::to_ulong() const +{ + return to_generic_numeric_unsigned_value(); + +} + + +unsigned long long Space::to_ulong_long() const +{ + switch(type) { - return &t->second; + case type_null: + case type_object: + case type_table: + return 0; + + case type_bool: + return value.value_bool ? 1 : 0; + + case type_long: + return static_cast(value.value_long); + + case type_float: + return static_cast(value.value_float); + + case type_double: + return static_cast(value.value_double); + + case type_string: + return convert_string_to_ulong_long(); + + case type_wstring: + return convert_wstring_to_ulong_long(); } + + return 0; } - -Space::Value * Space::GetValueNoCase(const wchar_t * name) +std::string Space::to_str() const { - tmp_name = name; - return GetValueNoCase(tmp_name); -} + if( type == type_string ) + return value.value_string; + std::string str; -Space::Value * Space::GetValueNoCase(const std::wstring & name) -{ - Table::iterator t = table.begin(); - - for( ; t != table.end() ; ++t) + if( type == type_wstring ) { - if( PT::EqualNoCase(t->first, name) ) - { - return &t->second; - } + PT::TextStream stream; + serialize_string_buffer(value.value_wstring.c_str(), stream, Escape::no_escape); + stream.to_string(str); + return str; } - return nullptr; + serialize_to_json_to(str); + return str; } - -const Space::Value * Space::GetValueNoCase(const wchar_t * name) const +std::wstring Space::to_wstr() const { - tmp_name = name; - return GetValueNoCase(tmp_name); -} + if( type == type_wstring ) + return value.value_wstring; + std::wstring str; -const Space::Value * Space::GetValueNoCase(const std::wstring & name) const -{ - Table::const_iterator t = table.begin(); - - for( ; t != table.end() ; ++t) + if( type == type_string ) { - if( PT::EqualNoCase(t->first, name) ) - { - return &t->second; - } + PT::WTextStream stream; + serialize_string_buffer(value.value_string.c_str(), stream, Escape::no_escape); + stream.to_string(str); + return str; } - return nullptr; + serialize_to_json_to(str); + return str; +} + + +std::string Space::serialize_to_space_str() const +{ + std::string str; + serialize_to_space_to(str); + return str; +} + + +std::wstring Space::serialize_to_space_wstr() const +{ + std::wstring str; + serialize_to_space_to(str); + return str; +} + + +void Space::serialize_to_space_to(std::string & str) const +{ + PT::TextStream stream; + serialize_to_space_stream(stream); + + stream.to_string(str); +} + + +void Space::serialize_to_space_to(std::wstring & str) const +{ + PT::WTextStream stream; + serialize_to_space_stream(stream); + + stream.to_string(str); } -std::wstring * Space::GetFirstValue(const wchar_t * name) +std::string Space::serialize_to_json_str() const { - tmp_name = name; - return GetFirstValue(tmp_name); + std::string str; + serialize_to_json_to(str); + return str; +} + + +std::wstring Space::serialize_to_json_wstr() const +{ + std::wstring str; + serialize_to_json_to(str); + return str; +} + + +void Space::serialize_to_json_to(std::string & str) const +{ + PT::TextStream stream; + serialize_to_json_stream(stream); + + stream.to_string(str); +} + + +void Space::serialize_to_json_to(std::wstring & str) const +{ + PT::WTextStream stream; + serialize_to_json_stream(stream); + + stream.to_string(str); } -std::wstring * Space::GetFirstValue(const std::wstring & name) +bool * Space::get_bool() { - Table::iterator t = table.find(name); + return type == type_bool ? &value.value_bool : nullptr; +} - if( t == table.end() || t->second.empty() ) +long long * Space::get_llong() +{ + return get_long_long(); +} + +long long * Space::get_long_long() +{ + return type == type_long ? &value.value_long : nullptr; +} + +float * Space::get_float() +{ + return type == type_float ? &value.value_float : nullptr; +} + +double * Space::get_double() +{ + return type == type_double ? &value.value_double : nullptr; +} + +std::string * Space::get_string() +{ + return type == type_string ? &value.value_string : nullptr; +} + +std::wstring * Space::get_wstring() +{ + return type == type_wstring ? &value.value_wstring : nullptr; +} + +Space::ObjectType * Space::get_object() +{ + return type == type_object ? &value.value_object : nullptr; +} + +Space::TableType * Space::get_table() +{ + return type == type_table ? &value.value_table : nullptr; +} + + + + + +const bool * Space::get_bool() const +{ + return type == type_bool ? &value.value_bool : nullptr; +} + +const long long * Space::get_llong() const +{ + return get_long_long(); +} + +const long long * Space::get_long_long() const +{ + return type == type_long ? &value.value_long : nullptr; +} + +const float * Space::get_float() const +{ + return type == type_float ? &value.value_float : nullptr; +} + +const double * Space::get_double() const +{ + return type == type_double ? &value.value_double : nullptr; +} + +const std::string * Space::get_string() const +{ + return type == type_string ? &value.value_string : nullptr; +} + +const std::wstring * Space::get_wstring() const +{ + return type == type_wstring ? &value.value_wstring : nullptr; +} + +const Space::ObjectType * Space::get_object() const +{ + return type == type_object ? &value.value_object : nullptr; +} + +const Space::TableType * Space::get_table() const +{ + return type == type_table ? &value.value_table : nullptr; +} + + + + +void Space::copy_value_from(const Space & space) +{ + switch(space.type) { - return nullptr; + case type_null: + initialize_value_null_if_needed(); + break; + + case type_bool: + initialize_value_bool_if_needed(); + value.value_bool = space.value.value_bool; + break; + + case type_long: + initialize_value_long_if_needed(); + value.value_long = space.value.value_long; + break; + + case type_float: + initialize_value_float_if_needed(); + value.value_float = space.value.value_float; + break; + + case type_double: + initialize_value_double_if_needed(); + value.value_double = space.value.value_double; + break; + + case type_string: + initialize_value_string_if_needed(); + value.value_string = space.value.value_string; + break; + + case type_wstring: + initialize_value_wstring_if_needed(); + value.value_wstring = space.value.value_wstring; + break; + + case type_object: + copy_value_object(space.value); + break; + + case type_table: + copy_value_table(space.value); + break; } - else +} + + + + +void Space::copy_value_object(const Value & value_from) +{ + initialize_value_object_if_needed(); + value.value_object.clear(); + + for(auto map_item : value_from.value_object) { - return &t->second[0]; + Space * new_space = new Space(*map_item.second); + value.value_object.insert(std::make_pair(map_item.first, new_space)); } } -// CHECK ME -const std::wstring * Space::GetFirstValue(const wchar_t * name) const +void Space::copy_value_table(const Value & value_from) { - tmp_name = name; - return GetFirstValue(tmp_name); -} + initialize_value_table_if_needed(); + value.value_table.clear(); -const std::wstring * Space::GetFirstValue(const std::wstring & name) const -{ - Table::const_iterator t = table.find(name); - - if( t == table.end() || t->second.empty() ) + for(Space * space : value_from.value_table) { - return nullptr; + Space * new_space = new Space(*space); + value.value_table.push_back(new_space); } - else +} + + +void Space::initialize_value_null_if_needed() +{ + if( type != type_null ) { - return &t->second[0]; + remove_value(); + type = type_null; } } - - -bool Space::HasValue(const wchar_t * name, const wchar_t * value) +void Space::initialize_value_bool_if_needed() { - tmp_name = name; - tmp_value_text = value; - -return HasValue(tmp_name, tmp_value_text); -} - -bool Space::HasValue(const wchar_t * name, const std::wstring & value) -{ - tmp_name = name; - -return HasValue(tmp_name, value); -} - - -bool Space::HasValue(const std::wstring & name, const wchar_t * value) -{ - tmp_value_text = value; - -return HasValue(name, tmp_value_text); -} - - -bool Space::HasValue(const std::wstring & name, const std::wstring & value) -{ - Table::const_iterator t = table.find(name); - - if( t != table.end() ) + if( type != type_bool ) { - for(size_t i=0 ; i < t->second.size() ; ++i) - if( t->second[i] == value ) - return true; + remove_value(); + new (&value) bool; + type = type_bool; } - -return false; } - - - -//std::wstring Space::Text(const wchar_t * name) const -//{ -// tmp_name = name; -// return Text(tmp_name, L""); -//} - - - -std::wstring Space::Text(const wchar_t * name, const wchar_t * def) const +void Space::initialize_value_long_if_needed() { - tmp_name = name; - return Text(tmp_name, def); -} - - -std::wstring Space::Text(const std::wstring & name, const wchar_t * def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) + if( type != type_long ) { - return *value; + remove_value(); + new (&value) long long; + type = type_long; } - else +} + + +void Space::initialize_value_float_if_needed() +{ + if( type != type_float ) { - if( def ) - return std::wstring(def); - else - return std::wstring(); + remove_value(); + new (&value) float; + type = type_float; } } -std::wstring Space::Text(const std::wstring & name, const std::wstring & def) const +void Space::initialize_value_double_if_needed() { - const std::wstring * value = GetFirstValue(name); - - if( value ) + if( type != type_double ) { - return *value; + remove_value(); + new (&value) double; + type = type_double; } - else +} + + +void Space::initialize_value_string_if_needed() +{ + if( type != type_string ) { - return def; + remove_value(); + new (&value) std::string; + type = type_string; } } - - -//std::wstring & Space::TextRef(const wchar_t * name) -//{ -// tmp_name = name; -// return TextRef(tmp_name, L""); -//} - - -std::wstring & Space::TextRef(const wchar_t * name, const wchar_t * def) +void Space::initialize_value_wstring_if_needed() { - tmp_name = name; - return TextRef(tmp_name, def); -} - -std::wstring & Space::TextRef(const std::wstring & name, const wchar_t * def) -{ - Value * value; - Table::iterator t = table.find(name); - - if( t != table.end() ) + if( type != type_wstring ) { - value = &t->second; + remove_value(); + new (&value) std::wstring; + type = type_wstring; } - else +} + + +void Space::initialize_value_object_if_needed() +{ + if( type != type_object ) { - value = &table[name]; + remove_value(); + new (&value) ObjectType; + type = type_object; } +} - if( value->empty() ) + +void Space::initialize_value_table_if_needed() +{ + if( type != type_table ) { - if( def ) - value->push_back(def); - else - value->push_back(std::wstring()); + remove_value(); + new (&value) TableType; + type = type_table; } - - return (*value)[0]; } -std::wstring & Space::TextRef(const std::wstring & name, const std::wstring & def) +void Space::remove_value() { - return TextRef(name, def.c_str()); -} - - - - -//std::string Space::TextA(const wchar_t * name) const -//{ -// tmp_name = name; -// return TextA(tmp_name, ""); -//} - - - -std::string Space::TextA(const wchar_t * name, const char * def) const -{ - tmp_name = name; - return TextA(tmp_name, def); -} - - -std::string Space::TextA(const std::wstring & name, const char * def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) + switch(type) { - std::string res; - PT::WideToUTF8(*value, res); - return res; - } - else + case type_null: + break; + + case type_bool: + case type_long: + case type_float: + case type_double: + type = type_null; + break; + + case type_string: { - if( def ) - return std::string(def); - else - return std::string(); + remove_value_string(); + break; } -} - -std::string Space::TextA(const std::wstring & name, const std::string & def) const -{ - return TextA(name, def.c_str()); -} - - - -std::string Space::TextA(const wchar_t * name, const wchar_t * def) const -{ - tmp_name = name; - return TextA(tmp_name, def); -} - - -std::string Space::TextA(const std::wstring & name, const wchar_t * def) const -{ - const std::wstring * value = GetFirstValue(name); - std::string res; - - if( value ) + case type_wstring: { - PT::WideToUTF8(*value, res); - return res; + remove_value_wstring(); + break; } - else + + case type_object: { - PT::WideToUTF8(def, res); - return res; + remove_value_object(); + break; + } + + case type_table: + remove_value_table(); + break; } } -std::string Space::TextA(const std::wstring & name, const std::wstring & def) const + +void Space::remove_value_string() { - return TextA(name, def.c_str()); + value.value_string.~basic_string(); + type = type_null; } - - -unsigned int Space::ToUInt(const std::wstring & value) +void Space::remove_value_wstring() { - return Toui_b(value.c_str()); -} - -int Space::ToInt(const std::wstring & value) -{ - return Toi_b(value.c_str()); + value.value_wstring.~basic_string(); + type = type_null; } -unsigned long Space::ToULong(const std::wstring & value) +void Space::remove_value_object() { - return Toul_b(value.c_str()); -} - -long Space::ToLong(const std::wstring & value) -{ - return Tol_b(value.c_str()); -} - - -unsigned long long Space::ToULongLong(const std::wstring & value) -{ - return Toull_b(value.c_str()); -} - -long long Space::ToLongLong(const std::wstring & value) -{ - return Toll_b(value.c_str()); -} - - -size_t Space::ToSize(const std::wstring & value) -{ - if( sizeof(size_t) == sizeof(unsigned int) ) - return ToUInt(value); - else - if( sizeof(size_t) == sizeof(unsigned long) ) - return ToULong(value); - else - return ToULongLong(value); -} - - -bool Space::ToBool(const std::wstring & value) -{ - const wchar_t * str_begin = SkipWhite(value.c_str()); - const wchar_t * str_end = SkipWhiteFromBack(str_begin); - - return (PT::EqualNoCase(str_begin, str_end, L"true") || - PT::EqualNoCase(str_begin, str_end, L"yes") || - PT::EqualNoCase(str_begin, str_end, L"1") - ); -} - - - - - - -int Space::Int(const wchar_t * name, int def) const -{ - tmp_name = name; - return Int(tmp_name, def); -} - - - - -int Space::Int(const std::wstring & name, int def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToInt(*value); - -return def; -} - - - -unsigned int Space::UInt(const wchar_t * name, unsigned int def) const -{ - tmp_name = name; - return UInt(tmp_name, def); -} - - -unsigned int Space::UInt(const std::wstring & name, unsigned int def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToUInt(*value); - -return def; -} - - - - - -long Space::Long(const wchar_t * name, long def) const -{ - tmp_name = name; - return Long(tmp_name, def); -} - - -long Space::Long(const std::wstring & name, long def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToLong(*value); - -return def; -} - - -unsigned long Space::ULong(const wchar_t * name, unsigned long def) const -{ - tmp_name = name; - return ULong(tmp_name, def); -} - - -unsigned long Space::ULong(const std::wstring & name, unsigned long def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToULong(*value); - -return def; -} - - - -long long Space::LongLong(const wchar_t * name, long long def) const -{ - tmp_name = name; - return LongLong(tmp_name, def); -} - -long long Space::LongLong(const std::wstring & name, long long def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToLongLong(*value); - -return def; -} - -unsigned long long Space::ULongLong(const wchar_t * name, unsigned long long def) const -{ - tmp_name = name; - return ULongLong(tmp_name, def); -} - -unsigned long long Space::ULongLong(const std::wstring & name, unsigned long long def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToULongLong(*value); - -return def; -} - - - - - -size_t Space::Size(const wchar_t * name, size_t def) const -{ - tmp_name = name; - return Size(tmp_name, def); -} - - -size_t Space::Size(const std::wstring & name, size_t def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToSize(*value); - -return def; -} - - - - -bool Space::Bool(const wchar_t * name, bool def) const -{ - tmp_name = name; - return Bool(tmp_name, def); -} - - - -bool Space::Bool(const std::wstring & name, bool def) const -{ - const std::wstring * value = GetFirstValue(name); - - if( value ) - return ToBool(*value); - -return def; -} - - -// !! CHECKME -std::wstring & Space::FindAdd(const std::wstring & name) -{ - Value * value; - - Table::iterator t = table.find(name); - - if( t != table.end() ) + for(auto map_item : value.value_object) { - value = &t->second; + delete map_item.second; + map_item.second = nullptr; } - else + + value.value_object.~ObjectType(); + type = type_null; +} + + +void Space::remove_value_table() +{ + for(size_t i = 0 ; i < value.value_table.size() ; ++i) { - value = &table[name]; + delete value.value_table[i]; + value.value_table[i] = nullptr; } - if( value->empty() ) - value->push_back(std::wstring()); - - return (*value)[0]; + value.value_table.~TableType(); + type = type_null; } -// !! CHECKME -std::wstring & Space::FindAdd(const wchar_t * name) -{ - tmp_name = name; - return FindAdd(tmp_name); -} - - -// !! CHECKME -std::wstring & Space::FindAdd(const WTextStream & name) -{ - name.to_string(tmp_name); - return FindAdd(tmp_name); -} - - - - - - -/* - * - * - * - * - * CHECKME !! - */ -std::wstring & Space::Add(const std::wstring & name, const std::wstring & value, bool replace_existing) -{ - Table::iterator i = table.find(name); - - if( i == table.end() ) - { - Value & val = table[name]; - val.push_back(value); - return val.back(); - } - else - { - Value & val = i->second; - - if( replace_existing ) - val.clear(); - - val.push_back(value); - return val.back(); - } -} - - -// CHECKME !! -std::wstring & Space::Add(const std::wstring & name, const wchar_t * value, bool replace_existing) -{ - tmp_value = value; - return Add(name, tmp_value, replace_existing); -} - - -// CHECKME !! -std::wstring & Space::Add(const wchar_t * name, const wchar_t * value, bool replace_existing) -{ - tmp_name = name; - tmp_value = value; - return Add(tmp_name, tmp_value, replace_existing); -} - - -// CHECKME !! -std::wstring & Space::Add(const wchar_t * name, const std::wstring & value, bool replace_existing) -{ - tmp_name = name; - return Add(tmp_name, value, replace_existing); -} - - - - -// CHECKME !! -std::wstring & Space::Add(const wchar_t * name, const WTextStream & value, bool replace_existing) -{ - tmp_name = name; - value.to_string(tmp_value); - return Add(tmp_name, tmp_value, replace_existing); -} - - -// CHECKME !! -std::wstring & Space::Add(const std::wstring & name, const WTextStream & value, bool replace_existing) -{ - value.to_string(tmp_value); - return Add(name, tmp_value, replace_existing); -} - - -// CHECKME !! -std::wstring & Space::Add(const WTextStream & name, const WTextStream & value, bool replace_existing) -{ - name.to_string(tmp_name); - value.to_string(tmp_value); - return Add(tmp_name, tmp_value, replace_existing); -} - - - - -/* - * - * - * - * - * - */ -// CHECKME -std::wstring & Space::Add(const std::wstring & name, bool value, bool replace_existing) -{ - if( value ) - return Add(name, L"true", replace_existing); - else - return Add(name, L"false", replace_existing); -} - - -// CHECKME -std::wstring & Space::Add(const wchar_t * name, bool value, bool replace_existing) -{ - tmp_name = name; - return Add(tmp_name, value, replace_existing); -} - - - -// CHECKME -std::wstring & Space::Add(const std::wstring & name, int value, bool replace_existing) -{ -wchar_t value_str[50]; - -#if defined _WIN32 || defined _WIN64 - swprintf(value_str, L"%d", value); -#else - swprintf(value_str, sizeof(value_str)/sizeof(wchar_t), L"%d", value); -#endif - - return Add(name, value_str, replace_existing); -} - - -// CHECKME -std::wstring & Space::Add(const wchar_t * name, int value, bool replace_existing) -{ - tmp_name = name; - return Add(tmp_name, value, replace_existing); -} - - - - - -// CHECKME -std::wstring & Space::Add(const std::wstring & name, long value, bool replace_existing) -{ -wchar_t value_str[50]; - -#if defined _WIN32 || defined _WIN64 - swprintf(value_str, L"%ld", value); -#else - swprintf(value_str, sizeof(value_str)/sizeof(wchar_t), L"%ld", value); -#endif - - return Add(name, value_str, replace_existing); -} - - - -// CHECKME -std::wstring & Space::Add(const wchar_t * name, long value, bool replace_existing) -{ - tmp_name = name; - return Add(tmp_name, value, replace_existing); -} - - - -std::wstring & Space::Add(const std::wstring & name, size_t value, bool replace_existing) -{ -wchar_t value_str[50]; - -#if defined _WIN32 || defined _WIN64 - // see http://msdn.microsoft.com/en-us/library/tcxf1dw6%28v=vs.71%29.aspx - swprintf(value_str, L"%Iu", value); -#else - swprintf(value_str, sizeof(value_str)/sizeof(wchar_t), L"%zu", value); -#endif - - return Add(name, value_str, replace_existing); -} - - -std::wstring & Space::Add(const wchar_t * name, size_t value, bool replace_existing) -{ - tmp_name = name; - return Add(tmp_name, value, replace_existing); -} - - - - - - -void Space::Remove(const std::wstring & name) -{ - table.erase(name); -} - - -void Space::Remove(const wchar_t * name) -{ - tmp_name = name; - Remove(tmp_name); -} - - - - - -// CHECKME -Space & Space::AddSpace(const std::wstring & name) -{ - spaces.push_back(new Space()); - spaces.back()->name = name; - spaces.back()->parent = this; - -return *spaces.back(); -} - - -// CHECKME -Space & Space::AddSpace(const wchar_t * name) -{ - tmp_name = name; - return AddSpace(tmp_name); -} - - - - -Space * Space::FindSpace(const wchar_t * name) -{ - for(size_t i=0 ; iname == name ) // there is a special == operator in string class taking c-string as an argument - return spaces[i]; - } - -return nullptr; -} - - -Space * Space::FindSpace(const std::wstring & name) -{ - for(size_t i=0 ; iname == name ) - return spaces[i]; - } - -return nullptr; -} - - -Space & Space::FindAddSpace(const wchar_t * name) -{ - Space * space = FindSpace(name); - - if( space ) - return *space; - -return AddSpace(name); -} - - -Space & Space::FindAddSpace(const std::wstring & name) -{ - Space * space = FindSpace(name); - - if( space ) - return *space; - -return AddSpace(name); -} - - - -void Space::RemoveSpace(const wchar_t * name) -{ - for(size_t i=0 ; iname == name ) - RemoveSpace(i); - else - ++i; - } -} - - -void Space::RemoveSpace(const std::wstring & name) -{ - for(size_t i=0 ; iname == name ) - RemoveSpace(i); - else - ++i; - } -} - - -void Space::RemoveSpace(size_t child_index) -{ - if( child_index < spaces.size() ) - { - delete spaces[child_index]; - spaces.erase(spaces.begin() + child_index); - } -} - - - - - - - -bool Space::ListText(const std::wstring & name, std::vector & list) -{ - list.clear(); - - Table::iterator t = table.find(name); - - if( t != table.end() ) - { - list = t->second; - return true; - } - -return false; -} - - - -// in lists we don't use default values -bool Space::ListText(const wchar_t * name, std::vector & list) -{ - tmp_name = name; - return ListText(tmp_name, list); -} - - - - -/* - those white characters here should be the same as in spaceparser.cpp -*/ -bool Space::IsWhite(int c) -{ - // dont use '\n' here - // 13 (\r) is at the end of a line in a dos file \r\n - // 160 is an unbreakable space - if( c==' ' || c=='\t' || c==13 || c==160 ) - return true; - -return false; -} - - -bool Space::HasWhite(const std::wstring & str) -{ - for(size_t i=0 ; i #include #include +#include +#include #include "textstream/types.h" +#include "convert/inttostr.h" +//#include "utf8/utf8.h" @@ -165,400 +169,625 @@ class Space { public: + typedef std::map ObjectType; + typedef std::vector TableType; + + enum Escape + { + no_escape, + escape_space, + escape_json, + }; + + enum Type + { + type_null, + type_bool, + type_long, + type_float, + type_double, + type_string, + type_wstring, + type_object, + type_table, + }; + + union Value + { + bool value_bool; + long long value_long; + float value_float; + double value_double; + std::string value_string; + std::wstring value_wstring; + ObjectType value_object; + TableType value_table; + + Value() + { + } + + ~Value() + { + } + }; + + + Type type; + Value value; - /* - this is the table which represents your config file - in the Table map: the first (key) is your 'option' and the second is 'list' - */ - typedef std::vector Value; - typedef std::map Table; Space(); + Space(const Space & space); + Space & operator=(const Space & space); + // add move cctor ~Space(); - Space(const Space & s); - Space & operator=(const Space & s); - - // IMPROVE ME - // add move cctor - - - void Clear(); - - - - /* - returns true if such an option has 'value' - useful when testing lists (they don't have to be copied out) - */ - bool HasValue(const wchar_t * name, const wchar_t * value); - bool HasValue(const wchar_t * name, const std::wstring & value); - bool HasValue(const std::wstring & name, const wchar_t * value); - bool HasValue(const std::wstring & name, const std::wstring & value); - - - - /* - * - * methods for getting/finding a value - * - * - */ - - /* - * - * their working in O(log) - * can return a null pointer - * - */ - Value * GetValue(const wchar_t * name); - Value * GetValue(const std::wstring & name); - const Value * GetValue(const wchar_t * name) const; - const Value * GetValue(const std::wstring & name) const; - - - - // O(n) complexity - Value * GetValueNoCase(const wchar_t * name); - Value * GetValueNoCase(const std::wstring & name); - const Value * GetValueNoCase(const wchar_t * name) const; - const Value * GetValueNoCase(const std::wstring & name) const; - - - // they can return a null pointer if there is not such a 'name' - std::wstring * GetFirstValue(const wchar_t * name); - std::wstring * GetFirstValue(const std::wstring & name); - - const std::wstring * GetFirstValue(const wchar_t * name) const; - const std::wstring * GetFirstValue(const std::wstring & name) const; - - - /* - those methods are used to extract information from space.table - as a parameter they take the name of an option - and a default value (if there is no such a parameter), - they return appropriate value (either text, int or boolean) - (in lists they return the first item if exists) - - when calling Text(...) and AText(...) you should copy the object to whom a reference is returned - it will be cleared in a next call to one of these methods (as well to Int() Size() and Bool()) - - AText(...) always returns a reference to UTF-8 string - */ - //std::wstring Text(const wchar_t * name) const; - std::wstring Text(const wchar_t * name, const wchar_t * def = 0) const; - std::wstring Text(const std::wstring & name, const wchar_t * def = 0) const; - std::wstring Text(const std::wstring & name, const std::wstring & def) const; - - // returns a reference - // if there is no such an option then a new one (def value) is inserted - //std::wstring & TextRef(const wchar_t * name); - std::wstring & TextRef(const wchar_t * name, const wchar_t * def = 0); - std::wstring & TextRef(const std::wstring & name, const wchar_t * def = 0); - std::wstring & TextRef(const std::wstring & name, const std::wstring & def); - - - // returns UTF-8 string - //std::string TextA(const wchar_t * name) const; - std::string TextA(const wchar_t * name, const char * def) const; - std::string TextA(const std::wstring & name, const char * def) const; - std::string TextA(const std::wstring & name, const std::string & def) const; - - std::string TextA(const wchar_t * name, const wchar_t * def) const; - std::string TextA(const std::wstring & name, const wchar_t * def) const; - std::string TextA(const std::wstring & name, const std::wstring & def) const; - - - - int Int(const wchar_t * name, int def = 0) const; - int Int(const std::wstring & name, int def = 0) const; - unsigned int UInt(const wchar_t * name, unsigned int def = 0) const; - unsigned int UInt(const std::wstring & name, unsigned int def = 0) const; - - long Long(const wchar_t * name, long def = 0) const; - long Long(const std::wstring & name, long def = 0) const; - unsigned long ULong(const wchar_t * name, unsigned long def = 0) const; - unsigned long ULong(const std::wstring & name, unsigned long def = 0) const; - - long long LongLong(const wchar_t * name, long long def = 0) const; - long long LongLong(const std::wstring & name, long long def = 0) const; - unsigned long long ULongLong(const wchar_t * name, unsigned long long def = 0) const; - unsigned long long ULongLong(const std::wstring & name, unsigned long long def = 0) const; - - size_t Size(const wchar_t * name, size_t def = 0) const; - size_t Size(const std::wstring & name, size_t def = 0) const; - - bool Bool(const wchar_t * name, bool def = false) const; - bool Bool(const std::wstring & name, bool def = false) const; - - - - /* - * - * methods for adding a new value - * - * - */ - - - std::wstring & FindAdd(const wchar_t * name); - std::wstring & FindAdd(const std::wstring & name); - std::wstring & FindAdd(const WTextStream & name); - - std::wstring & Add(const wchar_t * name, bool value, bool replace_existing = true); - std::wstring & Add(const std::wstring & name, bool value, bool replace_existing = true); - std::wstring & Add(const wchar_t * name, int value, bool replace_existing = true); - std::wstring & Add(const std::wstring & name, int value, bool replace_existing = true); - std::wstring & Add(const wchar_t * name, long value, bool replace_existing = true); - std::wstring & Add(const std::wstring & name, long value, bool replace_existing = true); - std::wstring & Add(const wchar_t * name, size_t value, bool replace_existing = true); - std::wstring & Add(const std::wstring & name, size_t value, bool replace_existing = true); - - std::wstring & Add(const std::wstring & name, const std::wstring & value, bool replace_existing = true); - std::wstring & Add(const std::wstring & name, const wchar_t * value, bool replace_existing = true); - std::wstring & Add(const wchar_t * name, const wchar_t * value, bool replace_existing = true); - std::wstring & Add(const wchar_t * name, const std::wstring & value, bool replace_existing = true); - - std::wstring & Add(const wchar_t * name, const WTextStream & value, bool replace_existing = true); - std::wstring & Add(const std::wstring & name, const WTextStream & value, bool replace_existing = true); - std::wstring & Add(const WTextStream & name, const WTextStream & value, bool replace_existing = true); - - void Remove(const wchar_t * name); - void Remove(const std::wstring & name); - - - - Space & AddSpace(const wchar_t * name); - Space & AddSpace(const std::wstring & name); - - // looking for the first space with the specified name - // if there is not such a space those methods return a null pointer - Space * FindSpace(const wchar_t * name); - Space * FindSpace(const std::wstring & name); - - // looking for the first space with the specified name - // if there is not such a space then this methods adds such a space - Space & FindAddSpace(const wchar_t * name); - Space & FindAddSpace(const std::wstring & name); - - void RemoveSpace(const wchar_t * name); - void RemoveSpace(const std::wstring & name); - void RemoveSpace(size_t child_index); - - - /* - * - * - raw access to the parsed values - * - * - */ - - std::wstring name; // space name - Table table; // std::map > - - // childs - typedef std::vector Spaces; - Spaces spaces; - - // a parent space - // null means a root space - Space * parent; - - - - /* - those methods are used to extract lists - return true if such an option exists (but value can be an empty list) - */ - bool ListText(const wchar_t * name, std::vector & list); - bool ListText(const std::wstring & name, std::vector & list); - - - /* - serialize the content - */ - template - void Serialize(Stream & out, bool use_indents = false, bool use_comments = false, int level = 0) const; - - template - void SerializeTableMulti(Stream & out, bool use_indents, int level) const; - - template - static void PrintValue(Stream & out, const StringType & str, bool use_quote = true); - - template - static void PrintKey(Stream & out, const std::wstring & str); - - template - static void PrintLevel(Stream & out, bool use_indents, int level); - - - -private: - - mutable std::wstring tmp_name; - - std::wstring tmp_value; - std::wstring tmp_value_text; - std::string tmp_value_text_ascii; - - static unsigned int ToUInt(const std::wstring & value); - static int ToInt(const std::wstring & value); - static unsigned long ToULong(const std::wstring & value); - static long ToLong(const std::wstring & value); - static unsigned long long ToULongLong(const std::wstring & value); - static long long ToLongLong(const std::wstring & value); - static size_t ToSize(const std::wstring & value); - static bool ToBool(const std::wstring & value); - - static bool IsWhite(int c); - static bool HasWhite(const std::wstring & str); - -}; - - - -template -void Space::PrintLevel(Stream & out, bool use_indents, int level) -{ - if( use_indents ) + Space(bool val); + Space(short val); + Space(int val); + Space(long val); + Space(long long val); + Space(unsigned short val); + Space(unsigned int val); + Space(unsigned long val); + Space(unsigned long long val); + Space(float val); + Space(double val); + Space(const char * str); + Space(const wchar_t * str); + Space(const std::string & str); + Space(const std::wstring & str); + Space(const Space * space); + + + // set a new value + void set(bool val); + void set(short val); + void set(int val); + void set(long val); + void set(long long val); + void set(unsigned short val); + void set(unsigned int val); + void set(unsigned long val); + void set(unsigned long long val); + void set(float val); + void set(double val); + void set(const char * str); + void set(const wchar_t * str); + void set(const std::string & str); + void set(const std::wstring & str); + void set(const Space * space = nullptr); + + + // add a value to the table, change to table if needed, return the reference to the new inserted item + Space & add(bool val); + Space & add(short val); + Space & add(int val); + Space & add(long val); + Space & add(long long val); + Space & add(unsigned short val); + Space & add(unsigned int val); + Space & add(unsigned long val); + Space & add(unsigned long long val); + Space & add(float val); + Space & add(double val); + Space & add(const char * val); + Space & add(const wchar_t * val); + Space & add(const std::string & val); + Space & add(const std::wstring & val); + Space & add(const Space * space); + + // add a value to the object, change to object if needed, return the reference to the new inserted item + Space & add(const wchar_t * field, bool val); + Space & add(const wchar_t * field, short val); + Space & add(const wchar_t * field, int val); + Space & add(const wchar_t * field, long val); + Space & add(const wchar_t * field, long long val); + Space & add(const wchar_t * field, unsigned short val); + Space & add(const wchar_t * field, unsigned int val); + Space & add(const wchar_t * field, unsigned long val); + Space & add(const wchar_t * field, unsigned long long val); + Space & add(const wchar_t * field, float val); + Space & add(const wchar_t * field, double val); + Space & add(const wchar_t * field, const char * val); + Space & add(const wchar_t * field, const wchar_t * val); + Space & add(const wchar_t * field, const std::string & val); + Space & add(const wchar_t * field, const std::wstring & val); + Space & add(const wchar_t * field, const Space * space); + Space & add_empty_space(const wchar_t * field); // IMPROVEME rename me to something better + + + + bool is_null() const; + bool is_bool() const; + bool is_llong() const; + bool is_long_long() const; + bool is_float() const; + bool is_double() const; + bool is_numeric() const; + bool is_str() const; + bool is_wstr() const; + bool is_text() const; + bool is_object() const; + bool is_table() const; + + + + bool to_bool() const; + short to_short() const; + int to_int() const; + long to_long() const; + long long to_llong() const; + long long to_long_long() const; + unsigned short to_ushort() const; + unsigned int to_uint() const; + unsigned long to_ulong() const; + unsigned long long to_ullong() const; + unsigned long long to_ulong_long() const; + std::string to_str() const; + std::wstring to_wstr() const; + + + + bool * get_bool(); + long long * get_llong(); + long long * get_long_long(); + float * get_float(); + double * get_double(); + std::string * get_string(); + std::wstring * get_wstring(); + ObjectType * get_object(); + TableType * get_table(); + + + + const bool * get_bool() const; + const long long * get_llong() const; + const long long * get_long_long() const; + const float * get_float() const; + const double * get_double() const; + const std::string * get_string() const; + const std::wstring * get_wstring() const; + const ObjectType * get_object() const; + const TableType * get_table() const; + + + + std::string serialize_to_space_str() const; + std::wstring serialize_to_space_wstr() const; + void serialize_to_space_to(std::string & str) const; + void serialize_to_space_to(std::wstring & str) const; + + template + void serialize_to_space_stream(StreamType & str) const { - for(int i=0 ; i -void Space::PrintValue(Stream & out, const StringType & str, bool use_quote) -{ - if( use_quote ) - out << '\"'; - - for(size_t i=0 ; i + void serialize_to_json_stream(StreamType & str) const { - switch(str[i]) + switch(type) + { + case type_null: + serialize_json_null(str); + break; + + case type_bool: + serialize_json_bool(str); + break; + + case type_long: + serialize_json_long(str); + break; + + case type_float: + serialize_json_float(str); + break; + + case type_double: + serialize_json_double(str); + break; + + case type_string: + serialize_json_string(str); + break; + + case type_wstring: + serialize_json_wstring(str); + break; + + case type_object: + serialize_json_object(str); + break; + + case type_table: + serialize_json_table(str); + break; + } + } + + +protected: + + + template + Space & add_generic(ArgType val) + { + initialize_value_table_if_needed(); + + Space * new_space = new Space(val); + value.value_table.push_back(new_space); + + return *value.value_table.back(); + } + + + template + Space & add_generic(const wchar_t * field, ArgType val) + { + initialize_value_object_if_needed(); + + auto insert_res = value.value_object.insert(std::make_pair(field, nullptr)); + insert_res.first->second = new Space(val); + + return *(insert_res.first->second); + } + + + template + ArgType to_generic_numeric_signed_value() const + { + long long val = to_long_long(); + + if( val < std::numeric_limits::min() || val > std::numeric_limits::max() ) + val = 0; + + return val; + } + + template + ArgType to_generic_numeric_unsigned_value() const + { + unsigned long long val = to_ulong_long(); + + if( val > std::numeric_limits::max() ) + val = 0; + + return val; + } + + long long convert_string_to_long_long() const; + long long convert_wstring_to_long_long() const; + + unsigned long long convert_string_to_ulong_long() const; + unsigned long long convert_wstring_to_ulong_long() const; + + + + + template + void escape_to_space_format(int c, StreamType & out) const + { + // IMPLEMENT ME + } + + + template + void escape_to_json_format(int c, StreamType & out) const + { + switch(c) { case 0: out << '\\'; out << '0'; break; case '\r': out << '\\'; out << 'r'; break; case '\n': out << '\\'; out << 'n'; break; - case '\\': out << '\\'; out << '\\'; break; - case '"': out << '\\'; out << '\"'; break; - case '(': out << '\\'; out << '('; break; - case ')': out << '\\'; out << ')'; break; - case '=': out << '\\'; out << '='; break; + case '\\': out << '\\'; out << '\\'; break; + case '"': out << '\\'; out << '\"'; break; + //case '(': out << '\\'; out << '('; break; + //case ')': out << '\\'; out << ')'; break; + //case '=': out << '\\'; out << '='; break; default: - out << str[i]; + out << static_cast(c); } } - if( use_quote ) - out << '\"'; -} -template -void Space::PrintKey(Stream & out, const std::wstring & str) -{ -bool use_quote = false; - - // CHECK ME - // HasWhite doesn't take a new line into account, is it correct to use it here? - if( str.empty() || HasWhite(str) ) - use_quote = true; - - PrintValue(out, str, use_quote); -} - - - - -template -void Space::SerializeTableMulti(Stream & out, bool use_indents, int level) const -{ -Table::const_iterator i2; -size_t v; - - for(i2 = table.begin() ; i2 != table.end() ; ++i2) + template + void copy_input_string_to_output(const CharT * input_str, StreamType & out_str, Escape escape) const { - PrintLevel(out, use_indents, level); - PrintKey(out, i2->first); - out << L" = "; - - if( i2->second.size() != 1 ) - out << '('; - - for(v = 0 ; v < i2->second.size() ; ++v) + while( *input_str ) { - if( v > 0 ) - PrintLevel(out, use_indents, level + i2->first.size() + 3); - - PrintValue(out, i2->second[v]); - - if( v + 1 < i2->second.size() ) - out << '\n'; - } - - if( i2->second.size() != 1 ) - out << ')'; - - out << '\n'; - } -} - - -template -void Space::Serialize(Stream & out, bool use_indents, bool use_comments, int level) const -{ - if( level > 0 ) - { - out << '\n'; - PrintLevel(out, use_indents, level); - - if( !name.empty() ) - { - PrintKey(out, name); - out << ' '; - } - - out << L"(\n"; - - if( use_comments ) - { - PrintLevel(out, use_indents, level); - out << L"# space level " << level << '\n'; - } - } - - SerializeTableMulti(out, use_indents, level); - - for(size_t i=0 ; iSerialize(out, use_indents, use_comments, level+1); - - if( level > 0 ) - { - PrintLevel(out, use_indents, level); - out << ')'; - - if( use_comments ) - { - if( name.empty() ) - out << L" # end of unnamed space"; + if( escape == Escape::no_escape ) + out_str << static_cast(*input_str); else - out << L" # end of space: " << name; + if( escape == Escape::escape_space ) + escape_to_space_format(*input_str, out_str); + else + if( escape == Escape::escape_json ) + escape_to_json_format(*input_str, out_str); - out << L" (level " << level << L")"; + input_str += 1; + } + } + + template + void copy_input_stream_to_output(const StreamType & input_str, StreamType & out_str, Escape escape) const + { + typename StreamType::const_iterator i = input_str.begin(); + + while( i != input_str.end() ) + { + if( escape == Escape::no_escape ) + out_str << static_cast(*i); + else + if( escape == Escape::escape_space ) + escape_to_space_format(*i, out_str); + else + if( escape == Escape::escape_json ) + escape_to_json_format(*i, out_str); + + ++i; + } + } + + + template + void serialize_string_buffer(const char * input_str, StreamType & out_str, Escape escape) const + { + if constexpr ( sizeof(char) == sizeof(typename StreamType::char_type) ) + { + // input and output are char (we assume it is utf8) + copy_input_string_to_output(input_str, out_str, escape); + } + else + { + StreamType temp_stream; + + // input is utf8 but output is wide + UTF8ToWide(input_str, temp_stream, false); + copy_input_stream_to_output(temp_stream, out_str, escape); + } + } + + + template + void serialize_string_buffer(const wchar_t * input_str, StreamType & out_str, Escape escape) const + { + if constexpr ( sizeof(wchar_t) == sizeof(typename StreamType::char_type) ) + { + // input and output are wide characters + copy_input_string_to_output(input_str, out_str, escape); + } + else + { + StreamType temp_stream; + + // input is wide but output is utf8 + WideToUTF8(input_str, temp_stream, false); + copy_input_stream_to_output(temp_stream, out_str, escape); + } + } + + + template + void serialize_json_null(StreamType & str) const + { + serialize_string_buffer(L"null", str, Escape::escape_json); + } + + template + void serialize_json_bool(StreamType & str) const + { + if( value.value_bool ) + { + serialize_string_buffer(L"true", str, Escape::escape_json); + } + else + { + serialize_string_buffer(L"false", str, Escape::escape_json); + } + } + + + template + void serialize_json_long(StreamType & str) const + { + wchar_t buffer[50]; + size_t buffer_len = sizeof(buffer) / sizeof(char); + + PT::Toa(value.value_long, buffer, buffer_len); + serialize_string_buffer(buffer, str, Escape::escape_json); + } + + template + void serialize_json_float(StreamType & str) const + { + wchar_t buffer[50]; + size_t buffer_len = sizeof(buffer) / sizeof(char); + + std::swprintf(buffer, buffer_len, L"%f", value.value_float); + serialize_string_buffer(buffer, str, Escape::escape_json); + } + + template + void serialize_json_double(StreamType & str) const + { + wchar_t buffer[50]; + size_t buffer_len = sizeof(buffer) / sizeof(char); + + std::swprintf(buffer, buffer_len, L"%f", value.value_double); + serialize_string_buffer(buffer, str, Escape::escape_json); + } + + template + void serialize_json_string(StreamType & str) const + { + str << '"'; + serialize_string_buffer(value.value_string.c_str(), str, Escape::escape_json); + str << '"'; + } + + template + void serialize_json_wstring(StreamType & str) const + { + str << '"'; + serialize_string_buffer(value.value_wstring.c_str(), str, Escape::escape_json); + str << '"'; + } + + template + void serialize_json_object(StreamType & str) const + { + str << '{'; + + bool is_first = true; + + for(auto & map_item : value.value_object) + { + if( !is_first ) + { + str << ','; + } + + str << '"'; + serialize_string_buffer(map_item.first.c_str(), str, Escape::escape_json); + str << '"'; + str << ':'; + map_item.second->serialize_to_json_stream(str); + is_first = false; } - out << '\n'; + str << '}'; + } + + template + void serialize_json_table(StreamType & str) const + { + str << '['; + + bool is_first = true; + + for(Space * space : value.value_table) + { + if( !is_first ) + { + str << ','; + } + + space->serialize_to_json_stream(str); + is_first = false; + } + + str << ']'; } -} +public: + + + ///////////////////////////// remove me + template + void Serialize(Stream & out, bool use_indents = false, bool use_comments = false, int level = 0) const + { + } + + template + void SerializeTableMulti(Stream & out, bool use_indents, int level) const + { + } + + template + static void PrintValue(Stream & out, const StringType & str, bool use_quote = true) + { + } + + template + static void PrintKey(Stream & out, const std::wstring & str) + { + } + + template + static void PrintLevel(Stream & out, bool use_indents, int level) + { + } + ///////////////////////////// + + +protected: + + + void copy_value_from(const Space & space); + void copy_value_object(const Value & value_from); + void copy_value_table(const Value & value_from); + + void initialize_value_null_if_needed(); + void initialize_value_bool_if_needed(); + void initialize_value_long_if_needed(); + void initialize_value_float_if_needed(); + void initialize_value_double_if_needed(); + void initialize_value_string_if_needed(); + void initialize_value_wstring_if_needed(); + void initialize_value_object_if_needed(); + void initialize_value_table_if_needed(); + + void remove_value(); + void remove_value_string(); + void remove_value_wstring(); + void remove_value_object(); + void remove_value_table(); + + +}; } // namespace From 4ef8f5a884dab3398f73ea473c2811acaa28da58 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 15 Mar 2021 20:09:23 +0100 Subject: [PATCH 07/67] template changed to template --- utf8/utf8.h | 24 ++++++++++++------------ utf8/utf8_private.h | 4 ++-- utf8/utf8_templates.h | 24 ++++++++++++------------ 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/utf8/utf8.h b/utf8/utf8.h index 2cd5b72..a8c0362 100644 --- a/utf8/utf8.h +++ b/utf8/utf8.h @@ -92,17 +92,17 @@ bool UTF8ToWide(const char * utf8, std::wstring & res, bool cle bool UTF8ToWide(const std::string & utf8, std::wstring & res, bool clear = true, int mode = 1); bool UTF8ToWide(std::istream & utf8, std::wstring & res, bool clear = true, int mode = 1); -template -bool UTF8ToWide(const char * utf8, size_t utf8_len, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested +template +bool UTF8ToWide(const char * utf8, size_t utf8_len, StreamType & res, bool clear = true, int mode = 1); // need to be tested -template -bool UTF8ToWide(const char * utf8, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested +template +bool UTF8ToWide(const char * utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested -template -bool UTF8ToWide(const std::string & utf8, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested +template +bool UTF8ToWide(const std::string & utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested -template -bool UTF8ToWide(std::istream & utf8, TextStreamBase & res, bool clear = true, int mode = 1); // need to be tested +template +bool UTF8ToWide(std::istream & utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested @@ -156,11 +156,11 @@ bool WideToUTF8(const wchar_t * wide_string, char * utf8, siz bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, int mode = 1); // implement template -template -void WideToUTF8(TextStreamBase & buffer, std::string & utf8, bool clear = true, int mode = 1); // not tested +template +void WideStreamToUTF8(StreamType & buffer, std::string & utf8, bool clear = true, int mode = 1); // not tested -template -void WideToUTF8(TextStreamBase & buffer, std::ostream & utf8, int mode = 1); // not tested +template +void WideStreamToUTF8(StreamTypeIn & buffer, StreamTypeOut & utf8, int mode = 1); // not tested diff --git a/utf8/utf8_private.h b/utf8/utf8_private.h index d28e525..909d834 100644 --- a/utf8/utf8_private.h +++ b/utf8/utf8_private.h @@ -162,8 +162,8 @@ return !was_error; -template -void IntToWide(int c, TextStreamBase & res) +template +void IntToWide(int c, StreamType & res) { if( sizeof(wchar_t)==2 && c>0xffff ) { diff --git a/utf8/utf8_templates.h b/utf8/utf8_templates.h index bbf9ceb..7acde96 100644 --- a/utf8/utf8_templates.h +++ b/utf8/utf8_templates.h @@ -52,8 +52,8 @@ namespace PT (need to be tested) */ // need to be tested -template -bool UTF8ToWide(const char * utf8, size_t utf8_len, TextStreamBase & res, bool clear, int mode) +template +bool UTF8ToWide(const char * utf8, size_t utf8_len, StreamType & res, bool clear, int mode) { if( clear ) res.clear(); @@ -68,8 +68,8 @@ bool UTF8ToWide(const char * utf8, size_t utf8_len, TextStreamBase -bool UTF8ToWide(const char * utf8, TextStreamBase & res, bool clear, int mode) +template +bool UTF8ToWide(const char * utf8, StreamType & res, bool clear, int mode) { size_t utf8_len = 0; @@ -81,8 +81,8 @@ return UTF8ToWide(utf8, utf8_len, res, clear, mode); -template -bool UTF8ToWide(const std::string & utf8, TextStreamBase & res, bool clear, int mode) +template +bool UTF8ToWide(const std::string & utf8, StreamType & res, bool clear, int mode) { return UTF8ToWide(utf8.c_str(), utf8.size(), res, clear, mode); } @@ -90,8 +90,8 @@ bool UTF8ToWide(const std::string & utf8, TextStreamBase -bool UTF8ToWide(std::istream & utf8, TextStreamBase & res, bool clear, int mode) +template +bool UTF8ToWide(std::istream & utf8, StreamType & res, bool clear, int mode) { int z; bool correct, was_error = false; @@ -238,8 +238,8 @@ bool WideToUTF8(const std::wstring & wide_string, StreamType & utf8, int mode) -template -void WideToUTF8(TextStreamBase & buffer, std::string & utf8, bool clear, int mode) +template +void WideStreamToUTF8(StreamType & buffer, std::string & utf8, bool clear, int mode) { if( clear ) utf8.clear(); @@ -251,8 +251,8 @@ void WideToUTF8(TextStreamBase & buffer, s // not tested -template -void WideToUTF8(TextStreamBase & buffer, std::ostream & utf8, int mode) +template +void WideStreamToUTF8(StreamTypeIn & buffer, StreamTypeOut & utf8, int mode) { private_namespace::WideToUTF8Generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ utf8.write(utf8_buffer, buffer_len); From bc9e4a3844cf4eab7514d68b474cf98747f5a5ce Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 16 Mar 2021 18:35:08 +0100 Subject: [PATCH 08/67] use PT::WideStreamToUTF8() instead of PT::WideToUTF8() for a moment --- log/filelog.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/log/filelog.cpp b/log/filelog.cpp index e4de22e..82c1cb7 100644 --- a/log/filelog.cpp +++ b/log/filelog.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2018, Tomasz Sowa + * Copyright (c) 2018-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,7 +111,7 @@ void FileLog::save_log(PT::WTextStream * buffer) { if( log_stdout ) { - PT::WideToUTF8(*buffer, std::cout); + PT::WideStreamToUTF8(*buffer, std::cout); } if( !log_file.empty() ) @@ -126,7 +126,7 @@ void FileLog::save_log(PT::WTextStream * buffer) if( file ) { - PT::WideToUTF8(*buffer, file); + PT::WideStreamToUTF8(*buffer, file); file.flush(); } } From ba7fa1c19557c2be73a53187568b800c24ca741d Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 16 Mar 2021 18:36:59 +0100 Subject: [PATCH 09/67] fixed: in serialize_json_double(): the buffer length was calculated incorrectly: sizeof(char) changed to sizeof(wchar_t) added to Space struct: void set_null(); void set_empty_string(); void set_empty_wstring(); void set_empty_table(); void set_empty_object(); void clear(); --- space/space.cpp | 55 ++++++++++++++-- space/space.h | 166 +++++++++++++++++++++--------------------------- 2 files changed, 123 insertions(+), 98 deletions(-) diff --git a/space/space.cpp b/space/space.cpp index 203eca2..584c1b4 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -156,6 +156,39 @@ Space::Space(const Space * space) } +void Space::clear() +{ + set_null(); +} + + + +void Space::set_null() +{ + initialize_value_null_if_needed(); +} + +void Space::set_empty_string() +{ + initialize_value_string_if_needed(); +} + +void Space::set_empty_wstring() +{ + initialize_value_wstring_if_needed(); +} + +void Space::set_empty_table() +{ + initialize_value_table_if_needed(); +} + +void Space::set_empty_object() +{ + initialize_value_object_if_needed(); +} + + void Space::set(bool val) @@ -220,14 +253,28 @@ void Space::set(double val) void Space::set(const char * str) { - initialize_value_string_if_needed(); - value.value_string = str; + if( str == nullptr ) + { + initialize_value_null_if_needed(); + } + else + { + initialize_value_string_if_needed(); + value.value_string = str; + } } void Space::set(const wchar_t * str) { - initialize_value_wstring_if_needed(); - value.value_wstring = str; + if( str == nullptr ) + { + initialize_value_null_if_needed(); + } + else + { + initialize_value_wstring_if_needed(); + value.value_wstring = str; + } } void Space::set(const std::string & str) diff --git a/space/space.h b/space/space.h index a6c7ec2..5f5052b 100644 --- a/space/space.h +++ b/space/space.h @@ -55,110 +55,72 @@ namespace PT /* -A parser for parsing config files. -A config file can look like this: - variable1 = value 1 - variable2 = " value 2 " - variable3 = (value 1, value 2) - variable4 = (" value 1 " , "value2", value 3) +Simple form: + key = value -sample of use: - SpaceParser parser; - parser.Parse("/path/to/config"); +If value is equal to 'null' then the internal representation is equal to Type::type_null, e.g: + key = null - if( parser.status == SpaceParser::ok ) - { - // the whole config we have in parser.table - } +If value is either 'false' or 'true' then the internal representation is Type::type_bool, e.g: + key = false + key = true -config syntax: - option = list +If value is an integer number and not an overflow has occured while parsing then type of the value +is Type::type_long (type is 'long long' internally): + key = 1000 - list can consists of any number of items, if you're using more than one item you should - use brackets () +If value is a floating point number then type is Type::type_double (type is 'double' internally): + key = 123.45 + key = 123.45e+10 - for one item the brackets can be ommited: - option = value - white characters at the beginning of the value (and at the end) will be trimmed, - or you can use quotes: - option = "value" - option2 = "value with spaces at the end " +In other cases value has Type::type_wstring type. - the form without quotes: - option = value - should be written in one line, so this is not allowed: - option = - value - you can use a new line characters only between brackets and quotes: - option = "this is - a multiline string" - option = ( value1, - value2 ) +The form with quotation marks: + key = "value" +In such a case value has Type::type_wstring type and can be multiline e.g: + key = "multiline + value" +In this form you can have spaces around value, e.g.: + key = " value with spaces " - but there is one requirement: the first character " or ( should be in the same line, - so this is not allowed - option = - "this is wrong" - but this is ok: - option = " - that is ok" - empty lists: - option = () - this creates an empty list: parser.table['option'].empty() == true +The value can be a list: + key = (value1,value2) +or the same written with spaces around: + key = ( value1 , value2 ) +or written in multiline fashion: + key = ( + value1, + value2, + ) +a colon after value2 is optional. - option = - this creates an empty list too (the same as previously) +List can be written with quotation marks too: + key = ( + "value1", + "value2", + "value3 + with a new line character inside", + ) - option = "" - but this doesn't create an empty list, it creates a list with one (empty) item +List without value: + key = () +is equal to simple form without value, e.g.: + key = - commentaries: - # this is a commentary (until the end of the line) - option = value # this is a commentary too - - commentaries are treated as white characters, other example: - option = ( # this is my list - "value 1" # this is a value one - value 2 # and this is a value two - ) # end of my list - overwriting: - option1 = some value - option1 = other value - # always the last option is used so option1 is "other value" - list delimiter: - option1 = (value1, value2, value3) - option2 = ("value1", "value2", "value3") - above we're using a comma ',' as a list delimiter but when using quotes (second line) - the commas can be omitted: - option2 = ("value1" "value2" "value3") +Difference between a simple form and a list is when parsing the colon, in simple form the colon is a part of the value, e.g.: + key = value with , a colon inside +this is equal to: + key = "value with , a colon inside" - white characters: - the name of an option cannot consist of white characters - some option = value # this is wrong - some_option = value # this is ok +and in a form of a list it would have two values: + key = (value with , a colon inside) +would be equal to: + key = ("value with" , "a colon inside") - which characters are allowed in an option name is defined by IsVariableChar() method - - you can use white characters in values - option = value with spaces or tabs - white characters at the beginning and at the end will be trimmed, - so if you want them use quotes: - option = " other value with spaces " - - special characters in quoted strings: - option = "this is a string with \" a quote inside" - the option will be: this is a string with " a quote inside - \\ - means one \ - basically: \char produces char - so: - "\a" gives "a" - "\\" gives "\" - "\Z" gives "Z" and so on - you can call UseEscapeChar(false) to turn this off */ @@ -242,7 +204,15 @@ public: Space(const Space * space); + void clear(); + // set a new value + void set_null(); + void set_empty_string(); + void set_empty_wstring(); + void set_empty_table(); + void set_empty_object(); + void set(bool val); void set(short val); void set(int val); @@ -258,7 +228,7 @@ public: void set(const wchar_t * str); void set(const std::string & str); void set(const std::wstring & str); - void set(const Space * space = nullptr); + void set(const Space * space); // add a value to the table, change to table if needed, return the reference to the new inserted item @@ -652,20 +622,28 @@ protected: template void serialize_json_float(StreamType & str) const { - wchar_t buffer[50]; + wchar_t buffer[100]; size_t buffer_len = sizeof(buffer) / sizeof(char); - std::swprintf(buffer, buffer_len, L"%f", value.value_float); + int chars_written = std::swprintf(buffer, buffer_len, L"%e", static_cast(value.value_float)); + + if( errno == EOVERFLOW || chars_written < 0 ) + buffer[0] = 0; + serialize_string_buffer(buffer, str, Escape::escape_json); } template void serialize_json_double(StreamType & str) const { - wchar_t buffer[50]; - size_t buffer_len = sizeof(buffer) / sizeof(char); + wchar_t buffer[100]; + size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); + + int chars_written = std::swprintf(buffer, buffer_len, L"%e", value.value_double); + + if( errno == EOVERFLOW || chars_written < 0 ) + buffer[0] = 0; - std::swprintf(buffer, buffer_len, L"%f", value.value_double); serialize_string_buffer(buffer, str, Escape::escape_json); } From 0c0f15ab8a09a83c0a496d8f715d9eb625954990 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 16 Mar 2021 18:40:14 +0100 Subject: [PATCH 10/67] changed: JSONToSpaceParser can parse json string/file to the new Space format now (some minor chars escaping not ready yet) --- space/jsontospaceparser.cpp | 674 +++++++++++++++++++----------------- space/jsontospaceparser.h | 131 +++---- 2 files changed, 420 insertions(+), 385 deletions(-) diff --git a/space/jsontospaceparser.cpp b/space/jsontospaceparser.cpp index a69f820..a88fe8e 100644 --- a/space/jsontospaceparser.cpp +++ b/space/jsontospaceparser.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2012-2017, Tomasz Sowa + * Copyright (c) 2012-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,12 +39,13 @@ #include #include "jsontospaceparser.h" #include "utf8/utf8.h" +#include "convert/strtoint.h" namespace PT { -#ifdef nonexisting_value + JSONToSpaceParser::JSONToSpaceParser() @@ -81,7 +82,6 @@ void JSONToSpaceParser::SetDefault() use_escape_char = true; input_as_utf8 = true; max_nested_level = 1000; - create_table_as_space = true; } @@ -104,13 +104,14 @@ void JSONToSpaceParser::UTF8(bool utf) } -void JSONToSpaceParser::CreateTableAsSpace(bool create_table_as_space_) +int JSONToSpaceParser::get_last_parsed_line() { - create_table_as_space = create_table_as_space_; + return line; } -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const char * file_name) + +JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const char * file_name) { reading_from_file = true; @@ -119,7 +120,7 @@ JSONToSpaceParser::Status JSONToSpaceParser::Parse(const char * file_name) if( file ) { - Parse(); + ParseRootSpace(); file.close(); } else @@ -132,305 +133,438 @@ return status; -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const std::string & file_name) +JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const std::string & file_name) { - return Parse(file_name.c_str()); + return ParseFile(file_name.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const wchar_t * file_name) +JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const wchar_t * file_name) { PT::WideToUTF8(file_name, afile_name); - return Parse(afile_name.c_str()); + return ParseFile(afile_name.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const std::wstring & file_name) +JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const std::wstring & file_name) { - return Parse(file_name.c_str()); + return ParseFile(file_name.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::ParseString(const char * str) +JSONToSpaceParser::Status JSONToSpaceParser::Parse(const char * str) { reading_from_file = false; reading_from_wchar_string = false; pchar_ascii = str; pchar_unicode = 0; - Parse(); + ParseRootSpace(); return status; } -JSONToSpaceParser::Status JSONToSpaceParser::ParseString(const std::string & str) +JSONToSpaceParser::Status JSONToSpaceParser::Parse(const std::string & str) { - return ParseString(str.c_str()); + return Parse(str.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::ParseString(const wchar_t * str) +JSONToSpaceParser::Status JSONToSpaceParser::Parse(const wchar_t * str) { reading_from_file = false; reading_from_wchar_string = true; pchar_unicode = str; pchar_ascii = 0; - Parse(); + ParseRootSpace(); return status; } -JSONToSpaceParser::Status JSONToSpaceParser::ParseString(const std::wstring & str) +JSONToSpaceParser::Status JSONToSpaceParser::Parse(const std::wstring & str) { - return ParseString(str.c_str()); + return Parse(str.c_str()); } -void JSONToSpaceParser::Parse() +void JSONToSpaceParser::ParseRootSpace() { + line = 1; + status = ok; + skipped = 0; + current_nested_level = 0; + parsing_space = false; + if( !root_space ) { status = no_space; return; } - line = 1; - status = ok; - space = root_space; - skipped = 0; - current_nested_level = 0; - ReadChar(); + ReadChar(); // put first character to lastc + Parse(root_space); + token.clear(); +} + + +void JSONToSpaceParser::Parse(Space * space) +{ SkipWhite(); if( lastc == space_start ) { - ParseSpace(false, false); + ParseSpace(space); } else if( lastc == table_start ) { - ParseTable(false); + ParseTable(space); + } + else + if( lastc == '"' ) // IMPROVEME define a variable + { + ParseTextValue(space); } else { - // '{' or '[' expected - status = syntax_error; - } + ReadAlfaNumericToken(); - if( status == ok && space != root_space ) - { - // last closing '}' characters are missing (closing a space) - status = syntax_error; + if( token == L"null" ) + { + space->set_null(); + } + else + if( token == L"true" ) + { + space->set(true); + } + else + if( token == L"false" ) + { + space->set(false); + } + else + if( is_integer_token() ) + { + ParseIntegerValue(space); + } + else + if( is_floating_point_token() ) + { + ParseFloatingPointValue(space); + } + else + { + status = syntax_error; + } } - - token.clear(); - key.clear(); - value.clear(); } -void JSONToSpaceParser::ParseSpace(bool has_space_name, bool insert_new_space) +void JSONToSpaceParser::ParseSpace(Space * space) { - //current_nested_level += 1; + current_nested_level += 1; - if( current_nested_level > max_nested_level ) - { - status = max_nested_spaces_exceeded; - return; - } +// if( current_nested_level > max_nested_level ) +// { +// status = max_nested_spaces_exceeded; +// return; +// } - if( insert_new_space ) + ReadChar(); // inserting a next character after the space_start char to lastc + space->set_empty_object(); + ParseKeyValuePairs(space); + + if( lastc == space_end ) { - SpaceStarts(has_space_name); + ReadChar(); } else { - // insert_new_space as a false is used only when parsing - // the first space (root_space) - ReadChar(); // skipping the first space character '{' + status = syntax_error; } - ParseKeyValuePairs(); - - if( insert_new_space ) - { - SpaceEnds(); - } - else - { - ReadChar(); // skipping the last space character '}' - } - - //current_nested_level -= 1; + current_nested_level -= 1; } -void JSONToSpaceParser::ParseKeyValuePairs() + + + +void JSONToSpaceParser::ParseTextValue(Space * space) { + ReadChar(); // inserting a next character after the ... char to lastc + space->set_empty_wstring(); + std::wstring * str = space->get_wstring(); + + // IMPROVEME add support for escaped characters + while( status == ok && lastc != '"' && lastc != -1 ) + { + str->push_back(static_cast(lastc)); + ReadChar(); + } + + if( lastc == '"' ) + { + ReadChar(); + } + else + { + status = syntax_error; + } +} + + +void JSONToSpaceParser::ParseIntegerValue(Space * space) +{ + const wchar_t * after_str = nullptr; + bool was_overflow = false; + + long long val = Toll(token.c_str(), 10, &after_str, &was_overflow, false); + + if( was_overflow ) + { + status = syntax_error; + } + else + if( size_t(after_str - token.c_str()) != token.size() ) + { + status = syntax_error; + } + else + { + space->set(val); + } +} + + +void JSONToSpaceParser::ParseFloatingPointValue(Space * space) +{ + wchar_t * after_str = nullptr; + double val = wcstod(token.c_str(), &after_str); + + if( errno == ERANGE ) + { + status = syntax_error; + } + else + if( size_t(after_str - token.c_str()) != token.size() ) + { + status = syntax_error; + } + else + { + space->set(val); + } +} + + + + +void JSONToSpaceParser::ParseTable(Space * space) +{ + space->set_empty_table(); + + ReadChar(); // inserting a next character after the table_start char to lastc + space->set_empty_object(); + ParseValuesList(space); + + if( lastc == table_end ) + { + ReadChar(); + } + else + { + status = syntax_error; + } +} + + + + +void JSONToSpaceParser::ParseKeyValuePairs(Space * space) +{ + bool is_first = true; SkipWhite(); while( status == ok && lastc != space_end && lastc != -1 ) { - ReadKey(); - SkipWhite(); - - if( lastc == separator ) + if( !is_first ) { - value.clear(); - ReadChar(); // skipping separator ':' - ReadValue(false, false, true, true); SkipWhite(); if( lastc == option_delimiter ) { - ReadChar(); // skipping delimiter ',' + ReadChar(); // inserting a next character after the option_delimiter to lastc } else - if( lastc != space_end && status == ok ) { status = syntax_error; } } - else + if( status == ok ) { - status = syntax_error; + Space * new_key_space = ReadKey(space); + + if( status == ok && new_key_space ) + { + SkipWhite(); + + if( lastc == separator ) + { + ReadChar(); // inserting a next character after the separator to lastc + + Parse(new_key_space); + //value.clear(); + //ReadValue(false, false, true, true); + } + else + { + status = syntax_error; + } + } } - } -} - -void JSONToSpaceParser::ParseTextTable() -{ - ReadChar(); // skipping table start character '[' - SkipWhite(); - value.clear(); - - while( status == ok && lastc != table_end && lastc != -1 ) - { - // all space objects inside or tables will be skipped - ReadValue(true); + is_first = false; SkipWhite(); - - if( lastc == option_delimiter ) - { - ReadChar(); // skipping delimiter ',' - } - else - if( lastc != table_end && status == ok ) - { - status = syntax_error; - } } - - if( lastc == table_end ) - ReadChar(); // skipping end table character ']' - - AddKeyValuePair(); } -void JSONToSpaceParser::ParseObjectsTable(bool has_key) + + +void JSONToSpaceParser::ParseValuesList(Space * space) { - ReadChar(); // skipping table start character '[' - SpaceStarts(has_key, false); + bool is_first = true; SkipWhite(); while( status == ok && lastc != table_end && lastc != -1 ) { - // 'value' table will not be used here - // (we are creating spaces) - ReadValue(false, true); + if( !is_first ) + { + SkipWhite(); + + if( lastc == option_delimiter ) // may add a new delimiter for tables? default the same as for objects... + { + ReadChar(); // inserting a next character after the delimiter + } + else + { + status = syntax_error; + } + } + + if( status == ok ) + { + Space * new_space = &space->add(new Space()); + Parse(new_space); + } + + is_first = false; SkipWhite(); + } +} - if( lastc == option_delimiter ) + + +bool JSONToSpaceParser::is_integer_token() +{ + if( token.empty() ) + return false; + + size_t i = 0; + + if( token[i] == '-' ) + { + i += 1; + + if( token.size() == 1 ) + return false; + } + + for( ; i < token.size() ; ++i) + { + if( token[i] < '0' || token[i] > '9' ) { - ReadChar(); // skipping delimiter ',' + return false; + } + } + + return true; +} + + +bool JSONToSpaceParser::is_floating_point_token() +{ + bool was_dot = false; + bool was_exponential = false; + bool was_plus_minus_sign = false; + + if( token.empty() ) + return false; + + size_t i = 0; + + if( token[i] == '-' ) + { + i += 1; + + if( token.size() == 1 ) + return false; + } + + for( ; i < token.size() ; ++i) + { + if( token[i] == '.' ) + { + if( was_dot || was_exponential ) + return false; + + was_dot = true; } else - if( lastc != table_end && status == ok ) + if( token[i] == 'e' || token[i]=='E' ) { - status = syntax_error; - } - } + if( was_exponential ) + return false; - if( lastc == table_end ) - ReadChar(); // skipping end table character ']' + was_exponential = true; - SpaceEnds(false); -} - - -void JSONToSpaceParser::ParseTable(bool has_key) -{ - if( create_table_as_space ) - { - //current_nested_level += 1; - - if( current_nested_level > max_nested_level ) - { - status = max_nested_spaces_exceeded; + // the exponential character cannot be the last character + if( i + 1 == token.size() ) + return false; } else + if( token[i] == '+' || token[i] == '-' ) { - ParseObjectsTable(has_key); + if( was_plus_minus_sign || !was_exponential ) + return false; + + // the plus or minus should be after the exponential character + if( i > 0 && (token[i-1] != 'e' && token[i-1] != 'E') ) + return false; + + was_plus_minus_sign = true; + } + else + if( token[i] < '0' || token[i] > '9' ) + { + return false; } - - //current_nested_level -= 1; } - else - { - // ParseTextTable will not create a next level - if( !has_key ) - key.clear(); - - ParseTextTable(); // ParseTextTable will use key - } -} - - - -void JSONToSpaceParser::SpaceStarts(bool has_space_name, bool skip_space_char) -{ - Space * new_space = new Space(); - space->spaces.push_back(new_space); - new_space->parent = space; - - if( has_space_name ) - new_space->name = key; - - space = new_space; - - if( skip_space_char ) - ReadChar(); // skipping space starts character '{' -} - - -void JSONToSpaceParser::SpaceEnds(bool skip_space_char) -{ - if( space == root_space ) - { - // there cannot be a loose list end character in the global space - status = syntax_error; - } - else - { - space = space->parent; - - if( skip_space_char ) - ReadChar(); // skipping closing space character '}' - } + return true; } @@ -446,6 +580,15 @@ return false; } +bool JSONToSpaceParser::is_alfa_numeric_char(int c) +{ + return (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '.' || c=='-'; +} + + void JSONToSpaceParser::SkipWhite() { @@ -456,7 +599,7 @@ void JSONToSpaceParser::SkipWhite() } - +/* void JSONToSpaceParser::Trim(std::wstring & s) { std::wstring::size_type i; @@ -469,7 +612,7 @@ std::wstring::size_type i; if( i==0 && IsWhite(s[i]) ) { - // the whole string has white characters + // the whole string consists of white characters s.clear(); return; } @@ -485,27 +628,28 @@ std::wstring::size_type i; if( i != 0 ) s.erase(0, i); } +*/ - -void JSONToSpaceParser::DeleteFromTable(const std::wstring & var) +void JSONToSpaceParser::ReadAlfaNumericToken() { - Space::Table::iterator i = space->table.find(var); + token.clear(); - if( i != space->table.end() ) - space->table.erase(i); + while( is_alfa_numeric_char(lastc) ) + { + token += static_cast(lastc); + ReadChar(); + } } - - - - +// IMPROVEME in JSON we should not allow non-escaped a new line character void JSONToSpaceParser::ReadTokenQuoted() { + token.clear(); ReadChar(); // skipping the first quotation mark while( lastc != -1 && (char_was_escaped || lastc != '"') ) @@ -515,165 +659,51 @@ void JSONToSpaceParser::ReadTokenQuoted() } if( !char_was_escaped && lastc == '"' ) - ReadChar(); // skipping the last quotation mark - else - status = syntax_error; -} - - -void JSONToSpaceParser::ReadTokenSingle(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2) -{ - while( true ) { - if( lastc == -1 || - (!char_was_escaped && - ( - lastc == space_end || - lastc == table_end || - (white_delimit && IsWhite(lastc)) || - (new_line_delimit && lastc == '\n') || - (delimit1 != -1 && lastc == delimit1) || - (delimit2 != -1 && lastc == delimit2) - ) ) ) - - { - break; - } - - token += static_cast(lastc); - ReadChar(); + ReadChar(); // skipping the last quotation mark } - - Trim(token); -} - - -void JSONToSpaceParser::ReadToken(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2) -{ - token.clear(); - SkipWhite(); - - if( !char_was_escaped && lastc == '"' ) - ReadTokenQuoted(); else - ReadTokenSingle(white_delimit, new_line_delimit, delimit1, delimit2); + { + status = syntax_error; + } } -void JSONToSpaceParser::ReadKey() + + + +Space * JSONToSpaceParser::ReadKey(Space * space) { SkipWhite(); - ReadToken(false, true, separator, table_start); - key = token; -} - -void JSONToSpaceParser::SkipText() -{ - ReadChar(); // skipping the first quote character '"' - - while( lastc != '"' && lastc != -1 ) - ReadChar(); -} - - -void JSONToSpaceParser::SkipObjectOrTable(int start_char, int end_char) -{ -int mark = 1; - - skipped += 1; - ReadChar(); // skipping the first object character '{' or '[' - - do + if( parsing_space ) + { + // IMPROVEME implement me + } + else { if( lastc == '"' ) - SkipText(); - else - if( lastc == end_char ) - mark -= 1; - else - if( lastc == start_char ) - mark += 1; - - ReadChar(); - } - while( mark > 0 && lastc != -1 ); -} - - -void JSONToSpaceParser::SkipObject() -{ - SkipObjectOrTable(space_start, space_end); -} - - -void JSONToSpaceParser::SkipTable() -{ - SkipObjectOrTable(table_start, table_end); -} - - - -//void JSONToSpaceParser::ReadValue(bool add_space_for_single_value, bool auto_add_single_value, bool has_space_name) -void JSONToSpaceParser::ReadValue(bool skip_object_or_table, - bool add_space_for_text_value, - bool has_key, - bool auto_add_text_value) -{ - SkipWhite(); - - if( lastc == space_start ) - { - if( skip_object_or_table ) - SkipObject(); - else - ParseSpace(has_key); - } - else - if( lastc == table_start ) - { - if( skip_object_or_table ) - SkipTable(); - else - ParseTable(has_key); - } - else - { - if( add_space_for_text_value ) { - SpaceStarts(false, false); - ReadToken(false, true, option_delimiter, -1); - space->name = token; - SpaceEnds(false); + ReadTokenQuoted(); } else { - ReadToken(false, true, option_delimiter, -1); - value.push_back(token); - - if( auto_add_text_value ) - AddKeyValuePair(); + status = syntax_error; } } -} - -void JSONToSpaceParser::AddKeyValuePair() -{ - if( value.empty() && skip_empty ) + if( status == ok ) { - DeleteFromTable(key); - return; + Space * new_space = new Space(); + return &space->add(token.c_str(), new_space); } - space->table[key] = value; + return nullptr; } - - int JSONToSpaceParser::ReadUTF8Char() { int c; @@ -862,7 +892,7 @@ int JSONToSpaceParser::ReadChar() return lastc; } -#endif + } // namespace diff --git a/space/jsontospaceparser.h b/space/jsontospaceparser.h index 6691fbc..16a4390 100644 --- a/space/jsontospaceparser.h +++ b/space/jsontospaceparser.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2012-2017, Tomasz Sowa + * Copyright (c) 2012-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ namespace PT { -#ifdef nonexisting_value + class JSONToSpaceParser @@ -86,10 +86,6 @@ public: Status status; - /* - a number of a line in which there is a syntax_error - */ - int line; /* @@ -103,26 +99,32 @@ public: main methods used to parse file_name is the path to a file */ - Status Parse(const char * file_name); - Status Parse(const std::string & file_name); - Status Parse(const wchar_t * file_name); - Status Parse(const std::wstring & file_name); + Status ParseFile(const char * file_name); + Status ParseFile(const std::string & file_name); + Status ParseFile(const wchar_t * file_name); + Status ParseFile(const std::wstring & file_name); /* main methods used to parse str - input string (either 8bit ascii or UTF-8 -- see UTF8() method) */ - Status ParseString(const char * str); - Status ParseString(const std::string & str); + Status Parse(const char * str); + Status Parse(const std::string & str); /* main methods used to parse here input string is always in unicode (wide characters) */ - Status ParseString(const wchar_t * str); - Status ParseString(const std::wstring & str); + Status Parse(const wchar_t * str); + Status Parse(const std::wstring & str); + + /* + * add two args Parse method + * Status Parse(const char * str, Space & output_space); + * + */ /* @@ -145,15 +147,23 @@ public: /* if true then the input file or string (char* or std::string) is treated as UTF-8 + default true + + the internal storage for strings is std::wstring so if you call UTF8(false) then + the characters of input string will be simple static_cast<> from char to wchar_t */ + // rename to use_utf8(bool) void UTF8(bool utf); /* + * + * returns a number of a last parsed line + * can be used to obtain the line in which there was a syntax error + * + */ + int get_last_parsed_line(); - default: true - */ - void CreateTableAsSpace(bool create_table_as_space_); private: @@ -165,10 +175,9 @@ private: /* - a space in which we are now + a number of a line in which there is a syntax_error */ - Space * space; - + int line; /* true if Parse() method was called @@ -197,18 +206,6 @@ private: std::wstring token; - /* - last read key - */ - std::wstring key; - - - /* - last read list - */ - Space::Value value; - - /* separator between a variable and a value, default: '=' */ @@ -261,6 +258,9 @@ private: /* current file + + may it would be better to make a pointer? + if we parse only a string then there is no sense to have such an object */ std::ifstream file; @@ -288,14 +288,6 @@ private: bool use_escape_char; - /* - if false we only allow the tables to consists of text items (numeric, boolean too) - objects are not allowed then - default: true - */ - bool create_table_as_space; - - /* */ @@ -309,35 +301,48 @@ private: size_t max_nested_level; + /* + * + * if parsing_space is false then it means we are parsing JSON format + * + * + */ + bool parsing_space; + + + + // move to ParseFile() method std::string afile_name; - void Parse(); - void ParseSpace(bool has_space_name, bool insert_new_space = true); - void ParseTextTable(); - void ParseObjectsTable(bool has_key); - void ParseTable(bool has_key); - void ParseKeyValuePairs(); - void SkipText(); - void SkipObjectOrTable(int start_char, int end_char); - void SkipTable(); - void SkipObject(); - void SpaceEnds(bool skip_space_char = true); - void SpaceStarts(bool has_space_name, bool skip_space_char = true); + // new + void ParseRootSpace(); + void Parse(Space * space); + void ParseSpace(Space * space); + void ParseTable(Space * space); - void DeleteFromTable(const std::wstring & var); + void ParseKeyValuePairs(Space * space); + void ParseValuesList(Space * space); + + Space * ReadKey(Space * space); + + void ParseTextValue(Space * space); + void ParseIntegerValue(Space * space); + void ParseFloatingPointValue(Space * space); + + + bool is_alfa_numeric_char(int c); + void ReadAlfaNumericToken(); + + + bool is_integer_token(); + bool is_floating_point_token(); void ReadTokenQuoted(); - void ReadTokenSingle(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2); - void ReadToken(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2); - void ReadKey(); - void ReadValue(bool skip_object_or_table = false, - bool add_space_for_text_value = false, - bool has_key = false, - bool auto_add_text_value = false); - void AddKeyValuePair(); + + int ReadUTF8Char(); int ReadASCIIChar(); int ReadCharFromWcharString(); @@ -347,14 +352,14 @@ private: int ReadChar(); bool IsWhite(int c); void SkipWhite(); - void Trim(std::wstring & s); + //void Trim(std::wstring & s); bool IsHexDigit(wchar_t c); int HexToInt(wchar_t c); void ReadUnicodeCodePoint(); }; -#endif + } // namespace From 61291cf7ad4527a0b1b0863d290561737b8e354c Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 16 Mar 2021 18:43:34 +0100 Subject: [PATCH 11/67] make depend --- space/Makefile.dep | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/space/Makefile.dep b/space/Makefile.dep index 2bfdb26..0c75896 100644 --- a/space/Makefile.dep +++ b/space/Makefile.dep @@ -5,11 +5,13 @@ jsontospaceparser.o: ../convert/inttostr.h ../utf8/utf8.h jsontospaceparser.o: ../textstream/textstream.h ../space/space.h jsontospaceparser.o: ../date/date.h ../membuffer/membuffer.h jsontospaceparser.o: ../textstream/types.h ../utf8/utf8_templates.h -jsontospaceparser.o: ../utf8/utf8_private.h +jsontospaceparser.o: ../utf8/utf8_private.h ../convert/strtoint.h +jsontospaceparser.o: ../convert/text.h ../convert/misc.h main.o: space.h ../textstream/types.h ../convert/inttostr.h ../utf8/utf8.h main.o: ../textstream/textstream.h ../space/space.h ../date/date.h main.o: ../membuffer/membuffer.h ../textstream/types.h main.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h +main.o: ../space/jsontospaceparser.h space.o: space.h ../textstream/types.h ../convert/inttostr.h ../utf8/utf8.h space.o: ../textstream/textstream.h ../space/space.h ../date/date.h space.o: ../membuffer/membuffer.h ../textstream/types.h From 5b5a1dfbb65ef1072e20c138609231379979ed06 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 17 Mar 2021 13:16:01 +0100 Subject: [PATCH 12/67] changed the way how the library is built - now there is only one Makefile in the root directory and we have only one pikotools.a lib file - removed: mainparser --- Makefile | 74 ++++------ Makefile.dep | 48 +++++++ convert/Makefile | 27 ---- convert/Makefile.dep | 5 - convert/Makefile.o.dep | 1 - date/Makefile | 27 ---- date/Makefile.dep | 3 - date/Makefile.o.dep | 1 - log/Makefile | 27 ---- log/Makefile.dep | 10 -- log/Makefile.o.dep | 1 - mainparser/Makefile | 27 ---- mainparser/Makefile.dep | 3 - mainparser/Makefile.o.dep | 1 - mainparser/mainparser.cpp | 237 --------------------------------- mainparser/mainparser.h | 132 ------------------ mainparser/sample/Makefile | 10 -- mainparser/sample/sample.cpp | 117 ---------------- mainspaceparser/Makefile | 27 ---- mainspaceparser/Makefile.dep | 7 - mainspaceparser/Makefile.o.dep | 1 - space/Makefile | 27 ---- space/Makefile.dep | 27 ---- space/Makefile.o.dep | 1 - utf8/Makefile | 27 ---- utf8/Makefile.dep | 9 -- utf8/Makefile.o.dep | 1 - 27 files changed, 77 insertions(+), 801 deletions(-) create mode 100644 Makefile.dep delete mode 100644 convert/Makefile delete mode 100644 convert/Makefile.dep delete mode 100644 convert/Makefile.o.dep delete mode 100644 date/Makefile delete mode 100644 date/Makefile.dep delete mode 100644 date/Makefile.o.dep delete mode 100644 log/Makefile delete mode 100644 log/Makefile.dep delete mode 100644 log/Makefile.o.dep delete mode 100644 mainparser/Makefile delete mode 100644 mainparser/Makefile.dep delete mode 100644 mainparser/Makefile.o.dep delete mode 100644 mainparser/mainparser.cpp delete mode 100644 mainparser/mainparser.h delete mode 100644 mainparser/sample/Makefile delete mode 100644 mainparser/sample/sample.cpp delete mode 100644 mainspaceparser/Makefile delete mode 100644 mainspaceparser/Makefile.dep delete mode 100644 mainspaceparser/Makefile.o.dep delete mode 100644 space/Makefile delete mode 100644 space/Makefile.dep delete mode 100644 space/Makefile.o.dep delete mode 100644 utf8/Makefile delete mode 100644 utf8/Makefile.dep delete mode 100644 utf8/Makefile.o.dep diff --git a/Makefile b/Makefile index 5ea0e93..058a006 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,14 @@ -# Makefile for GNU make +sourcefiles:=$(shell find . -name "*.cpp") +objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles)) + + + +CXX = g++10 +#CXX = clang++ +#CXXFLAGS = -fsanitize=address -O0 -g3 -gdwarf-2 -O0 -std=c++14 -I../ttmath -I../pikotools -Wl,-rpath=/usr/local/lib/gcc5/ -Wall -pedantic -Wextra +#CXXFLAGS = -O0 -g3 -gdwarf-2 -O0 -std=c++17 -I../ttmath -I../pikotools -Wl,-rpath=/usr/local/lib/gcc7/ -Wall -pedantic -Wextra +CXXFLAGS = -Wl,-rpath=/usr/local/lib/gcc10/ -O0 -g3 -std=c++20 -I../pikotools -Wall -pedantic + ifndef CXX CXX = clang++ @@ -16,61 +26,35 @@ ifndef AR AR = ar endif -#CXX=g++5 -#CXXFLAGS=-Wall -O0 -g3 -gdwarf-2 -std=c++14 -export CXX -export CXXFLAGS -export LDFLAGS -export AR +#export CXX +#export CXXFLAGS +#export LDFLAGS +#export AR -all: space mainparser mainspaceparser utf8 date convert log +libname = pikotools.a +all: $(libname) -space: FORCE - @cd space ; $(MAKE) -e - -mainparser: FORCE - @cd mainparser ; $(MAKE) -e - -mainspaceparser: FORCE - @cd mainspaceparser ; $(MAKE) -e - -utf8: FORCE - @cd utf8 ; $(MAKE) -e - -date: FORCE - @cd date ; $(MAKE) -e - -convert: FORCE - @cd convert ; $(MAKE) -e - -log: FORCE - @cd log ; $(MAKE) -e +$(libname): $(objfiles) + $(AR) rcs $(libname) $(objfiles) - - -FORCE: +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) -o $@ $< clean: - @cd space ; $(MAKE) -e clean - @cd mainparser ; $(MAKE) -e clean - @cd mainspaceparser ; $(MAKE) -e clean - @cd utf8 ; $(MAKE) -e clean - @cd date ; $(MAKE) -e clean - @cd convert ; $(MAKE) -e clean - @cd log ; $(MAKE) -e clean + rm -f $(objfiles) + rm -f $(libname) + depend: - @cd space ; $(MAKE) -e depend - @cd mainparser ; $(MAKE) -e depend - @cd mainspaceparser ; $(MAKE) -e depend - @cd utf8 ; $(MAKE) -e depend - @cd date ; $(MAKE) -e depend - @cd convert ; $(MAKE) -e depend - @cd log ; $(MAKE) -e depend + makedepend -Y. -f- $(sourcefiles) > Makefile.dep + + +-include Makefile.dep + diff --git a/Makefile.dep b/Makefile.dep new file mode 100644 index 0000000..891cd41 --- /dev/null +++ b/Makefile.dep @@ -0,0 +1,48 @@ +# DO NOT DELETE + +./convert/misc.o: ./convert/misc.h ./convert/text.h +./convert/text.o: ./convert/text.h +./convert/inttostr.o: ./convert/inttostr.h +./date/date.o: ./date/date.h convert/inttostr.h +./log/filelog.o: ./log/filelog.h textstream/textstream.h space/space.h +./log/filelog.o: textstream/types.h convert/inttostr.h date/date.h +./log/filelog.o: membuffer/membuffer.h textstream/types.h utf8/utf8.h +./log/filelog.o: utf8/utf8_templates.h utf8/utf8_private.h +./log/log.o: ./log/log.h textstream/textstream.h space/space.h +./log/log.o: textstream/types.h convert/inttostr.h date/date.h +./log/log.o: membuffer/membuffer.h textstream/types.h ./log/filelog.h +./log/log.o: utf8/utf8.h utf8/utf8_templates.h utf8/utf8_private.h +./mainspaceparser/mainspaceparser.o: ./mainspaceparser/mainspaceparser.h +./mainspaceparser/mainspaceparser.o: space/space.h textstream/types.h +./mainspaceparser/mainspaceparser.o: convert/inttostr.h utf8/utf8.h +./mainspaceparser/mainspaceparser.o: textstream/textstream.h date/date.h +./mainspaceparser/mainspaceparser.o: membuffer/membuffer.h textstream/types.h +./mainspaceparser/mainspaceparser.o: utf8/utf8_templates.h +./mainspaceparser/mainspaceparser.o: utf8/utf8_private.h +./space/jsontospaceparser.o: ./space/jsontospaceparser.h ./space/space.h +./space/jsontospaceparser.o: textstream/types.h convert/inttostr.h +./space/jsontospaceparser.o: utf8/utf8.h textstream/textstream.h +./space/jsontospaceparser.o: space/space.h date/date.h membuffer/membuffer.h +./space/jsontospaceparser.o: textstream/types.h utf8/utf8_templates.h +./space/jsontospaceparser.o: utf8/utf8_private.h convert/strtoint.h +./space/jsontospaceparser.o: ./convert/text.h ./convert/misc.h +./space/space.o: ./space/space.h textstream/types.h convert/inttostr.h +./space/space.o: utf8/utf8.h textstream/textstream.h space/space.h +./space/space.o: date/date.h membuffer/membuffer.h textstream/types.h +./space/space.o: utf8/utf8_templates.h utf8/utf8_private.h convert/convert.h +./space/space.o: ./convert/inttostr.h convert/patternreplacer.h +./space/space.o: convert/strtoint.h ./convert/text.h ./convert/misc.h +./space/spaceparser.o: ./space/spaceparser.h ./space/space.h +./space/spaceparser.o: textstream/types.h convert/inttostr.h utf8/utf8.h +./space/spaceparser.o: textstream/textstream.h space/space.h date/date.h +./space/spaceparser.o: membuffer/membuffer.h textstream/types.h +./space/spaceparser.o: utf8/utf8_templates.h utf8/utf8_private.h +./space/spacetojson.o: ./space/spacetojson.h ./space/space.h +./space/spacetojson.o: textstream/types.h convert/inttostr.h +./utf8/utf8.o: ./utf8/utf8.h textstream/textstream.h space/space.h +./utf8/utf8.o: textstream/types.h convert/inttostr.h date/date.h +./utf8/utf8.o: membuffer/membuffer.h textstream/types.h utf8/utf8_templates.h +./utf8/utf8.o: utf8/utf8_private.h +./utf8/utf8_private.o: utf8/utf8_private.h textstream/textstream.h +./utf8/utf8_private.o: space/space.h textstream/types.h convert/inttostr.h +./utf8/utf8_private.o: date/date.h membuffer/membuffer.h textstream/types.h diff --git a/convert/Makefile b/convert/Makefile deleted file mode 100644 index 3b74c9f..0000000 --- a/convert/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include Makefile.o.dep - -libname=convert.a - -all: $(libname) - -$(libname): $(o) - $(AR) rcs $(libname) $(o) - - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) -I.. $< - - - -depend: - makedepend -Y. -I.. -f- *.cpp > Makefile.dep - echo -n "o = " > Makefile.o.dep - ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep - - -clean: - rm -f *.o - rm -f $(libname) - - -include Makefile.dep diff --git a/convert/Makefile.dep b/convert/Makefile.dep deleted file mode 100644 index 35b219c..0000000 --- a/convert/Makefile.dep +++ /dev/null @@ -1,5 +0,0 @@ -# DO NOT DELETE - -inttostr.o: inttostr.h -misc.o: misc.h text.h -text.o: text.h diff --git a/convert/Makefile.o.dep b/convert/Makefile.o.dep deleted file mode 100644 index 70b7e42..0000000 --- a/convert/Makefile.o.dep +++ /dev/null @@ -1 +0,0 @@ -o = inttostr.o misc.o text.o \ No newline at end of file diff --git a/date/Makefile b/date/Makefile deleted file mode 100644 index a17267b..0000000 --- a/date/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include Makefile.o.dep - -libname=date.a - -all: $(libname) - -$(libname): $(o) - $(AR) rcs $(libname) $(o) - - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) -I.. $< - - - -depend: - makedepend -Y. -I.. -f- *.cpp > Makefile.dep - echo -n "o = " > Makefile.o.dep - ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep - - -clean: - rm -f *.o - rm -f $(libname) - - -include Makefile.dep diff --git a/date/Makefile.dep b/date/Makefile.dep deleted file mode 100644 index 4b933e3..0000000 --- a/date/Makefile.dep +++ /dev/null @@ -1,3 +0,0 @@ -# DO NOT DELETE - -date.o: date.h ../convert/inttostr.h diff --git a/date/Makefile.o.dep b/date/Makefile.o.dep deleted file mode 100644 index 1e1c891..0000000 --- a/date/Makefile.o.dep +++ /dev/null @@ -1 +0,0 @@ -o = date.o \ No newline at end of file diff --git a/log/Makefile b/log/Makefile deleted file mode 100644 index bed6eba..0000000 --- a/log/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include Makefile.o.dep - -libname=log.a - -all: $(libname) - -$(libname): $(o) - $(AR) rcs $(libname) $(o) - - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) -I.. $< - - - -depend: - makedepend -Y. -I.. -f- *.cpp > Makefile.dep - echo -n "o = " > Makefile.o.dep - ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep - - -clean: - rm -f *.o - rm -f $(libname) - - -include Makefile.dep diff --git a/log/Makefile.dep b/log/Makefile.dep deleted file mode 100644 index a409558..0000000 --- a/log/Makefile.dep +++ /dev/null @@ -1,10 +0,0 @@ -# DO NOT DELETE - -filelog.o: filelog.h ../textstream/textstream.h ../space/space.h -filelog.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h -filelog.o: ../membuffer/membuffer.h ../textstream/types.h ../utf8/utf8.h -filelog.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h -log.o: log.h ../textstream/textstream.h ../space/space.h -log.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h -log.o: ../membuffer/membuffer.h ../textstream/types.h filelog.h -log.o: ../utf8/utf8.h ../utf8/utf8_templates.h ../utf8/utf8_private.h diff --git a/log/Makefile.o.dep b/log/Makefile.o.dep deleted file mode 100644 index 3eff2ad..0000000 --- a/log/Makefile.o.dep +++ /dev/null @@ -1 +0,0 @@ -o = filelog.o log.o \ No newline at end of file diff --git a/mainparser/Makefile b/mainparser/Makefile deleted file mode 100644 index a451264..0000000 --- a/mainparser/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include Makefile.o.dep - -libname=mainparser.a - -all: $(libname) - -$(libname): $(o) - $(AR) rcs $(libname) $(o) - - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) -I.. $< - - - -depend: - makedepend -Y. -I.. -f- *.cpp > Makefile.dep - echo -n "o = " > Makefile.o.dep - ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep - - -clean: - rm -f *.o - rm -f $(libname) - - -include Makefile.dep diff --git a/mainparser/Makefile.dep b/mainparser/Makefile.dep deleted file mode 100644 index ad09e57..0000000 --- a/mainparser/Makefile.dep +++ /dev/null @@ -1,3 +0,0 @@ -# DO NOT DELETE - -mainparser.o: mainparser.h diff --git a/mainparser/Makefile.o.dep b/mainparser/Makefile.o.dep deleted file mode 100644 index 0a6c3a7..0000000 --- a/mainparser/Makefile.o.dep +++ /dev/null @@ -1 +0,0 @@ -o = mainparser.o \ No newline at end of file diff --git a/mainparser/mainparser.cpp b/mainparser/mainparser.cpp deleted file mode 100644 index 6a67449..0000000 --- a/mainparser/mainparser.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * This file is a part of PikoTools - * and is distributed under the (new) BSD licence. - * Author: Tomasz Sowa - */ - -/* - * Copyright (c) 2011-2012, Tomasz Sowa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name Tomasz Sowa nor the names of contributors to this - * project may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "mainparser.h" -#include - - -namespace PT -{ - - -MainParser::MainParser() -{ - argsize = 0; - arg = 0; - Reset(); -} - - - -MainParser::MainParser(int argc, const char ** argv) -{ - Set(argc, argv); - Reset(); -} - - - -void MainParser::Set(int argc, const char ** argv) -{ - argsize = argc; - arg = argv; - Reset(); -} - - - -void MainParser::Reset() -{ - argindex = 1; - offset = 0; - has_single_param = false; - has_double_param = false; -} - - - -char MainParser::GetSingleParam() -{ - if( !has_single_param ) - return 0; - - if( last_single_param != 0 ) - return last_single_param; - - Advance(); - - if( argindex >= argsize ) - return 0; - - last_single_param = arg[argindex][offset]; - offset += 1; - -return last_single_param; -} - - - -bool MainParser::IsSingleParam(char c) -{ - return GetSingleParam() == c; -} - - -const char * MainParser::GetDoubleParam() -{ - empty = 0; - - if( !has_double_param ) - return ∅ - - if( last_double_param != &empty ) - return last_double_param; - - Advance(); - - if( argindex >= argsize ) - return ∅ - - last_double_param = &arg[argindex][offset]; - offset = 0; - argindex += 1; - -return last_double_param; -} - - -bool MainParser::IsDoubleParam(const char * param) -{ - return strcmp(GetDoubleParam(), param) == 0; -} - - -const char * MainParser::GetValue() -{ - empty = 0; - Advance(); - - if( argindex >= argsize ) - return ∅ - - const char * value = &arg[argindex][offset]; - offset = 0; - argindex += 1; - has_single_param = false; - has_double_param = false; - -return value; -} - - - -bool MainParser::NextParam() -{ - bool was_single_param = has_single_param; - has_single_param = false; - has_double_param = false; - last_single_param = 0; - last_double_param = ∅ - empty = 0; - - if( Advance() ) - was_single_param = false; - - if( argindex >= argsize ) - return false; - - if( arg[argindex][offset]=='-' ) - { - if( arg[argindex][offset+1]=='-' ) - { - has_double_param = true; - offset += 2; - } - else - { - has_single_param = true; - offset += 1; - } - } - else - { - if( was_single_param ) - has_single_param = true; - } - -return has_single_param || has_double_param; -} - - - -bool MainParser::IsEnd() -{ - Advance(); - -return argindex >= argsize; -} - - - -bool MainParser::HasSingleParam() -{ - return has_single_param; -} - - - -bool MainParser::HasDoubleParam() -{ - return has_double_param; -} - - - -bool MainParser::Advance() -{ -bool was_incremented = false; - - while( argindex < argsize && arg[argindex][offset] == 0 ) - { - offset = 0; - argindex += 1; - was_incremented = true; - } - -return was_incremented; -} - - -} // namespace - - diff --git a/mainparser/mainparser.h b/mainparser/mainparser.h deleted file mode 100644 index 248f22a..0000000 --- a/mainparser/mainparser.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is a part of PikoTools - * and is distributed under the (new) BSD licence. - * Author: Tomasz Sowa - */ - -/* - * Copyright (c) 2011-2012, Tomasz Sowa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name Tomasz Sowa nor the names of contributors to this - * project may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef headerfile_picotools_mainparser_mainparser -#define headerfile_picotools_mainparser_mainparser - - -namespace PT -{ - - -/* - a very little parser for main(int argc, char ** argv) parameters - look in sample/sample.cpp how to use the parser -*/ -class MainParser -{ -public: - - MainParser(); - MainParser(int argc, const char ** argv); - - // setting arguments passed to main(int argc, char ** argv) function - void Set(int argc, const char ** argv); - - // reseting the current state of parsing - // now you can start parsing from the beginning - // you don't have to call it for the first time - // (is automatically called by the Set method) - void Reset(); - - // checking if there is a next single or double parameter - // this method represents the main loop of checking parameters - bool NextParam(); - - // returning a single parameter (if exists) or '\0' otherwise - // single parameter means a parameter with '-' at the beginning e.g. "-a" - // next call to this method (without calling NextParam) returns the same value - // this method should be called after NextParam() - char GetSingleParam(); - - // calling GetSingleParam() and comparign with 'c' - bool IsSingleParam(char c); - - // returning a string for a double parameter or an empty string if there is no such a parameter - // double parameter means a parameter with '--' at the beginning e.g. "--output" - // next call to this method (without calling NextParam) returns the same value - // GetDoubleParam() should be called after NextParam() - // this method never returns a null pointer -- if there is no a param name (end of the string) - // a pointer to en empty string will be returned - const char * GetDoubleParam(); - - // calling GetDoubleParam() and comparing with 'param' - // so you don't have to call strcmp directly - bool IsDoubleParam(const char * param); - - // returning a string representing a value - // you have to know which parameter requires a value - // and if such a parameter is found then use this method to obtain the value - // the method advances the current pointer so next call to this method return a next value - // you can call GetValue() even when NextParam() has returned false - // in such a case this gets you the last values (those at the end of the parameter list) - // this method never returns a null pointer -- if there is no a value (end of the string) - // a pointer to en empty string will be returned - const char * GetValue(); - - // returning true if the input string is finished - // there are no more parameters or values - bool IsEnd(); - - // returning true if there is a single parameter - // should be called after NextParam() - bool HasSingleParam(); - - // returning true if there is a double parameter - // should be called after NextParam() - bool HasDoubleParam(); - -private: - - bool Advance(); - - int argindex; - int offset; - int argsize; - const char ** arg; - char empty; - bool has_single_param; - bool has_double_param; - char last_single_param; - const char * last_double_param; -}; - - -} // namespace - - -#endif diff --git a/mainparser/sample/Makefile b/mainparser/sample/Makefile deleted file mode 100644 index 81942f4..0000000 --- a/mainparser/sample/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -output=sample - -all: $(output) - -$(output): sample.cpp ../mainparser.h ../mainparser.cpp - g++ -o $(output) sample.cpp ../mainparser.cpp - -clean: - rm -f $(output) - rm -f $(output).exe diff --git a/mainparser/sample/sample.cpp b/mainparser/sample/sample.cpp deleted file mode 100644 index 17f38ce..0000000 --- a/mainparser/sample/sample.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is a part of MainParser -- simple parser for main() parameters - * and is distributed under the (new) BSD licence. - * Author: Tomasz Sowa - */ - -/* - * Copyright (c) 2011, Tomasz Sowa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name Tomasz Sowa nor the names of contributors to this - * project may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - - - -#include -#include -#include "../mainparser.h" - - -int main() -{ -MainParser mp; - - // suppose you call a 'programname' in such a way: - // $ programname -a -b - c --longparam -- otherlongparam -xyz paramwithvalue -x --longparam2 longwithvalue lastvalue1 lastvalue2 lastvalue3 - // so the main() function get this table as input: - - const char * tab[] = { - "programname", - "-a", - "-b", - "-", - "c", - "--longparam", - "--", - "otherlongparam", - "-xyz", - "paramwithvalue", - "-x", - "--longparam2", - "longwithvalue", - "lastvalue1", // some values left at the end - "lastvalue2", // you can get them by using GetValue() method - "lastvalue3", - }; - - mp.Set(sizeof(tab)/sizeof(const char*), tab); - - while( mp.NextParam() ) - { - if( mp.GetSingleParam() != 0 ) - { - std::cout << "-" << mp.GetSingleParam() << std::endl; - - // we know that 'z' requires a value - if( mp.GetSingleParam() == 'z' ) - std::cout << "value for z: " << mp.GetValue() << std::endl; - } - - if( *mp.GetDoubleParam() ) - { - std::cout << "--" << mp.GetDoubleParam() << std::endl; - - // we know that "longparam2" requires a value - if( strcmp(mp.GetDoubleParam(), "longparam2") == 0 ) - std::cout << "value for longparam2: " << mp.GetValue() << std::endl; - } - } - - while( !mp.IsEnd() ) - std::cout << mp.GetValue() << std::endl; -} - -/* -program output: - --a --b --c ---longparam ---otherlongparam --x --y --z -value for z: paramwithvalue --x ---longparam2 -value for longparam2: longwithvalue -lastvalue1 -lastvalue2 -lastvalue3 -*/ diff --git a/mainspaceparser/Makefile b/mainspaceparser/Makefile deleted file mode 100644 index 5e52fc0..0000000 --- a/mainspaceparser/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include Makefile.o.dep - -libname=mainspaceparser.a - -all: $(libname) - -$(libname): $(o) - $(AR) rcs $(libname) $(o) - - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) -I.. $< - - - -depend: - makedepend -Y. -I.. -f- *.cpp > Makefile.dep - echo -n "o = " > Makefile.o.dep - ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep - - -clean: - rm -f *.o - rm -f $(libname) - - -include Makefile.dep diff --git a/mainspaceparser/Makefile.dep b/mainspaceparser/Makefile.dep deleted file mode 100644 index 733d32a..0000000 --- a/mainspaceparser/Makefile.dep +++ /dev/null @@ -1,7 +0,0 @@ -# DO NOT DELETE - -mainspaceparser.o: mainspaceparser.h ../space/space.h ../textstream/types.h -mainspaceparser.o: ../convert/inttostr.h ../utf8/utf8.h -mainspaceparser.o: ../textstream/textstream.h ../date/date.h -mainspaceparser.o: ../membuffer/membuffer.h ../textstream/types.h -mainspaceparser.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h diff --git a/mainspaceparser/Makefile.o.dep b/mainspaceparser/Makefile.o.dep deleted file mode 100644 index 029147f..0000000 --- a/mainspaceparser/Makefile.o.dep +++ /dev/null @@ -1 +0,0 @@ -o = mainspaceparser.o \ No newline at end of file diff --git a/space/Makefile b/space/Makefile deleted file mode 100644 index fc2ffe6..0000000 --- a/space/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include Makefile.o.dep - -libname=space.a - -all: $(libname) - -$(libname): $(o) - $(AR) rcs $(libname) $(o) - - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) -I.. $< - - - -depend: - makedepend -Y. -I.. -f- *.cpp > Makefile.dep - echo -n "o = " > Makefile.o.dep - ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep - - -clean: - rm -f *.o - rm -f $(libname) - - -include Makefile.dep diff --git a/space/Makefile.dep b/space/Makefile.dep deleted file mode 100644 index 0c75896..0000000 --- a/space/Makefile.dep +++ /dev/null @@ -1,27 +0,0 @@ -# DO NOT DELETE - -jsontospaceparser.o: jsontospaceparser.h space.h ../textstream/types.h -jsontospaceparser.o: ../convert/inttostr.h ../utf8/utf8.h -jsontospaceparser.o: ../textstream/textstream.h ../space/space.h -jsontospaceparser.o: ../date/date.h ../membuffer/membuffer.h -jsontospaceparser.o: ../textstream/types.h ../utf8/utf8_templates.h -jsontospaceparser.o: ../utf8/utf8_private.h ../convert/strtoint.h -jsontospaceparser.o: ../convert/text.h ../convert/misc.h -main.o: space.h ../textstream/types.h ../convert/inttostr.h ../utf8/utf8.h -main.o: ../textstream/textstream.h ../space/space.h ../date/date.h -main.o: ../membuffer/membuffer.h ../textstream/types.h -main.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h -main.o: ../space/jsontospaceparser.h -space.o: space.h ../textstream/types.h ../convert/inttostr.h ../utf8/utf8.h -space.o: ../textstream/textstream.h ../space/space.h ../date/date.h -space.o: ../membuffer/membuffer.h ../textstream/types.h -space.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h ../convert/convert.h -space.o: ../convert/inttostr.h ../convert/patternreplacer.h -space.o: ../convert/strtoint.h ../convert/text.h ../convert/misc.h -spaceparser.o: spaceparser.h space.h ../textstream/types.h -spaceparser.o: ../convert/inttostr.h ../utf8/utf8.h -spaceparser.o: ../textstream/textstream.h ../space/space.h ../date/date.h -spaceparser.o: ../membuffer/membuffer.h ../textstream/types.h -spaceparser.o: ../utf8/utf8_templates.h ../utf8/utf8_private.h -spacetojson.o: spacetojson.h space.h ../textstream/types.h -spacetojson.o: ../convert/inttostr.h diff --git a/space/Makefile.o.dep b/space/Makefile.o.dep deleted file mode 100644 index 0b7ca32..0000000 --- a/space/Makefile.o.dep +++ /dev/null @@ -1 +0,0 @@ -o = jsontospaceparser.o main.o space.o spaceparser.o spacetojson.o \ No newline at end of file diff --git a/utf8/Makefile b/utf8/Makefile deleted file mode 100644 index 33c71a6..0000000 --- a/utf8/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include Makefile.o.dep - -libname=utf8.a - -all: $(libname) - -$(libname): $(o) - $(AR) rcs $(libname) $(o) - - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) -I.. $< - - - -depend: - makedepend -Y. -I.. -f- *.cpp > Makefile.dep - echo -n "o = " > Makefile.o.dep - ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep - - -clean: - rm -f *.o - rm -f $(libname) - - -include Makefile.dep diff --git a/utf8/Makefile.dep b/utf8/Makefile.dep deleted file mode 100644 index 3808a63..0000000 --- a/utf8/Makefile.dep +++ /dev/null @@ -1,9 +0,0 @@ -# DO NOT DELETE - -utf8_private.o: utf8_private.h ../textstream/textstream.h ../space/space.h -utf8_private.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h -utf8_private.o: ../membuffer/membuffer.h ../textstream/types.h -utf8.o: utf8.h ../textstream/textstream.h ../space/space.h -utf8.o: ../textstream/types.h ../convert/inttostr.h ../date/date.h -utf8.o: ../membuffer/membuffer.h ../textstream/types.h -utf8.o: ../utf8/utf8_templates.h utf8_private.h diff --git a/utf8/Makefile.o.dep b/utf8/Makefile.o.dep deleted file mode 100644 index b58ce53..0000000 --- a/utf8/Makefile.o.dep +++ /dev/null @@ -1 +0,0 @@ -o = utf8_private.o utf8.o \ No newline at end of file From 31f7bdb85789bfb04e8e0cd7af1e9468d6b7fe69 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 17 Mar 2021 18:09:47 +0100 Subject: [PATCH 13/67] added to Space: child_spaces and a name of a Space --- space/space.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++++-- space/space.h | 13 ++++++ 2 files changed, 121 insertions(+), 3 deletions(-) diff --git a/space/space.cpp b/space/space.cpp index 584c1b4..a0ca225 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -50,17 +50,19 @@ namespace PT Space::Space() { type = type_null; + child_spaces = nullptr; + name = nullptr; } Space::Space(const Space & space) { - copy_value_from(space); + copy_from(space); } Space & Space::operator=(const Space & space) { - copy_value_from(space); + copy_from(space); return *this; } @@ -68,6 +70,8 @@ Space & Space::operator=(const Space & space) Space::~Space() { remove_value(); + remove_child_spaces(); + remove_space_name(); } @@ -298,7 +302,7 @@ void Space::set(const Space * space) } else { - copy_value_from(*space); + copy_from(*space); } } @@ -472,6 +476,19 @@ Space & Space::add_empty_space(const wchar_t * field) return add_generic(field, static_cast(nullptr)); } +Space & Space::add_child_space(const wchar_t * space_name) +{ + initialize_child_spaces_if_needed(); + + child_spaces->push_back(new Space()); + Space * last_space = child_spaces->back(); + + last_space->initialize_space_name_if_needed(); + last_space->name->append(space_name); + + return *last_space; +} + bool Space::is_null() const @@ -947,6 +964,50 @@ void Space::copy_value_from(const Space & space) } +void Space::copy_child_spaces_from(const Space & space) +{ + if( space.child_spaces ) + { + initialize_child_spaces_if_needed(); + child_spaces->clear(); + + for(size_t i = 0 ; i < space.child_spaces->size() ; ++i) + { + child_spaces->push_back(new Space((*space.child_spaces)[i])); + } + } + else + if( child_spaces ) + { + remove_child_spaces(); + } +} + + +void Space::copy_space_name_from(const Space & space) +{ + if( space.name ) + { + initialize_space_name_if_needed(); + *name = *space.name; + } + else + if( name ) + { + remove_space_name(); + } +} + + +void Space::copy_from(const Space & space) +{ + copy_value_from(space); + copy_child_spaces_from(space); + copy_space_name_from(space); +} + + + void Space::copy_value_object(const Value & value_from) @@ -1074,6 +1135,25 @@ void Space::initialize_value_table_if_needed() } +void Space::initialize_child_spaces_if_needed() +{ + if( child_spaces == nullptr ) + { + child_spaces = new TableType(); + } +} + + +void Space::initialize_space_name_if_needed() +{ + if( name == nullptr ) + { + name = new std::wstring(); + } +} + + + void Space::remove_value() { switch(type) @@ -1153,6 +1233,31 @@ void Space::remove_value_table() } +void Space::remove_child_spaces() +{ + if( child_spaces ) + { + for(size_t i = 0 ; i < child_spaces->size() ; ++i) + { + delete (*child_spaces)[i]; + (*child_spaces)[i] = nullptr; + } + + delete child_spaces; + child_spaces = nullptr; + } +} + +void Space::remove_space_name() +{ + if( name ) + { + delete name; + name = nullptr; + } +} + + } // namespace diff --git a/space/space.h b/space/space.h index 5f5052b..340813d 100644 --- a/space/space.h +++ b/space/space.h @@ -178,6 +178,9 @@ public: Type type; Value value; + std::wstring * name; + TableType * child_spaces; + Space(); @@ -269,6 +272,8 @@ public: Space & add_empty_space(const wchar_t * field); // IMPROVEME rename me to something better + Space & add_child_space(const wchar_t * space_name); + bool is_null() const; bool is_bool() const; @@ -745,6 +750,10 @@ protected: void copy_value_from(const Space & space); + void copy_child_spaces_from(const Space & space); + void copy_space_name_from(const Space & space); + void copy_from(const Space & space); + void copy_value_object(const Value & value_from); void copy_value_table(const Value & value_from); @@ -757,12 +766,16 @@ protected: void initialize_value_wstring_if_needed(); void initialize_value_object_if_needed(); void initialize_value_table_if_needed(); + void initialize_child_spaces_if_needed(); + void initialize_space_name_if_needed(); void remove_value(); void remove_value_string(); void remove_value_wstring(); void remove_value_object(); void remove_value_table(); + void remove_child_spaces(); + void remove_space_name(); }; From 6e169f7650758eb6609accbe9a27b282903d21a9 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 17 Mar 2021 18:24:50 +0100 Subject: [PATCH 14/67] added to JSONToSpaceParser: possibility to parse the Space format renamed: ParseFile() -> ParseJSONFile() added: ParseSpaceFile(), ParseJSON(), ParseSpace() --- space/jsontospaceparser.cpp | 397 +++++++++++++++++++++++++++++------- space/jsontospaceparser.h | 72 ++++--- 2 files changed, 360 insertions(+), 109 deletions(-) diff --git a/space/jsontospaceparser.cpp b/space/jsontospaceparser.cpp index a88fe8e..8881a86 100644 --- a/space/jsontospaceparser.cpp +++ b/space/jsontospaceparser.cpp @@ -81,7 +81,6 @@ void JSONToSpaceParser::SetDefault() skip_empty = false; use_escape_char = true; input_as_utf8 = true; - max_nested_level = 1000; } @@ -111,9 +110,10 @@ int JSONToSpaceParser::get_last_parsed_line() -JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const char * file_name) +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const char * file_name) { reading_from_file = true; + parsing_space = false; file.clear(); file.open(file_name, std::ios_base::binary | std::ios_base::in); @@ -133,35 +133,88 @@ return status; -JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const std::string & file_name) +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const std::string & file_name) { - return ParseFile(file_name.c_str()); + return ParseJSONFile(file_name.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const wchar_t * file_name) +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const wchar_t * file_name) { - PT::WideToUTF8(file_name, afile_name); - return ParseFile(afile_name.c_str()); + std::string file_name_utf8; + + PT::WideToUTF8(file_name, file_name_utf8); + return ParseJSONFile(file_name_utf8.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::ParseFile(const std::wstring & file_name) +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const std::wstring & file_name) { - return ParseFile(file_name.c_str()); + return ParseJSONFile(file_name.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const char * str) + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const char * file_name) +{ + reading_from_file = true; + parsing_space = true; + + file.clear(); + file.open(file_name, std::ios_base::binary | std::ios_base::in); + + if( file ) + { + ParseRootSpace(); + file.close(); + } + else + { + status = cant_open_file; + } + +return status; +} + + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const std::string & file_name) +{ + return ParseSpaceFile(file_name.c_str()); +} + + + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const wchar_t * file_name) +{ + std::string file_name_utf8; + + PT::WideToUTF8(file_name, file_name_utf8); + return ParseSpaceFile(file_name_utf8.c_str()); +} + + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const std::wstring & file_name) +{ + return ParseSpaceFile(file_name.c_str()); +} + + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const char * str) { reading_from_file = false; reading_from_wchar_string = false; pchar_ascii = str; pchar_unicode = 0; + parsing_space = false; ParseRootSpace(); @@ -169,18 +222,19 @@ return status; } -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const std::string & str) +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const std::string & str) { - return Parse(str.c_str()); + return ParseJSON(str.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const wchar_t * str) +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const wchar_t * str) { reading_from_file = false; reading_from_wchar_string = true; pchar_unicode = str; pchar_ascii = 0; + parsing_space = false; ParseRootSpace(); @@ -188,19 +242,63 @@ return status; } -JSONToSpaceParser::Status JSONToSpaceParser::Parse(const std::wstring & str) +JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const std::wstring & str) { - return Parse(str.c_str()); + return ParseJSON(str.c_str()); } + + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const char * str) +{ + reading_from_file = false; + reading_from_wchar_string = false; + pchar_ascii = str; + pchar_unicode = 0; + parsing_space = true; + + ParseRootSpace(); + +return status; +} + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const std::string & str) +{ + return ParseSpace(str.c_str()); +} + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const wchar_t * str) +{ + reading_from_file = false; + reading_from_wchar_string = true; + pchar_unicode = str; + pchar_ascii = 0; + parsing_space = true; + + ParseRootSpace(); + +return status; +} + + +JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const std::wstring & str) +{ + return ParseSpace(str.c_str()); +} + + + + + void JSONToSpaceParser::ParseRootSpace() { line = 1; status = ok; skipped = 0; - current_nested_level = 0; - parsing_space = false; if( !root_space ) { @@ -209,12 +307,27 @@ void JSONToSpaceParser::ParseRootSpace() } ReadChar(); // put first character to lastc - Parse(root_space); + + if( parsing_space ) + { + separator = '='; + table_start = '('; + table_end = ')'; + ParseSpace(root_space); + } + else + { + separator = ':'; + table_start = '['; + table_end = ']'; + Parse(root_space, false, false); + } + token.clear(); } -void JSONToSpaceParser::Parse(Space * space) +void JSONToSpaceParser::Parse(Space * space, bool is_object_value, bool is_table_value) { SkipWhite(); @@ -234,7 +347,7 @@ void JSONToSpaceParser::Parse(Space * space) } else { - ReadAlfaNumericToken(); + ReadStringValue(token, is_object_value, is_table_value); if( token == L"null" ) { @@ -262,7 +375,14 @@ void JSONToSpaceParser::Parse(Space * space) } else { - status = syntax_error; + if( parsing_space ) + { + space->set(token); + } + else + { + status = syntax_error; + } } } } @@ -273,28 +393,30 @@ void JSONToSpaceParser::Parse(Space * space) void JSONToSpaceParser::ParseSpace(Space * space) { - current_nested_level += 1; + /* + * in Space format in global namespace the space start character is not required + */ + bool need_space_start_character = !parsing_space || space != root_space; -// if( current_nested_level > max_nested_level ) -// { -// status = max_nested_spaces_exceeded; -// return; -// } + if( need_space_start_character ) + { + ReadChar(); // inserting a next character after the space_start char to lastc + } - ReadChar(); // inserting a next character after the space_start char to lastc space->set_empty_object(); ParseKeyValuePairs(space); - if( lastc == space_end ) + if( need_space_start_character ) { - ReadChar(); + if( lastc == space_end ) + { + ReadChar(); + } + else + { + status = syntax_error; + } } - else - { - status = syntax_error; - } - - current_nested_level -= 1; } @@ -303,25 +425,13 @@ void JSONToSpaceParser::ParseSpace(Space * space) void JSONToSpaceParser::ParseTextValue(Space * space) { - ReadChar(); // inserting a next character after the ... char to lastc space->set_empty_wstring(); std::wstring * str = space->get_wstring(); - // IMPROVEME add support for escaped characters - while( status == ok && lastc != '"' && lastc != -1 ) - { - str->push_back(static_cast(lastc)); - ReadChar(); - } - - if( lastc == '"' ) - { - ReadChar(); - } + if( parsing_space ) + ReadMultilineTokenQuoted(*str); else - { - status = syntax_error; - } + ReadTokenQuoted(*str); } @@ -375,8 +485,9 @@ void JSONToSpaceParser::ParseTable(Space * space) { space->set_empty_table(); + ReadChar(); // inserting a next character after the table_start char to lastc - space->set_empty_object(); + space->set_empty_table(); ParseValuesList(space); if( lastc == table_end ) @@ -406,18 +517,29 @@ void JSONToSpaceParser::ParseKeyValuePairs(Space * space) if( lastc == option_delimiter ) { ReadChar(); // inserting a next character after the option_delimiter to lastc + + if( parsing_space ) + { + // in space format a space_end character is allowed to be after the last table item + SkipWhite(); + + if( lastc == space_end ) + break; + } } else + if( !parsing_space ) { + // in json format the option_delimiter is required status = syntax_error; } } if( status == ok ) { - Space * new_key_space = ReadKey(space); + ReadKey(); - if( status == ok && new_key_space ) + if( status == ok ) { SkipWhite(); @@ -425,9 +547,14 @@ void JSONToSpaceParser::ParseKeyValuePairs(Space * space) { ReadChar(); // inserting a next character after the separator to lastc - Parse(new_key_space); - //value.clear(); - //ReadValue(false, false, true, true); + Space & new_space = space->add(token.c_str(), new Space()); + Parse(&new_space, true, false); + } + else + if( parsing_space && lastc == space_start ) + { + Space & new_space = space->add_child_space(token.c_str()); + ParseSpace(&new_space); } else { @@ -458,9 +585,20 @@ void JSONToSpaceParser::ParseValuesList(Space * space) if( lastc == option_delimiter ) // may add a new delimiter for tables? default the same as for objects... { ReadChar(); // inserting a next character after the delimiter + + if( parsing_space ) + { + // in space format a table_end character is allowed to be after the last table item + SkipWhite(); + + if( lastc == table_end ) + break; + } } else + if( !parsing_space ) { + // in json format the option_delimiter is required status = syntax_error; } } @@ -468,7 +606,7 @@ void JSONToSpaceParser::ParseValuesList(Space * space) if( status == ok ) { Space * new_space = &space->add(new Space()); - Parse(new_space); + Parse(new_space, false, true); } is_first = false; @@ -589,12 +727,47 @@ bool JSONToSpaceParser::is_alfa_numeric_char(int c) } +void JSONToSpaceParser::SkipLine() +{ + while( lastc != -1 && (char_was_escaped || lastc != '\n') ) + ReadChar(); +} + + void JSONToSpaceParser::SkipWhite() { - while( IsWhite(lastc) ) + if( parsing_space ) { - ReadChar(); + while( IsWhite(lastc) || lastc == '#' ) + { + if( lastc == '#' ) + SkipLine(); + else + ReadChar(); + } + } + else + { + while( IsWhite(lastc) ) + { + ReadChar(); + } + } +} + + +void JSONToSpaceParser::TrimLastWhite(std::wstring & s) +{ + std::wstring::size_type i; + + for(i=s.size() ; i>0 && IsWhite(s[i-1]) ; --i) + { + } + + if( i < s.size() ) + { + s.erase(i, std::wstring::npos); } } @@ -631,11 +804,21 @@ std::wstring::size_type i; */ +void JSONToSpaceParser::ReadTokenUntilDelimiter(std::wstring & token, int delimiter1, int delimiter2) +{ + token.clear(); + + while( lastc != -1 && lastc != '\n' && lastc != '#' && lastc != delimiter1 && lastc != delimiter2 ) + { + token += static_cast(lastc); + ReadChar(); + } + + TrimLastWhite(token); +} - - -void JSONToSpaceParser::ReadAlfaNumericToken() +void JSONToSpaceParser::ReadAlfaNumericToken(std::wstring & token) { token.clear(); @@ -646,8 +829,71 @@ void JSONToSpaceParser::ReadAlfaNumericToken() } } + +void JSONToSpaceParser::ReadStringValue(std::wstring & token, bool is_object_value, bool is_table_value) +{ + if( parsing_space ) + { + if( is_object_value ) + { + ReadTokenUntilDelimiter(token, space_end, -1); + } + else + if( is_table_value ) + { + ReadTokenUntilDelimiter(token, table_end, option_delimiter); + } + else + { + ReadTokenUntilDelimiter(token, -1, -1); + } + } + else + { + ReadAlfaNumericToken(token); + } +} + + +// rename to something like ReadSpaceFieldToken??? +void JSONToSpaceParser::ReadSpaceFieldToken(std::wstring & token) +{ + token.clear(); + + while( lastc != -1 && (char_was_escaped || (lastc != separator && lastc != 10 && lastc != space_start)) ) + { + token += static_cast(lastc); + ReadChar(); + } + + TrimLastWhite(token); +} + + // IMPROVEME in JSON we should not allow non-escaped a new line character -void JSONToSpaceParser::ReadTokenQuoted() +void JSONToSpaceParser::ReadTokenQuoted(std::wstring & token) +{ + token.clear(); + ReadChar(); // skipping the first quotation mark + + while( lastc != -1 && (char_was_escaped || (lastc != '"' && lastc != 10)) ) + { + token += static_cast(lastc); + ReadChar(); + } + + if( !char_was_escaped && lastc == '"' ) + { + ReadChar(); // skipping the last quotation mark + } + else + { + status = syntax_error; + } +} + + +void JSONToSpaceParser::ReadMultilineTokenQuoted(std::wstring & token) { token.clear(); ReadChar(); // skipping the first quotation mark @@ -670,35 +916,32 @@ void JSONToSpaceParser::ReadTokenQuoted() - - -Space * JSONToSpaceParser::ReadKey(Space * space) +void JSONToSpaceParser::ReadKey() { SkipWhite(); if( parsing_space ) { - // IMPROVEME implement me + if( lastc == '"' ) + { + ReadMultilineTokenQuoted(token); + } + else + { + ReadSpaceFieldToken(token); + } } else { if( lastc == '"' ) { - ReadTokenQuoted(); + ReadTokenQuoted(token); } else { status = syntax_error; } } - - if( status == ok ) - { - Space * new_space = new Space(); - return &space->add(token.c_str(), new_space); - } - - return nullptr; } diff --git a/space/jsontospaceparser.h b/space/jsontospaceparser.h index 16a4390..cea2f51 100644 --- a/space/jsontospaceparser.h +++ b/space/jsontospaceparser.h @@ -77,7 +77,7 @@ public: /* status of parsing */ - enum Status { ok, cant_open_file, syntax_error, max_nested_spaces_exceeded, no_space }; + enum Status { ok, cant_open_file, syntax_error, no_space }; /* @@ -96,29 +96,47 @@ public: /* - main methods used to parse + main methods used to parse a JSON file file_name is the path to a file */ - Status ParseFile(const char * file_name); - Status ParseFile(const std::string & file_name); - Status ParseFile(const wchar_t * file_name); - Status ParseFile(const std::wstring & file_name); + Status ParseJSONFile(const char * file_name); + Status ParseJSONFile(const std::string & file_name); + Status ParseJSONFile(const wchar_t * file_name); + Status ParseJSONFile(const std::wstring & file_name); + + + /* + main methods used to parse a Space file + file_name is the path to a file + */ + Status ParseSpaceFile(const char * file_name); + Status ParseSpaceFile(const std::string & file_name); + Status ParseSpaceFile(const wchar_t * file_name); + Status ParseSpaceFile(const std::wstring & file_name); /* main methods used to parse str - input string (either 8bit ascii or UTF-8 -- see UTF8() method) */ - Status Parse(const char * str); - Status Parse(const std::string & str); - + Status ParseJSON(const char * str); + Status ParseJSON(const std::string & str); /* main methods used to parse here input string is always in unicode (wide characters) */ - Status Parse(const wchar_t * str); - Status Parse(const std::wstring & str); + Status ParseJSON(const wchar_t * str); + Status ParseJSON(const std::wstring & str); + + + + Status ParseSpace(const char * str); + Status ParseSpace(const std::string & str); + Status ParseSpace(const wchar_t * str); + Status ParseSpace(const std::wstring & str); + + /* * add two args Parse method @@ -288,18 +306,6 @@ private: bool use_escape_char; - /* - - */ - size_t current_nested_level; - - - /* - - default: 1000; - */ - size_t max_nested_level; - /* * @@ -311,21 +317,16 @@ private: - // move to ParseFile() method - std::string afile_name; - - - // new void ParseRootSpace(); - void Parse(Space * space); + void Parse(Space * space, bool is_object_value, bool is_table_value); void ParseSpace(Space * space); void ParseTable(Space * space); void ParseKeyValuePairs(Space * space); void ParseValuesList(Space * space); - Space * ReadKey(Space * space); + void ReadKey(); void ParseTextValue(Space * space); void ParseIntegerValue(Space * space); @@ -333,13 +334,18 @@ private: bool is_alfa_numeric_char(int c); - void ReadAlfaNumericToken(); + + void ReadTokenUntilDelimiter(std::wstring & token, int delimiter1, int delimiter2); + void ReadAlfaNumericToken(std::wstring & token); + void ReadStringValue(std::wstring & token, bool is_object_value, bool is_table_value); bool is_integer_token(); bool is_floating_point_token(); - void ReadTokenQuoted(); + void ReadSpaceFieldToken(std::wstring & token); + void ReadTokenQuoted(std::wstring & token); + void ReadMultilineTokenQuoted(std::wstring & token); @@ -351,7 +357,9 @@ private: int ReadCharNoEscape(); int ReadChar(); bool IsWhite(int c); + void SkipLine(); void SkipWhite(); + void TrimLastWhite(std::wstring & s); //void Trim(std::wstring & s); bool IsHexDigit(wchar_t c); int HexToInt(wchar_t c); From 961a02ab396177657f12272e77c38d3afc0cbcd8 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 17 Mar 2021 18:26:13 +0100 Subject: [PATCH 15/67] removed: old SpaceParser --- space/spaceparser.cpp | 678 ------------------------------------------ space/spaceparser.h | 328 -------------------- 2 files changed, 1006 deletions(-) delete mode 100644 space/spaceparser.cpp delete mode 100644 space/spaceparser.h diff --git a/space/spaceparser.cpp b/space/spaceparser.cpp deleted file mode 100644 index 392c9ce..0000000 --- a/space/spaceparser.cpp +++ /dev/null @@ -1,678 +0,0 @@ -/* - * This file is a part of PikoTools - * and is distributed under the (new) BSD licence. - * Author: Tomasz Sowa - */ - -/* - * Copyright (c) 2008-2017, Tomasz Sowa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name Tomasz Sowa nor the names of contributors to this - * project may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include "spaceparser.h" -#include "utf8/utf8.h" - - -namespace PT -{ - -#ifdef nonexisting_value - - -SpaceParser::SpaceParser() -{ - root_space = 0; - SetDefault(); -} - - -void SpaceParser::SetSpace(Space * pspace) -{ - root_space = pspace; -} - - -void SpaceParser::SetSpace(Space & pspace) -{ - root_space = &pspace; -} - - -void SpaceParser::SetDefault() -{ - // you can change this separators to what you want - // you shoud not use only white characters here (as expected by IsWhite() method) - // and new line characters ('\n') - separator = '='; - commentary = '#'; - list_start = '('; - list_end = ')'; - list_delimiter = ','; - skip_empty = false; - use_escape_char = true; - input_as_utf8 = true; -} - - - -void SpaceParser::SkipEmpty(bool skip) -{ - skip_empty = skip; -} - - -void SpaceParser::UseEscapeChar(bool escape) -{ - use_escape_char = escape; -} - - -void SpaceParser::UTF8(bool utf) -{ - input_as_utf8 = utf; -} - - - - -SpaceParser::Status SpaceParser::Parse(const char * file_name) -{ - reading_from_file = true; - - file.clear(); - file.open(file_name, std::ios_base::binary | std::ios_base::in); - - if( file ) - { - Parse(); - file.close(); - } - else - { - status = cant_open_file; - } - -return status; -} - - - -SpaceParser::Status SpaceParser::Parse(const std::string & file_name) -{ - return Parse(file_name.c_str()); -} - - - - -SpaceParser::Status SpaceParser::Parse(const wchar_t * file_name) -{ - PT::WideToUTF8(file_name, afile_name); - return Parse(afile_name.c_str()); -} - - - -SpaceParser::Status SpaceParser::Parse(const std::wstring & file_name) -{ - return Parse(file_name.c_str()); -} - - - -SpaceParser::Status SpaceParser::ParseString(const char * str) -{ - reading_from_file = false; - reading_from_wchar_string = false; - pchar_ascii = str; - pchar_unicode = 0; - - Parse(); - -return status; -} - - -SpaceParser::Status SpaceParser::ParseString(const std::string & str) -{ - return ParseString(str.c_str()); -} - - -SpaceParser::Status SpaceParser::ParseString(const wchar_t * str) -{ - reading_from_file = false; - reading_from_wchar_string = true; - pchar_unicode = str; - pchar_ascii = 0; - - Parse(); - -return status; -} - - -SpaceParser::Status SpaceParser::ParseString(const std::wstring & str) -{ - return ParseString(str.c_str()); -} - - -void SpaceParser::Parse() -{ - if( !root_space ) - { - status = no_space; - return; - } - - line = 1; - status = ok; - space = root_space; - reading_commentary = false; - ReadChar(); - SkipWhiteLines(); - - ParseLoop(); - - if( status == ok && space != root_space ) - { - // last closing ')' characters are missing (closing a space) - status = syntax_error; - } - - token.clear(); - key.clear(); - value.clear(); -} - - -void SpaceParser::ParseLoop() -{ - while( status == ok && lastc != -1 ) - { - if( lastc == list_end ) - { - SpaceEnds(); - } - else - { - ReadKey(); - SkipWhite(); - - if( lastc == list_start ) - { - SpaceStarts(); - } - else - if( lastc == separator ) - { - ReadValue(); - AddKeyValuePair(); - } - else - { - status = syntax_error; - } - } - - if( status == ok ) - SkipWhiteLines(); - } -} - - -void SpaceParser::SpaceEnds() -{ - if( space == root_space ) - { - // there cannot be a loose list end character in the global space - status = syntax_error; - } - else - { - space = space->parent; - ReadChar(); // skipping closing space character ')' - SkipWhite(); - } -} - - -void SpaceParser::SpaceStarts() -{ - Space * new_space = new Space(); - space->spaces.push_back(new_space); - new_space->parent = space; - new_space->name = key; - space = new_space; - - ReadChar(); // skipping space starts character ')' -} - - - - - -/* - those white characters here should be the same as in space.h -*/ -bool SpaceParser::IsWhite(int c) -{ - // dont use '\n' here - // 13 (\r) is at the end of a line in a dos file \r\n - // 160 is an unbreakable space - if( c==' ' || c=='\t' || c==13 || c==160 ) - return true; - -return false; -} - - -/* - skip_lines is default false -*/ -void SpaceParser::SkipWhite(bool skip_lines) -{ - while( IsWhite(lastc) || lastc == commentary || (skip_lines && lastc=='\n')) - { - if( lastc == commentary ) - SkipComment(); - else - ReadChar(); - } -} - - -void SpaceParser::SkipWhiteLines() -{ - SkipWhite(true); -} - - -/* - do not skip the last \n character -*/ -void SpaceParser::SkipLine() -{ - while( lastc != -1 && lastc != '\n' ) - ReadChar(); -} - - -/* - do not skip the last \n character -*/ -void SpaceParser::SkipComment() -{ - reading_commentary = true; - SkipLine(); - reading_commentary = false; -} - - - -void SpaceParser::Trim(std::wstring & s) -{ -std::wstring::size_type i; - - if( s.empty() ) - return; - - // looking for white characters at the end - for(i=s.size()-1 ; i>0 && IsWhite(s[i]) ; --i); - - if( i==0 && IsWhite(s[i]) ) - { - // the whole string has white characters - s.clear(); - return; - } - - // deleting white characters at the end - if( i != s.size() - 1 ) - s.erase(i+1, std::wstring::npos); - - // looking for white characters at the beginning - for(i=0 ; itable.find(var); - - if( i != space->table.end() ) - space->table.erase(i); -} - - - - - -void SpaceParser::ReadTokenQuoted() -{ - ReadChar(); // skipping the first quotation mark - - while( lastc != -1 && (char_was_escaped || lastc != '"') ) - { - token += static_cast(lastc); - ReadChar(); - } - - if( !char_was_escaped && lastc == '"' ) - ReadChar(); // skipping the last quotation mark - else - status = syntax_error; -} - - -void SpaceParser::ReadTokenSingle(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2) -{ - while( true ) - { - if( lastc == commentary ) - SkipComment(); - - if( lastc == -1 || - (!char_was_escaped && - ( - lastc == list_end || - (white_delimit && IsWhite(lastc)) || - (new_line_delimit && lastc == '\n') || - (delimit1 != -1 && lastc == delimit1) || - (delimit2 != -1 && lastc == delimit2) - ) ) ) - - { - break; - } - - token += static_cast(lastc); - ReadChar(); - } - - Trim(token); -} - - -void SpaceParser::ReadToken(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2) -{ - token.clear(); - SkipWhite(); - - if( !char_was_escaped && lastc == '"' ) - ReadTokenQuoted(); - else - ReadTokenSingle(white_delimit, new_line_delimit, delimit1, delimit2); -} - - -void SpaceParser::ReadKey() -{ - ReadToken(false, true, separator, list_start); - key = token; - SkipWhite(); -} - - - -void SpaceParser::ReadValueList() -{ - ReadChar(); // skipping the first list character ')' - SkipWhiteLines(); - - while( lastc != -1 && lastc != list_end ) - { - ReadToken(true, true, list_delimiter, list_end); - value.push_back(token); - - SkipWhiteLines(); - - if( lastc == list_delimiter ) - { - ReadChar(); - SkipWhiteLines(); - } - } - - if( lastc == list_end ) - { - ReadChar(); // skipping the last list character ')' - SkipWhite(); - } - else - { - status = syntax_error; // missing one ')' - } -} - - -void SpaceParser::ReadValueSingle() -{ - SkipWhite(); - ReadToken(false, true, -1, -1); - value.push_back(token); - SkipWhite(); -} - - -void SpaceParser::ReadValue() -{ - ReadChar(); // skipping separator '=' - value.clear(); - SkipWhite(); - - if( lastc == list_start ) - ReadValueList(); - else - ReadValueSingle(); - - SkipWhiteLines(); -} - - -void SpaceParser::AddKeyValuePair() -{ - if( value.empty() && skip_empty ) - { - DeleteFromTable(key); - return; - } - - space->table[key] = value; -} - - - - - - -int SpaceParser::ReadUTF8Char() -{ -int c; -bool correct; - - lastc = -1; - - do - { - PT::UTF8ToInt(file, c, correct); - - if( !file ) - return lastc; - } - while( !correct ); - - lastc = c; - - if( lastc == '\n' ) - ++line; - -return lastc; -} - - - -int SpaceParser::ReadASCIIChar() -{ - lastc = file.get(); - - if( lastc == '\n' ) - ++line; - -return lastc; -} - - - - -int SpaceParser::ReadCharFromWcharString() -{ - if( *pchar_unicode == 0 ) - lastc = -1; - else - lastc = *(pchar_unicode++); - - if( lastc == '\n' ) - ++line; - -return lastc; -} - - -int SpaceParser::ReadCharFromUTF8String() -{ -int c; -bool correct; - - lastc = -1; - - do - { - size_t len = PT::UTF8ToInt(pchar_ascii, c, correct); - pchar_ascii += len; - - if( *pchar_ascii == 0 ) - return lastc; - } - while( !correct ); - - lastc = c; - - if( lastc == '\n' ) - ++line; - -return lastc; - -} - - -int SpaceParser::ReadCharFromAsciiString() -{ - if( *pchar_ascii == 0 ) - lastc = -1; - else - lastc = *(pchar_ascii++); - - if( lastc == '\n' ) - ++line; - -return lastc; -} - - -int SpaceParser::ReadCharNoEscape() -{ - if( reading_from_file ) - { - if( input_as_utf8 ) - return ReadUTF8Char(); - else - return ReadASCIIChar(); - } - else - { - if( reading_from_wchar_string ) - { - return ReadCharFromWcharString(); - } - else - { - if( input_as_utf8 ) - return ReadCharFromUTF8String(); - else - return ReadCharFromAsciiString(); - } - } -} - - -int SpaceParser::ReadChar() -{ - char_was_escaped = false; - ReadCharNoEscape(); - - if( !reading_commentary && use_escape_char && lastc == '\\' ) - { - char_was_escaped = true; - ReadCharNoEscape(); - - switch(lastc) - { - case '0': lastc = 0; break; - case 't': lastc = '\t'; break; - case 'r': lastc = '\r'; break; - case 'n': lastc = '\n'; break; - // in other cases we return the last character - } - } - -return lastc; -} - - -#endif - - -} // namespace - - - - diff --git a/space/spaceparser.h b/space/spaceparser.h deleted file mode 100644 index bba03e6..0000000 --- a/space/spaceparser.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * This file is a part of PikoTools - * and is distributed under the (new) BSD licence. - * Author: Tomasz Sowa - */ - -/* - * Copyright (c) 2010-2017, Tomasz Sowa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name Tomasz Sowa nor the names of contributors to this - * project may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef headerfile_picotools_confparser_spaceparser -#define headerfile_picotools_confparser_spaceparser - -#include -#include "space.h" - - - -namespace PT -{ - -#ifdef nonexisting_value - - -class SpaceParser -{ -public: - - - /* - ctor -- setting default values (SetDefault() method) - */ - SpaceParser(); - - - /* - setting the root space - */ - void SetSpace(Space * pspace); - void SetSpace(Space & pspace); - - - /* - setting options of the parser to the default values - utf8 etc. - */ - void SetDefault(); - - - /* - status of parsing - */ - enum Status { ok, cant_open_file, syntax_error, no_space }; - - - /* - the last status of parsing, set by Parse() methods - */ - Status status; - - - /* - a number of a line in which there is a syntax_error - */ - int line; - - - /* - main methods used to parse - file_name is the path to a file - */ - Status Parse(const char * file_name); - Status Parse(const std::string & file_name); - Status Parse(const wchar_t * file_name); - Status Parse(const std::wstring & file_name); - - - /* - main methods used to parse - str - input string (either 8bit ascii or UTF-8 -- see UTF8() method) - */ - Status ParseString(const char * str); - Status ParseString(const std::string & str); - - - /* - main methods used to parse - here input string is always in unicode (wide characters) - */ - Status ParseString(const wchar_t * str); - Status ParseString(const std::wstring & str); - - - /* - if true then empty values and lists, e.g: - option = - option2 = () - will be omitted (not inserted to 'table') - default: false - */ - void SkipEmpty(bool skip); - - - /* - '\' character is used to escape other characters - so "some \t t\"ext" will produce "some t t"ext" - default: true - special characters: - \0 - 0 (zero code point) - \t - tabulator (9 code point) - \r - carriage return (13 code point) - \n - a new line character (10 code point) - in other cases we return the last character so \Z gives Z and \\ gives one \ - escape character are not used in commentaries - so you can write: - # this is my comment \n but this was not a new line - */ - void UseEscapeChar(bool escape); - - - /* - if true then the input file or string (char* or std::string) is treated as UTF-8 - default: true - */ - void UTF8(bool utf); - - -private: - - - /* - current space set by SetSpace(); - */ - Space * root_space; - - - /* - a space in which we are now - */ - Space * space; - - - /* - true if Parse() method was called - false if ParseString() was called - */ - bool reading_from_file; - - - /* - pointers to the current character - if ParseString() is in used - */ - const char * pchar_ascii; - const wchar_t * pchar_unicode; - - - /* - true if ParseString(wchar_t *) or ParseString(std::wstring&) was called - */ - bool reading_from_wchar_string; - - - /* - last read token - */ - std::wstring token; - - - /* - last read key - */ - std::wstring key; - - - /* - last read list - */ - Space::Value value; - - - /* - separator between a variable and a value, default: '=' - */ - int separator; - - - /* - commentary char, default: '#' - */ - int commentary; - - - /* - list starting character, default: '(' - */ - int list_start; - - - /* - list ending character, default: ')' - */ - int list_end; - - - /* - list delimiter, default: ',' - */ - int list_delimiter; - - - /* - last read char - or -1 if the end - */ - int lastc; - - - /* - true if the lastc was escaped (with a backslash) - we have to know if the last sequence was \" or just " - */ - bool char_was_escaped; - - - /* - current file - */ - std::ifstream file; - - - /* - if true then empty lists, e.g: - option = - option2 = () - will be omitted (not inserted to 'table') - default: false - */ - bool skip_empty; - - - /* - input file is in UTF-8 - default: true - */ - bool input_as_utf8; - - - /* - if true you can use an escape character '\' in quoted values - */ - bool use_escape_char; - - - /* - true if we are reading the commentary (#) - this is to avoid parsing escape characters in the commentary - */ - bool reading_commentary; - - std::string afile_name; - - void Parse(); - void ParseLoop(); - void SpaceEnds(); - void SpaceStarts(); - - void DeleteFromTable(const std::wstring & var); - - void ReadTokenQuoted(); - void ReadTokenSingle(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2); - void ReadToken(bool white_delimit, bool new_line_delimit, int delimit1, int delimit2); - void ReadKey(); - void ReadValueList(); - void ReadValueSingle(); - void ReadValue(); - void AddKeyValuePair(); - - int ReadUTF8Char(); - int ReadASCIIChar(); - int ReadCharFromWcharString(); - int ReadCharFromUTF8String(); - int ReadCharFromAsciiString(); - int ReadCharNoEscape(); - int ReadChar(); - bool IsWhite(int c); - void SkipWhite(bool skip_lines = false); - void SkipWhiteLines(); - void SkipLine(); - void SkipComment(); - void Trim(std::wstring & s); - -}; - -#endif - - -} // namespace - - -#endif From ba82ac7cbee7d0e1224e33ad500ea893697eadae Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 17 Mar 2021 18:33:41 +0100 Subject: [PATCH 16/67] renamed: JSONToSpaceParser -> SpaceParser --- Makefile.dep | 18 +-- ...{jsontospaceparser.cpp => spaceparser.cpp} | 118 +++++++++--------- space/{jsontospaceparser.h => spaceparser.h} | 4 +- 3 files changed, 67 insertions(+), 73 deletions(-) rename space/{jsontospaceparser.cpp => spaceparser.cpp} (81%) rename space/{jsontospaceparser.h => spaceparser.h} (99%) diff --git a/Makefile.dep b/Makefile.dep index 891cd41..0e52a4b 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -19,24 +19,18 @@ ./mainspaceparser/mainspaceparser.o: membuffer/membuffer.h textstream/types.h ./mainspaceparser/mainspaceparser.o: utf8/utf8_templates.h ./mainspaceparser/mainspaceparser.o: utf8/utf8_private.h -./space/jsontospaceparser.o: ./space/jsontospaceparser.h ./space/space.h -./space/jsontospaceparser.o: textstream/types.h convert/inttostr.h -./space/jsontospaceparser.o: utf8/utf8.h textstream/textstream.h -./space/jsontospaceparser.o: space/space.h date/date.h membuffer/membuffer.h -./space/jsontospaceparser.o: textstream/types.h utf8/utf8_templates.h -./space/jsontospaceparser.o: utf8/utf8_private.h convert/strtoint.h -./space/jsontospaceparser.o: ./convert/text.h ./convert/misc.h +./space/spaceparser.o: ./space/spaceparser.h ./space/space.h +./space/spaceparser.o: textstream/types.h convert/inttostr.h utf8/utf8.h +./space/spaceparser.o: textstream/textstream.h space/space.h date/date.h +./space/spaceparser.o: membuffer/membuffer.h textstream/types.h +./space/spaceparser.o: utf8/utf8_templates.h utf8/utf8_private.h +./space/spaceparser.o: convert/strtoint.h ./convert/text.h ./convert/misc.h ./space/space.o: ./space/space.h textstream/types.h convert/inttostr.h ./space/space.o: utf8/utf8.h textstream/textstream.h space/space.h ./space/space.o: date/date.h membuffer/membuffer.h textstream/types.h ./space/space.o: utf8/utf8_templates.h utf8/utf8_private.h convert/convert.h ./space/space.o: ./convert/inttostr.h convert/patternreplacer.h ./space/space.o: convert/strtoint.h ./convert/text.h ./convert/misc.h -./space/spaceparser.o: ./space/spaceparser.h ./space/space.h -./space/spaceparser.o: textstream/types.h convert/inttostr.h utf8/utf8.h -./space/spaceparser.o: textstream/textstream.h space/space.h date/date.h -./space/spaceparser.o: membuffer/membuffer.h textstream/types.h -./space/spaceparser.o: utf8/utf8_templates.h utf8/utf8_private.h ./space/spacetojson.o: ./space/spacetojson.h ./space/space.h ./space/spacetojson.o: textstream/types.h convert/inttostr.h ./utf8/utf8.o: ./utf8/utf8.h textstream/textstream.h space/space.h diff --git a/space/jsontospaceparser.cpp b/space/spaceparser.cpp similarity index 81% rename from space/jsontospaceparser.cpp rename to space/spaceparser.cpp index 8881a86..d867cf6 100644 --- a/space/jsontospaceparser.cpp +++ b/space/spaceparser.cpp @@ -37,7 +37,7 @@ #include #include -#include "jsontospaceparser.h" +#include "spaceparser.h" #include "utf8/utf8.h" #include "convert/strtoint.h" @@ -48,26 +48,26 @@ namespace PT -JSONToSpaceParser::JSONToSpaceParser() +SpaceParser::SpaceParser() { root_space = 0; SetDefault(); } -void JSONToSpaceParser::SetSpace(Space * pspace) +void SpaceParser::SetSpace(Space * pspace) { root_space = pspace; } -void JSONToSpaceParser::SetSpace(Space & pspace) +void SpaceParser::SetSpace(Space & pspace) { root_space = &pspace; } -void JSONToSpaceParser::SetDefault() +void SpaceParser::SetDefault() { // you can change this separators to what you want // you shoud not use only white characters here (as expected by IsWhite() method) @@ -85,32 +85,32 @@ void JSONToSpaceParser::SetDefault() -void JSONToSpaceParser::SkipEmpty(bool skip) +void SpaceParser::SkipEmpty(bool skip) { skip_empty = skip; } -void JSONToSpaceParser::UseEscapeChar(bool escape) +void SpaceParser::UseEscapeChar(bool escape) { use_escape_char = escape; } -void JSONToSpaceParser::UTF8(bool utf) +void SpaceParser::UTF8(bool utf) { input_as_utf8 = utf; } -int JSONToSpaceParser::get_last_parsed_line() +int SpaceParser::get_last_parsed_line() { return line; } -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const char * file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const char * file_name) { reading_from_file = true; parsing_space = false; @@ -133,7 +133,7 @@ return status; -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const std::string & file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const std::string & file_name) { return ParseJSONFile(file_name.c_str()); } @@ -141,7 +141,7 @@ JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const std::string & f -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const wchar_t * file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const wchar_t * file_name) { std::string file_name_utf8; @@ -151,7 +151,7 @@ JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const wchar_t * file_ -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const std::wstring & file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const std::wstring & file_name) { return ParseJSONFile(file_name.c_str()); } @@ -160,7 +160,7 @@ JSONToSpaceParser::Status JSONToSpaceParser::ParseJSONFile(const std::wstring & -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const char * file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const char * file_name) { reading_from_file = true; parsing_space = true; @@ -183,7 +183,7 @@ return status; -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const std::string & file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const std::string & file_name) { return ParseSpaceFile(file_name.c_str()); } @@ -191,7 +191,7 @@ JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const std::string & -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const wchar_t * file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const wchar_t * file_name) { std::string file_name_utf8; @@ -201,14 +201,14 @@ JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const wchar_t * file -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpaceFile(const std::wstring & file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const std::wstring & file_name) { return ParseSpaceFile(file_name.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const char * str) +SpaceParser::Status SpaceParser::ParseJSON(const char * str) { reading_from_file = false; reading_from_wchar_string = false; @@ -222,13 +222,13 @@ return status; } -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const std::string & str) +SpaceParser::Status SpaceParser::ParseJSON(const std::string & str) { return ParseJSON(str.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const wchar_t * str) +SpaceParser::Status SpaceParser::ParseJSON(const wchar_t * str) { reading_from_file = false; reading_from_wchar_string = true; @@ -242,7 +242,7 @@ return status; } -JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const std::wstring & str) +SpaceParser::Status SpaceParser::ParseJSON(const std::wstring & str) { return ParseJSON(str.c_str()); } @@ -251,7 +251,7 @@ JSONToSpaceParser::Status JSONToSpaceParser::ParseJSON(const std::wstring & str) -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const char * str) +SpaceParser::Status SpaceParser::ParseSpace(const char * str) { reading_from_file = false; reading_from_wchar_string = false; @@ -265,13 +265,13 @@ return status; } -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const std::string & str) +SpaceParser::Status SpaceParser::ParseSpace(const std::string & str) { return ParseSpace(str.c_str()); } -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const wchar_t * str) +SpaceParser::Status SpaceParser::ParseSpace(const wchar_t * str) { reading_from_file = false; reading_from_wchar_string = true; @@ -285,7 +285,7 @@ return status; } -JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const std::wstring & str) +SpaceParser::Status SpaceParser::ParseSpace(const std::wstring & str) { return ParseSpace(str.c_str()); } @@ -294,7 +294,7 @@ JSONToSpaceParser::Status JSONToSpaceParser::ParseSpace(const std::wstring & str -void JSONToSpaceParser::ParseRootSpace() +void SpaceParser::ParseRootSpace() { line = 1; status = ok; @@ -327,7 +327,7 @@ void JSONToSpaceParser::ParseRootSpace() } -void JSONToSpaceParser::Parse(Space * space, bool is_object_value, bool is_table_value) +void SpaceParser::Parse(Space * space, bool is_object_value, bool is_table_value) { SkipWhite(); @@ -391,7 +391,7 @@ void JSONToSpaceParser::Parse(Space * space, bool is_object_value, bool is_table -void JSONToSpaceParser::ParseSpace(Space * space) +void SpaceParser::ParseSpace(Space * space) { /* * in Space format in global namespace the space start character is not required @@ -423,7 +423,7 @@ void JSONToSpaceParser::ParseSpace(Space * space) -void JSONToSpaceParser::ParseTextValue(Space * space) +void SpaceParser::ParseTextValue(Space * space) { space->set_empty_wstring(); std::wstring * str = space->get_wstring(); @@ -435,7 +435,7 @@ void JSONToSpaceParser::ParseTextValue(Space * space) } -void JSONToSpaceParser::ParseIntegerValue(Space * space) +void SpaceParser::ParseIntegerValue(Space * space) { const wchar_t * after_str = nullptr; bool was_overflow = false; @@ -458,7 +458,7 @@ void JSONToSpaceParser::ParseIntegerValue(Space * space) } -void JSONToSpaceParser::ParseFloatingPointValue(Space * space) +void SpaceParser::ParseFloatingPointValue(Space * space) { wchar_t * after_str = nullptr; double val = wcstod(token.c_str(), &after_str); @@ -481,7 +481,7 @@ void JSONToSpaceParser::ParseFloatingPointValue(Space * space) -void JSONToSpaceParser::ParseTable(Space * space) +void SpaceParser::ParseTable(Space * space) { space->set_empty_table(); @@ -503,7 +503,7 @@ void JSONToSpaceParser::ParseTable(Space * space) -void JSONToSpaceParser::ParseKeyValuePairs(Space * space) +void SpaceParser::ParseKeyValuePairs(Space * space) { bool is_first = true; SkipWhite(); @@ -571,7 +571,7 @@ void JSONToSpaceParser::ParseKeyValuePairs(Space * space) -void JSONToSpaceParser::ParseValuesList(Space * space) +void SpaceParser::ParseValuesList(Space * space) { bool is_first = true; SkipWhite(); @@ -616,7 +616,7 @@ void JSONToSpaceParser::ParseValuesList(Space * space) -bool JSONToSpaceParser::is_integer_token() +bool SpaceParser::is_integer_token() { if( token.empty() ) return false; @@ -643,7 +643,7 @@ bool JSONToSpaceParser::is_integer_token() } -bool JSONToSpaceParser::is_floating_point_token() +bool SpaceParser::is_floating_point_token() { bool was_dot = false; bool was_exponential = false; @@ -707,7 +707,7 @@ bool JSONToSpaceParser::is_floating_point_token() -bool JSONToSpaceParser::IsWhite(int c) +bool SpaceParser::IsWhite(int c) { // 13 (\r) is at the end of a line in a dos file \r\n // 160 is an unbreakable space @@ -718,7 +718,7 @@ return false; } -bool JSONToSpaceParser::is_alfa_numeric_char(int c) +bool SpaceParser::is_alfa_numeric_char(int c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || @@ -727,7 +727,7 @@ bool JSONToSpaceParser::is_alfa_numeric_char(int c) } -void JSONToSpaceParser::SkipLine() +void SpaceParser::SkipLine() { while( lastc != -1 && (char_was_escaped || lastc != '\n') ) ReadChar(); @@ -735,7 +735,7 @@ void JSONToSpaceParser::SkipLine() -void JSONToSpaceParser::SkipWhite() +void SpaceParser::SkipWhite() { if( parsing_space ) { @@ -757,7 +757,7 @@ void JSONToSpaceParser::SkipWhite() } -void JSONToSpaceParser::TrimLastWhite(std::wstring & s) +void SpaceParser::TrimLastWhite(std::wstring & s) { std::wstring::size_type i; @@ -773,7 +773,7 @@ void JSONToSpaceParser::TrimLastWhite(std::wstring & s) /* -void JSONToSpaceParser::Trim(std::wstring & s) +void SpaceParser::Trim(std::wstring & s) { std::wstring::size_type i; @@ -804,7 +804,7 @@ std::wstring::size_type i; */ -void JSONToSpaceParser::ReadTokenUntilDelimiter(std::wstring & token, int delimiter1, int delimiter2) +void SpaceParser::ReadTokenUntilDelimiter(std::wstring & token, int delimiter1, int delimiter2) { token.clear(); @@ -818,7 +818,7 @@ void JSONToSpaceParser::ReadTokenUntilDelimiter(std::wstring & token, int delimi } -void JSONToSpaceParser::ReadAlfaNumericToken(std::wstring & token) +void SpaceParser::ReadAlfaNumericToken(std::wstring & token) { token.clear(); @@ -830,7 +830,7 @@ void JSONToSpaceParser::ReadAlfaNumericToken(std::wstring & token) } -void JSONToSpaceParser::ReadStringValue(std::wstring & token, bool is_object_value, bool is_table_value) +void SpaceParser::ReadStringValue(std::wstring & token, bool is_object_value, bool is_table_value) { if( parsing_space ) { @@ -856,7 +856,7 @@ void JSONToSpaceParser::ReadStringValue(std::wstring & token, bool is_object_val // rename to something like ReadSpaceFieldToken??? -void JSONToSpaceParser::ReadSpaceFieldToken(std::wstring & token) +void SpaceParser::ReadSpaceFieldToken(std::wstring & token) { token.clear(); @@ -871,7 +871,7 @@ void JSONToSpaceParser::ReadSpaceFieldToken(std::wstring & token) // IMPROVEME in JSON we should not allow non-escaped a new line character -void JSONToSpaceParser::ReadTokenQuoted(std::wstring & token) +void SpaceParser::ReadTokenQuoted(std::wstring & token) { token.clear(); ReadChar(); // skipping the first quotation mark @@ -893,7 +893,7 @@ void JSONToSpaceParser::ReadTokenQuoted(std::wstring & token) } -void JSONToSpaceParser::ReadMultilineTokenQuoted(std::wstring & token) +void SpaceParser::ReadMultilineTokenQuoted(std::wstring & token) { token.clear(); ReadChar(); // skipping the first quotation mark @@ -916,7 +916,7 @@ void JSONToSpaceParser::ReadMultilineTokenQuoted(std::wstring & token) -void JSONToSpaceParser::ReadKey() +void SpaceParser::ReadKey() { SkipWhite(); @@ -947,7 +947,7 @@ void JSONToSpaceParser::ReadKey() -int JSONToSpaceParser::ReadUTF8Char() +int SpaceParser::ReadUTF8Char() { int c; bool correct; @@ -973,7 +973,7 @@ return lastc; -int JSONToSpaceParser::ReadASCIIChar() +int SpaceParser::ReadASCIIChar() { lastc = file.get(); @@ -986,7 +986,7 @@ return lastc; -int JSONToSpaceParser::ReadCharFromWcharString() +int SpaceParser::ReadCharFromWcharString() { if( *pchar_unicode == 0 ) lastc = -1; @@ -1000,7 +1000,7 @@ return lastc; } -int JSONToSpaceParser::ReadCharFromUTF8String() +int SpaceParser::ReadCharFromUTF8String() { int c; bool correct; @@ -1025,7 +1025,7 @@ return lastc; } -int JSONToSpaceParser::ReadCharFromAsciiString() +int SpaceParser::ReadCharFromAsciiString() { if( *pchar_ascii == 0 ) lastc = -1; @@ -1039,7 +1039,7 @@ return lastc; } -int JSONToSpaceParser::ReadCharNoEscape() +int SpaceParser::ReadCharNoEscape() { if( reading_from_file ) { @@ -1064,7 +1064,7 @@ int JSONToSpaceParser::ReadCharNoEscape() } } -bool JSONToSpaceParser::IsHexDigit(wchar_t c) +bool SpaceParser::IsHexDigit(wchar_t c) { return ((c>='0' && c<='9') || (c>='a' && c<='f') || @@ -1072,7 +1072,7 @@ bool JSONToSpaceParser::IsHexDigit(wchar_t c) } -int JSONToSpaceParser::HexToInt(wchar_t c) +int SpaceParser::HexToInt(wchar_t c) { if( c>='0' && c<='9' ) return c - '0'; @@ -1087,7 +1087,7 @@ return 0; } -void JSONToSpaceParser::ReadUnicodeCodePoint() +void SpaceParser::ReadUnicodeCodePoint() { wchar_t c; int value = 0; @@ -1109,7 +1109,7 @@ int value = 0; } -int JSONToSpaceParser::ReadChar() +int SpaceParser::ReadChar() { char_was_escaped = false; ReadCharNoEscape(); diff --git a/space/jsontospaceparser.h b/space/spaceparser.h similarity index 99% rename from space/jsontospaceparser.h rename to space/spaceparser.h index cea2f51..a602554 100644 --- a/space/jsontospaceparser.h +++ b/space/spaceparser.h @@ -49,7 +49,7 @@ namespace PT -class JSONToSpaceParser +class SpaceParser { public: @@ -57,7 +57,7 @@ public: /* ctor -- setting default values (SetDefault() method) */ - JSONToSpaceParser(); + SpaceParser(); /* From 1baf5042feff7627430c29cb4092da265a3fe21a Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 17 Mar 2021 18:35:48 +0100 Subject: [PATCH 17/67] removed: SpaceToJson --- space/spacetojson.cpp | 117 ------------------ space/spacetojson.h | 273 ------------------------------------------ 2 files changed, 390 deletions(-) delete mode 100644 space/spacetojson.cpp delete mode 100644 space/spacetojson.h diff --git a/space/spacetojson.cpp b/space/spacetojson.cpp deleted file mode 100644 index 64d09f8..0000000 --- a/space/spacetojson.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is a part of PikoTools - * and is distributed under the (new) BSD licence. - * Author: Tomasz Sowa - */ - -/* - * Copyright (c) 2012, Tomasz Sowa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name Tomasz Sowa nor the names of contributors to this - * project may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "spacetojson.h" - - -namespace PT -{ - -#ifdef nonexisting_value - - -void SpaceToJSON::Clear() -{ - numeric.clear(); - boolean.clear(); - table.clear(); -} - - -void SpaceToJSON::TreatAsTable(const wchar_t * space_name) -{ - table.insert(space_name); -} - - -void SpaceToJSON::TreatAsTable(const std::wstring & space_name) -{ - table.insert(space_name); -} - - - -void SpaceToJSON::TreatAsNumeric(const wchar_t * name) -{ - numeric.insert(name); -} - - -void SpaceToJSON::TreatAsNumeric(const std::wstring & name) -{ - numeric.insert(name); - -} - - -void SpaceToJSON::TreatAsBool(const wchar_t * name) -{ - boolean.insert(name); -} - -void SpaceToJSON::TreatAsBool(const std::wstring & name) -{ - boolean.insert(name); -} - - - -bool SpaceToJSON::IsNumeric(const std::wstring & name) -{ - std::set::iterator i = numeric.find(name); - return i != numeric.end(); -} - - -bool SpaceToJSON::IsBool(const std::wstring & name) -{ - std::set::iterator i = boolean.find(name); - return i != boolean.end(); -} - -bool SpaceToJSON::IsTable(const std::wstring & name) -{ - std::set::iterator i = table.find(name); - return i != table.end(); -} - -#endif - - - -} // namespace - diff --git a/space/spacetojson.h b/space/spacetojson.h deleted file mode 100644 index 6338e06..0000000 --- a/space/spacetojson.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * This file is a part of PikoTools - * and is distributed under the (new) BSD licence. - * Author: Tomasz Sowa - */ - -/* - * Copyright (c) 2012-2017, Tomasz Sowa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name Tomasz Sowa nor the names of contributors to this - * project may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef headerfile_picotools_space_spacetojson -#define headerfile_picotools_space_spacetojson - -#include -#include -#include -#include "space.h" - - - -namespace PT -{ - -#ifdef nonexisting_value - - -class SpaceToJSON -{ -public: - - void Clear(); - - void TreatAsTable(const wchar_t * space_name); - void TreatAsTable(const std::wstring & space_name); - - void TreatAsNumeric(const wchar_t * name); - void TreatAsNumeric(const std::wstring & name); - - void TreatAsBool(const wchar_t * name); - void TreatAsBool(const std::wstring & name); - - template - void Serialize(Space & space, Stream & out, bool use_indents = false); - - -private: - - std::set numeric, boolean, table; - - - template - void Serialize(Space & space, Stream & out, bool use_indents, int level, - bool use_comma, bool treat_as_table, bool skip_name); - - template - void SerializeTableMulti(Space & space, Stream & out, bool use_indents, int level, bool use_comma); - - template - void PrintToken(Stream & out, const StringType & str, bool check_specials = false); - - template - void PrintLevel(Stream & out, bool use_indents, int level); - - - bool IsNumeric(const std::wstring & name); - bool IsBool(const std::wstring & name); - bool IsTable(const std::wstring & name); - -}; - - - - -template -void SpaceToJSON::PrintLevel(Stream & out, bool use_indents, int level) -{ - if( use_indents ) - { - for(int i=0 ; i -void SpaceToJSON::PrintToken(Stream & out, const StringType & str, bool is_special) -{ - if( !is_special ) - out << '\"'; - - for(size_t i=0 ; i -void SpaceToJSON::SerializeTableMulti(Space & space, Stream & out, bool use_indents, int level, bool use_comma) -{ -Space::Table::const_iterator i2; -size_t v; -size_t index = 0; -bool is_special; - - if( use_comma && !space.table.empty() ) - { - PrintLevel(out, use_indents, level); - out << L",\n"; - } - - for(i2 = space.table.begin() ; i2 != space.table.end() ; ++i2, ++index) - { - is_special = IsNumeric(i2->first) || IsBool(i2->first); - - PrintLevel(out, use_indents, level); - PrintToken(out, i2->first); - out << L": "; - - if( i2->second.size() != 1 ) - out << '['; - - for(v = 0 ; v < i2->second.size() ; ++v) - { - if( v > 0 ) - PrintLevel(out, use_indents, level + i2->first.size() + 3); - - PrintToken(out, i2->second[v], is_special); - - if( v + 1 < i2->second.size() ) - out << L",\n"; - } - - if( i2->second.size() != 1 ) - out << ']'; - - if( index + 1 < space.table.size() ) - out << ','; - - out << '\n'; - } -} - - - - -template -void SpaceToJSON::Serialize(Space & space, Stream & out, bool use_indents, int level, - bool use_comma, bool treat_as_table, bool skip_name) -{ - if( use_comma ) - { - PrintLevel(out, use_indents, level); - out << L",\n"; - } - - PrintLevel(out, use_indents, level); - - if( !skip_name ) - { - if( space.name.empty() ) - { - out << L"\"empty\": "; - } - else - { - PrintToken(out, space.name); - out << L": "; - } - } - - if( treat_as_table ) - out << L"[\n"; - else - out << L"{\n"; - - bool printed_something = false; - - if( !treat_as_table ) - { - SerializeTableMulti(space, out, use_indents, level, false); - - if( !space.table.empty() ) - printed_something = true; - } - - /* - * !! IMPROVE ME when serializing a table - * we can make a test whether a space is empty and has a name - * in such a case put it as a string - * this is the same way as the json parser works - * - */ - for(size_t i=0 ; iname); - Serialize(*space.spaces[i], out, use_indents, level+1, printed_something, next_is_table, next_skip_name); - printed_something = true; - } - - PrintLevel(out, use_indents, level); - - if( treat_as_table ) - out << L"]\n"; - else - out << L"}\n"; -} - - - -template -void SpaceToJSON::Serialize(Space & space, Stream & out, bool use_indents) -{ - bool treat_as_table = IsTable(space.name); - Serialize(space, out, use_indents, 0, false, treat_as_table, true); -} - -#endif - - -} // namespace - -#endif - From db5e516564fb588c2899b38d961f14b94835f27e Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 18 Mar 2021 15:33:43 +0100 Subject: [PATCH 18/67] added to Space: serialization do Space format --- space/space.cpp | 16 ++-- space/space.h | 248 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 239 insertions(+), 25 deletions(-) diff --git a/space/space.cpp b/space/space.cpp index a0ca225..4a4fef2 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -748,35 +748,35 @@ std::wstring Space::to_wstr() const } -std::string Space::serialize_to_space_str() const +std::string Space::serialize_to_space_str(bool pretty_print) const { std::string str; - serialize_to_space_to(str); + serialize_to_space_to(str, pretty_print); return str; } -std::wstring Space::serialize_to_space_wstr() const +std::wstring Space::serialize_to_space_wstr(bool pretty_print) const { std::wstring str; - serialize_to_space_to(str); + serialize_to_space_to(str, pretty_print); return str; } -void Space::serialize_to_space_to(std::string & str) const +void Space::serialize_to_space_to(std::string & str, bool pretty_print) const { PT::TextStream stream; - serialize_to_space_stream(stream); + serialize_to_space_stream(stream, pretty_print); stream.to_string(str); } -void Space::serialize_to_space_to(std::wstring & str) const +void Space::serialize_to_space_to(std::wstring & str, bool pretty_print) const { PT::WTextStream stream; - serialize_to_space_stream(stream); + serialize_to_space_stream(stream, pretty_print); stream.to_string(str); } diff --git a/space/space.h b/space/space.h index 340813d..c19e7f3 100644 --- a/space/space.h +++ b/space/space.h @@ -330,52 +330,50 @@ public: - std::string serialize_to_space_str() const; - std::wstring serialize_to_space_wstr() const; - void serialize_to_space_to(std::string & str) const; - void serialize_to_space_to(std::wstring & str) const; + std::string serialize_to_space_str(bool pretty_print = false) const; + std::wstring serialize_to_space_wstr(bool pretty_print = false) const; + void serialize_to_space_to(std::string & str, bool pretty_print = false) const; + void serialize_to_space_to(std::wstring & str, bool pretty_print = false) const; template - void serialize_to_space_stream(StreamType & str) const + void serialize_to_space_stream(StreamType & str, bool pretty_print = false, bool is_main_object = true) const { - // IMPROVEME - switch(type) { case type_null: - //serialize_null(str, escape); + serialize_space_null(str); break; case type_bool: - //serialize_bool(str, escape); + serialize_space_bool(str); break; case type_long: - //serialize_long(str, escape); + serialize_space_long(str); break; case type_float: - //serialize_float(str, escape); + serialize_space_float(str); break; case type_double: - //serialize_double(str, escape); + serialize_space_double(str); break; case type_string: - //serialize_string(str, escape); + serialize_space_string(str); break; case type_wstring: - //serialize_wstring(str, escape); + serialize_space_wstring(str); break; case type_object: - //serialize_object(str, escape); + serialize_space_object(str, pretty_print, is_main_object); break; case type_table: - //serialize_table(str, escape); + serialize_space_table(str, pretty_print); break; } } @@ -387,7 +385,6 @@ public: void serialize_to_json_to(std::wstring & str) const; - template void serialize_to_json_stream(StreamType & str) const { @@ -494,6 +491,7 @@ protected: void escape_to_space_format(int c, StreamType & out) const { // IMPLEMENT ME + escape_to_json_format(c, out); } @@ -594,6 +592,183 @@ protected: } + + + template + void serialize_space_null(StreamType & str) const + { + serialize_string_buffer(L"null", str, Escape::escape_space); + } + + template + void serialize_space_bool(StreamType & str) const + { + if( value.value_bool ) + { + serialize_string_buffer(L"true", str, Escape::escape_space); + } + else + { + serialize_string_buffer(L"false", str, Escape::escape_space); + } + } + + + template + void serialize_space_long(StreamType & str) const + { + wchar_t buffer[50]; + size_t buffer_len = sizeof(buffer) / sizeof(char); + + PT::Toa(value.value_long, buffer, buffer_len); + serialize_string_buffer(buffer, str, Escape::escape_space); + } + + template + void serialize_space_float(StreamType & str) const + { + wchar_t buffer[100]; + size_t buffer_len = sizeof(buffer) / sizeof(char); + + int chars_written = std::swprintf(buffer, buffer_len, L"%e", static_cast(value.value_float)); + + if( errno == EOVERFLOW || chars_written < 0 ) + buffer[0] = 0; + + serialize_string_buffer(buffer, str, Escape::escape_space); + } + + template + void serialize_space_double(StreamType & str) const + { + wchar_t buffer[100]; + size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); + + int chars_written = std::swprintf(buffer, buffer_len, L"%e", value.value_double); + + if( errno == EOVERFLOW || chars_written < 0 ) + buffer[0] = 0; + + serialize_string_buffer(buffer, str, Escape::escape_space); + } + + template + void serialize_space_string(StreamType & str) const + { + str << '"'; + serialize_string_buffer(value.value_string.c_str(), str, Escape::escape_space); + str << '"'; + } + + template + void serialize_space_wstring(StreamType & str) const + { + str << '"'; + serialize_string_buffer(value.value_wstring.c_str(), str, Escape::escape_space); + str << '"'; + } + + template + void serialize_space_object(StreamType & str, bool pretty_print, bool is_main_object) const + { + if( !is_main_object ) + { + str << '{'; + print_if(pretty_print, str, '\n'); + } + + bool is_first = true; + + for(auto & map_item : value.value_object) + { + if( !is_first ) + print_if(pretty_print, str, '\n', ','); + + bool quote_field = should_field_be_quoted(map_item.first); + + print_if(quote_field, str, '"'); + serialize_string_buffer(map_item.first.c_str(), str, Escape::escape_space); + print_if(quote_field, str, '"'); + + print_if(pretty_print, str, ' '); + str << '='; + print_if(pretty_print, str, ' '); + + map_item.second->serialize_to_space_stream(str, pretty_print, false); + is_first = false; + } + + print_if(!is_first && pretty_print, str, '\n'); + serialize_child_spaces(str, pretty_print); + + if( !is_main_object ) + { + str << '}'; + print_if(pretty_print, str, '\n'); + } + } + + + template + void serialize_child_spaces(StreamType & str, bool pretty_print) const + { + if( child_spaces && !child_spaces->empty() ) + { + print_if(pretty_print, str, '\n'); + + for(Space * child_space : *child_spaces) + { + print_if(!pretty_print, str, ' '); + + if( child_space->name && !child_space->name->empty() ) + { + bool quote_field = should_field_be_quoted(*child_space->name); + + print_if(quote_field, str, '"'); + serialize_string_buffer(child_space->name->c_str(), str, Escape::escape_space); + print_if(quote_field, str, '"'); + + str << ' '; + } + + child_space->serialize_to_space_stream(str, pretty_print, false); + print_if(pretty_print, str, '\n'); + } + } + } + + + template + void serialize_space_table(StreamType & str, bool pretty_print) const + { + bool multivalue_table = false; + bool is_first = true; + + if( value.value_table.size() > 1 ) + { + multivalue_table = true; + } + + str << '('; + print_if(pretty_print && multivalue_table, str, '\n'); + + for(Space * space : value.value_table) + { + if( !is_first ) + print_if(pretty_print, str, '\n', ','); + + space->serialize_to_space_stream(str, pretty_print, false); + is_first = false; + } + + print_if(pretty_print && multivalue_table, str, '\n'); + str << ')'; + } + + + + + template void serialize_json_null(StreamType & str) const { @@ -719,6 +894,7 @@ public: ///////////////////////////// remove me + template void Serialize(Stream & out, bool use_indents = false, bool use_comments = false, int level = 0) const { @@ -748,6 +924,44 @@ public: protected: + template + bool should_field_be_quoted(StringType & str) const + { + if( str.empty() ) + return true; + + for(size_t i = 0 ; i < str.size() ; ++i) + { + int c = str[i]; + + // '{' is used when child spaces begin + + if( c == '\n' || c == '#' || c == '=' || c == '{' || c == '}' ) + return true; + } + + return false; + } + + + + + template + void print_if(bool condition, StreamType & str, wchar_t c) const + { + if( condition ) + str << c; + } + + template + void print_if(bool condition, StreamType & str, wchar_t c1, wchar_t c2) const + { + if( condition ) + str << c1; + else + str << c2; + } + void copy_value_from(const Space & space); void copy_child_spaces_from(const Space & space); From 4119461f8e6912e0b79aac186dc7647212a8f6ab Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 18 Mar 2021 16:26:56 +0100 Subject: [PATCH 19/67] fixed: when reading a non-escaped space token we should check whether a delimiter was escaped or not also a '#' was not tested --- space/space.h | 2 +- space/spaceparser.cpp | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/space/space.h b/space/space.h index c19e7f3..8647527 100644 --- a/space/space.h +++ b/space/space.h @@ -674,7 +674,7 @@ protected: if( !is_main_object ) { str << '{'; - print_if(pretty_print, str, '\n'); + print_if(pretty_print && (!value.value_object.empty() || (child_spaces && !child_spaces->empty())), str, '\n'); } bool is_first = true; diff --git a/space/spaceparser.cpp b/space/spaceparser.cpp index d867cf6..09bd6b6 100644 --- a/space/spaceparser.cpp +++ b/space/spaceparser.cpp @@ -739,7 +739,7 @@ void SpaceParser::SkipWhite() { if( parsing_space ) { - while( IsWhite(lastc) || lastc == '#' ) + while( IsWhite(lastc) || (!char_was_escaped && lastc == '#') ) { if( lastc == '#' ) SkipLine(); @@ -808,7 +808,7 @@ void SpaceParser::ReadTokenUntilDelimiter(std::wstring & token, int delimiter1, { token.clear(); - while( lastc != -1 && lastc != '\n' && lastc != '#' && lastc != delimiter1 && lastc != delimiter2 ) + while( lastc != -1 && (char_was_escaped || (lastc != '\n' && lastc != '#' && lastc != delimiter1 && lastc != delimiter2)) ) { token += static_cast(lastc); ReadChar(); @@ -860,7 +860,7 @@ void SpaceParser::ReadSpaceFieldToken(std::wstring & token) { token.clear(); - while( lastc != -1 && (char_was_escaped || (lastc != separator && lastc != 10 && lastc != space_start)) ) + while( lastc != -1 && (char_was_escaped || (lastc != separator && lastc != 10 && lastc != space_start && lastc != '#' )) ) { token += static_cast(lastc); ReadChar(); @@ -915,7 +915,10 @@ void SpaceParser::ReadMultilineTokenQuoted(std::wstring & token) } - +/* + * this method is used to read the field name (key) in an object + * or to read the space child name (used in Space format) + */ void SpaceParser::ReadKey() { SkipWhite(); @@ -1128,7 +1131,7 @@ int SpaceParser::ReadChar() case 'b': lastc = 0x08; break; case 'f': lastc = 0x0c; break; case 'u': ReadUnicodeCodePoint(); break; - // in other cases we return the last character + // "in other cases we return the last character, so two \\ returns one \ " } } From 679b9e61734db50c2c5c83b595cf5ad86b285417 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 18 Mar 2021 17:19:36 +0100 Subject: [PATCH 20/67] added some indentation when printing 'pretty Space format' --- space/space.h | 115 +++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/space/space.h b/space/space.h index 8647527..5af887e 100644 --- a/space/space.h +++ b/space/space.h @@ -336,49 +336,16 @@ public: void serialize_to_space_to(std::wstring & str, bool pretty_print = false) const; template - void serialize_to_space_stream(StreamType & str, bool pretty_print = false, bool is_main_object = true) const + void serialize_to_space_stream(StreamType & str, bool pretty_print = false) const { - switch(type) + if( is_object() ) { - case type_null: - serialize_space_null(str); - break; - - case type_bool: - serialize_space_bool(str); - break; - - case type_long: - serialize_space_long(str); - break; - - case type_float: - serialize_space_float(str); - break; - - case type_double: - serialize_space_double(str); - break; - - case type_string: - serialize_space_string(str); - break; - - case type_wstring: - serialize_space_wstring(str); - break; - - case type_object: - serialize_space_object(str, pretty_print, is_main_object); - break; - - case type_table: - serialize_space_table(str, pretty_print); - break; + serialize_to_space_stream(str, pretty_print, -1, true); } } + std::string serialize_to_json_str() const; std::wstring serialize_to_json_wstr() const; void serialize_to_json_to(std::string & str) const; @@ -669,7 +636,7 @@ protected: } template - void serialize_space_object(StreamType & str, bool pretty_print, bool is_main_object) const + void serialize_space_object(StreamType & str, bool pretty_print, int level, bool is_main_object) const { if( !is_main_object ) { @@ -686,6 +653,7 @@ protected: bool quote_field = should_field_be_quoted(map_item.first); + print_level(pretty_print, level, str); print_if(quote_field, str, '"'); serialize_string_buffer(map_item.first.c_str(), str, Escape::escape_space); print_if(quote_field, str, '"'); @@ -694,15 +662,16 @@ protected: str << '='; print_if(pretty_print, str, ' '); - map_item.second->serialize_to_space_stream(str, pretty_print, false); + map_item.second->serialize_to_space_stream(str, pretty_print, level + 1, false); is_first = false; } print_if(!is_first && pretty_print, str, '\n'); - serialize_child_spaces(str, pretty_print); + serialize_child_spaces(str, pretty_print, level); if( !is_main_object ) { + print_level(pretty_print, level - 2, str); str << '}'; print_if(pretty_print, str, '\n'); } @@ -710,7 +679,7 @@ protected: template - void serialize_child_spaces(StreamType & str, bool pretty_print) const + void serialize_child_spaces(StreamType & str, bool pretty_print, int level) const { if( child_spaces && !child_spaces->empty() ) { @@ -724,6 +693,7 @@ protected: { bool quote_field = should_field_be_quoted(*child_space->name); + print_level(pretty_print, level, str); print_if(quote_field, str, '"'); serialize_string_buffer(child_space->name->c_str(), str, Escape::escape_space); print_if(quote_field, str, '"'); @@ -731,7 +701,7 @@ protected: str << ' '; } - child_space->serialize_to_space_stream(str, pretty_print, false); + child_space->serialize_to_space_stream(str, pretty_print, level + 1, false); print_if(pretty_print, str, '\n'); } } @@ -739,7 +709,7 @@ protected: template - void serialize_space_table(StreamType & str, bool pretty_print) const + void serialize_space_table(StreamType & str, bool pretty_print, int level) const { bool multivalue_table = false; bool is_first = true; @@ -757,11 +727,13 @@ protected: if( !is_first ) print_if(pretty_print, str, '\n', ','); - space->serialize_to_space_stream(str, pretty_print, false); + print_level(pretty_print && multivalue_table, level, str); + space->serialize_to_space_stream(str, pretty_print, level + 1, false); is_first = false; } print_if(pretty_print && multivalue_table, str, '\n'); + print_level(pretty_print && multivalue_table, level - 2, str); str << ')'; } @@ -924,6 +896,50 @@ public: protected: + template + void serialize_to_space_stream(StreamType & str, bool pretty_print, int level, bool is_main_object) const + { + switch(type) + { + case type_null: + serialize_space_null(str); + break; + + case type_bool: + serialize_space_bool(str); + break; + + case type_long: + serialize_space_long(str); + break; + + case type_float: + serialize_space_float(str); + break; + + case type_double: + serialize_space_double(str); + break; + + case type_string: + serialize_space_string(str); + break; + + case type_wstring: + serialize_space_wstring(str); + break; + + case type_object: + serialize_space_object(str, pretty_print, level + 1, is_main_object); + break; + + case type_table: + serialize_space_table(str, pretty_print, level + 1); + break; + } + } + + template bool should_field_be_quoted(StringType & str) const { @@ -944,6 +960,17 @@ protected: } + template + void print_level(bool pretty_print, int level, StreamType & str) const + { + if( pretty_print ) + { + for(int i=0 ; i < level ; ++i) + { + str << ' '; + } + } + } template From 539faa4976d98e4d16c57575888ad3b4c8d448de Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 18 Mar 2021 17:28:11 +0100 Subject: [PATCH 21/67] changed the indentation algorithm when pretty printing the space format (no visual changes) --- space/space.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/space/space.h b/space/space.h index 5af887e..83cc5b3 100644 --- a/space/space.h +++ b/space/space.h @@ -340,7 +340,7 @@ public: { if( is_object() ) { - serialize_to_space_stream(str, pretty_print, -1, true); + serialize_to_space_stream(str, pretty_print, 0, true); } } @@ -671,7 +671,7 @@ protected: if( !is_main_object ) { - print_level(pretty_print, level - 2, str); + print_level(pretty_print, level - 1, str); str << '}'; print_if(pretty_print, str, '\n'); } @@ -733,7 +733,7 @@ protected: } print_if(pretty_print && multivalue_table, str, '\n'); - print_level(pretty_print && multivalue_table, level - 2, str); + print_level(pretty_print && multivalue_table, level - 1, str); str << ')'; } @@ -930,11 +930,11 @@ protected: break; case type_object: - serialize_space_object(str, pretty_print, level + 1, is_main_object); + serialize_space_object(str, pretty_print, level, is_main_object); break; case type_table: - serialize_space_table(str, pretty_print, level + 1); + serialize_space_table(str, pretty_print, level); break; } } @@ -967,7 +967,7 @@ protected: { for(int i=0 ; i < level ; ++i) { - str << ' '; + str << ' ' << ' '; } } } From 1c643a08b02aff5a5231eda9af8ffbaf91d5eaca Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 18 Mar 2021 17:55:30 +0100 Subject: [PATCH 22/67] added a test whether we have reach the end of the input string without this such an input json (incorrect json string as there is no {} characters): "key": "value" would be parsed correctly: "key" would be parsed and the rest would be skipped --- space/spaceparser.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/space/spaceparser.cpp b/space/spaceparser.cpp index 09bd6b6..6ec23e7 100644 --- a/space/spaceparser.cpp +++ b/space/spaceparser.cpp @@ -323,6 +323,11 @@ void SpaceParser::ParseRootSpace() Parse(root_space, false, false); } + SkipWhite(); + + if( lastc != -1 ) + status = syntax_error; + token.clear(); } From 0aeac12fa0d81904859214bcfe8ebee3ec62d5cb Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 8 Apr 2021 17:02:27 +0200 Subject: [PATCH 23/67] make depend --- Makefile.dep | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Makefile.dep b/Makefile.dep index 0e52a4b..c472605 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -19,20 +19,18 @@ ./mainspaceparser/mainspaceparser.o: membuffer/membuffer.h textstream/types.h ./mainspaceparser/mainspaceparser.o: utf8/utf8_templates.h ./mainspaceparser/mainspaceparser.o: utf8/utf8_private.h -./space/spaceparser.o: ./space/spaceparser.h ./space/space.h -./space/spaceparser.o: textstream/types.h convert/inttostr.h utf8/utf8.h -./space/spaceparser.o: textstream/textstream.h space/space.h date/date.h -./space/spaceparser.o: membuffer/membuffer.h textstream/types.h -./space/spaceparser.o: utf8/utf8_templates.h utf8/utf8_private.h -./space/spaceparser.o: convert/strtoint.h ./convert/text.h ./convert/misc.h ./space/space.o: ./space/space.h textstream/types.h convert/inttostr.h ./space/space.o: utf8/utf8.h textstream/textstream.h space/space.h ./space/space.o: date/date.h membuffer/membuffer.h textstream/types.h ./space/space.o: utf8/utf8_templates.h utf8/utf8_private.h convert/convert.h ./space/space.o: ./convert/inttostr.h convert/patternreplacer.h ./space/space.o: convert/strtoint.h ./convert/text.h ./convert/misc.h -./space/spacetojson.o: ./space/spacetojson.h ./space/space.h -./space/spacetojson.o: textstream/types.h convert/inttostr.h +./space/spaceparser.o: ./space/spaceparser.h ./space/space.h +./space/spaceparser.o: textstream/types.h convert/inttostr.h utf8/utf8.h +./space/spaceparser.o: textstream/textstream.h space/space.h date/date.h +./space/spaceparser.o: membuffer/membuffer.h textstream/types.h +./space/spaceparser.o: utf8/utf8_templates.h utf8/utf8_private.h +./space/spaceparser.o: convert/strtoint.h ./convert/text.h ./convert/misc.h ./utf8/utf8.o: ./utf8/utf8.h textstream/textstream.h space/space.h ./utf8/utf8.o: textstream/types.h convert/inttostr.h date/date.h ./utf8/utf8.o: membuffer/membuffer.h textstream/types.h utf8/utf8_templates.h From a2339eed347f69232aeb9d006e334c7b7ba85422 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 8 Apr 2021 17:16:37 +0200 Subject: [PATCH 24/67] fixed: in Space: pointers 'name' and 'child_spaces' were not correctly initialized in cctors added in Space: - some methods for adding values to an object, such as: Space & Space::add(const std::wstring & field, bool val) (bool, short, int, long, long long etc.) - methods for creating lists: void Space::to_list(std::list & output_list, bool clear_list) const bool Space::to_list(const wchar_t * field, std::list & output_list, bool clear_list) const - methods for converting a value from an object field: bool Space::to_bool(const wchar_t * field, bool default_value) const - methods for testing strings: bool Space::is_equal(const char * val) const bool Space::is_equal(const std::string & val) const bool Space::is_equal(const wchar_t * val) const bool Space::is_equal(const std::wstring & val) const - methods to get the raw pointer to a value from an object, such as: bool * Space::get_bool(const wchar_t * field) float * Space::get_float(const wchar_t * field) - methods for finding a child space (used in Space format only) Space * Space::find_child_space(const wchar_t * name) Space & Space::find_add_child_space(const wchar_t * name) --- space/space.cpp | 780 +++++++++++++++++++++++++++++++++++++++- space/space.h | 349 +++++++++++++++--- space/spaceparser.cpp | 13 +- textstream/textstream.h | 2 +- 4 files changed, 1087 insertions(+), 57 deletions(-) diff --git a/space/space.cpp b/space/space.cpp index 4a4fef2..ba64913 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -49,14 +49,13 @@ namespace PT Space::Space() { - type = type_null; - child_spaces = nullptr; - name = nullptr; + initialize(); } Space::Space(const Space & space) { + initialize(); copy_from(space); } @@ -78,84 +77,100 @@ Space::~Space() Space::Space(bool val) { + initialize(); set(val); } Space::Space(short val) { + initialize(); set(val); } Space::Space(int val) { + initialize(); set(val); } Space::Space(long val) { + initialize(); set(val); } Space::Space(long long val) { + initialize(); set(val); } Space::Space(unsigned short val) { + initialize(); set(val); } Space::Space(unsigned int val) { + initialize(); set(val); } Space::Space(unsigned long val) { + initialize(); set(val); } Space::Space(unsigned long long val) { + initialize(); set(val); } Space::Space(float val) { + initialize(); set(val); } Space::Space(double val) { + initialize(); set(val); } Space::Space(const char * str) { + initialize(); set(str); } Space::Space(const wchar_t * str) { + initialize(); set(str); } Space::Space(const std::string & str) { + initialize(); set(str); } Space::Space(const std::wstring & str) { + initialize(); set(str); } Space::Space(const Space * space) { + initialize(); set(space); } @@ -387,6 +402,10 @@ Space & Space::add(const Space * space) return add_generic(space); } +Space & Space::add_empty_space() +{ + return add_generic(static_cast(nullptr)); +} @@ -476,6 +495,99 @@ Space & Space::add_empty_space(const wchar_t * field) return add_generic(field, static_cast(nullptr)); } + + + +Space & Space::add(const std::wstring & field, bool val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, short val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, int val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, long long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, unsigned short val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, unsigned int val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, unsigned long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, unsigned long long val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, float val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, double val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, const char * val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, const wchar_t * val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, const std::string & val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, const std::wstring & val) +{ + return add_generic(field, val); +} + +Space & Space::add(const std::wstring & field, const Space * space) +{ + return add_generic(field, space); +} + +Space & Space::add_empty_space(const std::wstring & field) +{ + return add_generic(field, static_cast(nullptr)); +} + + + + + + Space & Space::add_child_space(const wchar_t * space_name) { initialize_child_spaces_if_needed(); @@ -554,6 +666,9 @@ bool Space::is_table() const bool Space::to_bool() const { + if( type == type_bool ) + return value.value_bool; + long long val = to_long_long(); return (val != 0) ? true : false; } @@ -737,9 +852,7 @@ std::wstring Space::to_wstr() const if( type == type_string ) { - PT::WTextStream stream; - serialize_string_buffer(value.value_string.c_str(), stream, Escape::no_escape); - stream.to_string(str); + PT::UTF8ToWide(value.value_string, str); return str; } @@ -748,6 +861,314 @@ std::wstring Space::to_wstr() const } + + +void Space::to_list(std::list & output_list, bool clear_list) const +{ + to_list_str_generic(output_list, clear_list); +} + + +void Space::to_list(std::list & output_list, bool clear_list) const +{ + to_list_wstr_generic(output_list, clear_list); +} + + +void Space::to_list(std::vector & output_list, bool clear_list) const +{ + to_list_str_generic(output_list, clear_list); +} + + +void Space::to_list(std::vector & output_list, bool clear_list) const +{ + to_list_wstr_generic(output_list, clear_list); +} + + + + + +bool Space::to_bool(const wchar_t * field, bool default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_bool() : default_value; +} + +short Space::to_short(const wchar_t * field, short default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_short() : default_value; +} + +int Space::to_int(const wchar_t * field, int default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_int() : default_value; +} + +long Space::to_long(const wchar_t * field, long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_long() : default_value; +} + +long long Space::to_llong(const wchar_t * field, long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_llong() : default_value; +} + +long long Space::to_long_long(const wchar_t * field, long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_long_long() : default_value; +} + +unsigned short Space::to_ushort(const wchar_t * field, unsigned short default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ushort() : default_value; +} + +unsigned int Space::to_uint(const wchar_t * field, unsigned int default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_uint() : default_value; +} + +unsigned long Space::to_ulong(const wchar_t * field, unsigned long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ulong() : default_value; +} + +unsigned long long Space::to_ullong(const wchar_t * field, unsigned long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ullong() : default_value; +} + +unsigned long long Space::to_ulong_long(const wchar_t * field, unsigned long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ulong_long() : default_value; +} + +std::string Space::to_str(const wchar_t * field, const char * default_value) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->to_str(); + } + + if( default_value ) + { + return std::string(default_value); + } + + return std::string(); +} + + +std::string Space::to_str(const wchar_t * field, const std::string & default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_str() : default_value; +} + + +std::wstring Space::to_wstr(const wchar_t * field, const wchar_t * default_value) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->to_wstr(); + } + + if( default_value ) + { + return std::wstring(default_value); + } + + return std::wstring(); +} + + +std::wstring Space::to_wstr(const wchar_t * field, const std::wstring & default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_wstr() : default_value; +} + + +bool Space::to_list(const wchar_t * field, std::list & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + +bool Space::to_list(const wchar_t * field, std::list & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + + +bool Space::to_list(const std::wstring & field, std::list & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + +bool Space::to_list(const std::wstring & field, std::list & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + + +bool Space::to_list(const wchar_t * field, std::vector & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + +bool Space::to_list(const wchar_t * field, std::vector & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + + +bool Space::to_list(const std::wstring & field, std::vector & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + +bool Space::to_list(const std::wstring & field, std::vector & output_list, bool clear_list) const +{ + return to_list_generic(field, output_list, clear_list); +} + + + +bool Space::to_bool(const std::wstring & field, bool default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_bool() : default_value; +} + +short Space::to_short(const std::wstring & field, short default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_short() : default_value; +} + +int Space::to_int(const std::wstring & field, int default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_int() : default_value; +} + +long Space::to_long(const std::wstring & field, long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_long() : default_value; +} + +long long Space::to_llong(const std::wstring & field, long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_llong() : default_value; +} + +long long Space::to_long_long(const std::wstring & field, long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_long_long() : default_value; +} + +unsigned short Space::to_ushort(const std::wstring & field, unsigned short default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ushort() : default_value; +} + +unsigned int Space::to_uint(const std::wstring & field, unsigned int default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_uint() : default_value; +} + +unsigned long Space::to_ulong(const std::wstring & field, unsigned long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ulong() : default_value; +} + +unsigned long long Space::to_ullong(const std::wstring & field, unsigned long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ullong() : default_value; +} + +unsigned long long Space::to_ulong_long(const std::wstring & field, unsigned long long default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_ulong_long() : default_value; +} + +std::string Space::to_str(const std::wstring & field, const char * default_value) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->to_str(); + } + + if( default_value ) + { + return std::string(default_value); + } + + return std::string(); +} + +std::string Space::to_str(const std::wstring & field, const std::string & default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_str() : default_value; +} + + +std::wstring Space::to_wstr(const std::wstring & field, const wchar_t * default_value) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->to_wstr(); + } + + if( default_value ) + { + return std::wstring(default_value); + } + + return std::wstring(); +} + +std::wstring Space::to_wstr(const std::wstring & field, const std::wstring & default_value) const +{ + const Space * space = get_object_field(field); + return space ? space->to_wstr() : default_value; +} + + + + + + std::string Space::serialize_to_space_str(bool pretty_print) const { std::string str; @@ -843,12 +1264,12 @@ double * Space::get_double() return type == type_double ? &value.value_double : nullptr; } -std::string * Space::get_string() +std::string * Space::get_str() { return type == type_string ? &value.value_string : nullptr; } -std::wstring * Space::get_wstring() +std::wstring * Space::get_wstr() { return type == type_wstring ? &value.value_wstring : nullptr; } @@ -863,6 +1284,121 @@ Space::TableType * Space::get_table() return type == type_table ? &value.value_table : nullptr; } +bool Space::is_equal(const char * val) const +{ + if( type == type_string ) + { + return value.value_string == val; + } + + return false; +} + +bool Space::is_equal(const std::string & val) const +{ + if( type == type_string ) + { + return value.value_string == val; + } + + return false; +} + +bool Space::is_equal(const wchar_t * val) const +{ + if( type == type_wstring ) + { + return value.value_wstring == val; + } + + return false; +} + +bool Space::is_equal(const std::wstring & val) const +{ + if( type == type_wstring ) + { + return value.value_wstring == val; + } + + return false; +} + + + + + + + + +Space * Space::get_object_field(const wchar_t * field) +{ + if( is_object() ) + { + ObjectType::iterator i = value.value_object.find(field); + + if( i != value.value_object.end() ) + { + return i->second; + } + } + + return nullptr; +} + +bool * Space::get_bool(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_bool() : nullptr; +} + +long long * Space::get_llong(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_llong() : nullptr; +} + +long long * Space::get_long_long(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_long_long() : nullptr; +} + +float * Space::get_float(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_float() : nullptr; +} + +double * Space::get_double(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_double() : nullptr; +} + +std::string * Space::get_str(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_str() : nullptr; +} + +std::wstring * Space::get_wstr(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_wstr() : nullptr; +} + +Space::ObjectType * Space::get_object(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_object() : nullptr; +} + +Space::TableType * Space::get_table(const wchar_t * field) +{ + Space * space = get_object_field(field); + return space ? space->get_table() : nullptr; +} @@ -892,12 +1428,12 @@ const double * Space::get_double() const return type == type_double ? &value.value_double : nullptr; } -const std::string * Space::get_string() const +const std::string * Space::get_str() const { return type == type_string ? &value.value_string : nullptr; } -const std::wstring * Space::get_wstring() const +const std::wstring * Space::get_wstr() const { return type == type_wstring ? &value.value_wstring : nullptr; } @@ -914,6 +1450,221 @@ const Space::TableType * Space::get_table() const +bool Space::has_key(const wchar_t * field) const +{ + return get_object_field(field) != nullptr; +} + +bool Space::has_key(const std::wstring & field) const +{ + return get_object_field(field) != nullptr; +} + + + + +const Space * Space::get_object_field(const wchar_t * field) const +{ + if( is_object() ) + { + ObjectType::const_iterator i = value.value_object.find(field); + + if( i != value.value_object.end() ) + { + return i->second; + } + } + + return nullptr; +} + + +const Space * Space::get_object_field(const std::wstring & field) const +{ + return get_object_field(field.c_str()); +} + + +const bool * Space::get_bool(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_bool() : nullptr; +} + +const long long * Space::get_llong(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_llong() : nullptr; +} + +const long long * Space::get_long_long(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_long_long() : nullptr; +} + +const float * Space::get_float(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_float() : nullptr; +} + +const double * Space::get_double(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_double() : nullptr; +} + +const std::string * Space::get_str(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_str() : nullptr; +} + +const std::wstring * Space::get_wstr(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_wstr() : nullptr; +} + +const Space::ObjectType * Space::get_object(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_object() : nullptr; +} + +const Space::TableType * Space::get_table(const wchar_t * field) const +{ + const Space * space = get_object_field(field); + return space ? space->get_table() : nullptr; +} + + + +void Space::remove(const wchar_t * field) +{ + remove(std::wstring(field)); +} + + +void Space::remove(const std::wstring & field) +{ + if( type == type_object ) + { + ObjectType::iterator i = value.value_object.find(field); + + if( i != value.value_object.end() ) + { + delete i->second; + i->second = nullptr; + + value.value_object.erase(i); + } + } +} + + +bool Space::is_equal(const wchar_t * field, const char * val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->is_equal(val); + } + + return false; +} + +bool Space::is_equal(const wchar_t * field, const std::string & val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->is_equal(val); + } + + return false; +} + + +bool Space::is_equal(const wchar_t * field, const wchar_t * val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->is_equal(val); + } + + return false; +} + + +bool Space::is_equal(const wchar_t * field, const std::wstring & val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->is_equal(val); + } + + return false; +} + + + + + +Space * Space::find_child_space(const wchar_t * name) +{ + return find_child_space_generic(name); +} + +Space * Space::find_child_space(const std::wstring & name) +{ + return find_child_space_generic(name); +} + + +const Space * Space::find_child_space(const wchar_t * name) const +{ + return find_child_space_generic(name); +} + + +const Space * Space::find_child_space(const std::wstring & name) const +{ + return find_child_space_generic(name); +} + + + +Space & Space::find_add_child_space(const wchar_t * name) +{ + Space * space = find_child_space(name); + + if( !space ) + { + return add_child_space(name); + } + + return *space; +} + + +Space & Space::find_add_child_space(const std::wstring & name) +{ + return find_add_child_space(name.c_str()); +} + + + + + + void Space::copy_value_from(const Space & space) { @@ -1037,6 +1788,13 @@ void Space::copy_value_table(const Value & value_from) } +void Space::initialize() +{ + type = type_null; + child_spaces = nullptr; + name = nullptr; +} + void Space::initialize_value_null_if_needed() { if( type != type_null ) @@ -1259,6 +2017,8 @@ void Space::remove_space_name() + + } // namespace diff --git a/space/space.h b/space/space.h index 83cc5b3..eaea946 100644 --- a/space/space.h +++ b/space/space.h @@ -39,13 +39,14 @@ #define headerfile_picotools_space_space #include +#include #include #include #include #include #include "textstream/types.h" #include "convert/inttostr.h" -//#include "utf8/utf8.h" + @@ -251,6 +252,9 @@ public: Space & add(const std::string & val); Space & add(const std::wstring & val); Space & add(const Space * space); + Space & add_empty_space(); // IMPROVEME rename me to something better + + // add a value to the object, change to object if needed, return the reference to the new inserted item Space & add(const wchar_t * field, bool val); @@ -271,10 +275,51 @@ public: Space & add(const wchar_t * field, const Space * space); Space & add_empty_space(const wchar_t * field); // IMPROVEME rename me to something better + Space & add(const std::wstring & field, bool val); + Space & add(const std::wstring & field, short val); + Space & add(const std::wstring & field, int val); + Space & add(const std::wstring & field, long val); + Space & add(const std::wstring & field, long long val); + Space & add(const std::wstring & field, unsigned short val); + Space & add(const std::wstring & field, unsigned int val); + Space & add(const std::wstring & field, unsigned long val); + Space & add(const std::wstring & field, unsigned long long val); + Space & add(const std::wstring & field, float val); + Space & add(const std::wstring & field, double val); + Space & add(const std::wstring & field, const char * val); + Space & add(const std::wstring & field, const wchar_t * val); + Space & add(const std::wstring & field, const std::string & val); + Space & add(const std::wstring & field, const std::wstring & val); + Space & add(const std::wstring & field, const Space * space); + Space & add_empty_space(const std::wstring & field); // IMPROVEME rename me to something better + + // for child spaces (used only in Space format) + // rename to something better Space & add_child_space(const wchar_t * space_name); + // IMPROVEME add a similar 'set' method and cctor + template + Space & add_stream(const wchar_t * field, StreamType & str) + { + std::wstring temp; + str.to_string(temp); + + return add(field, temp); + } + + template + Space & add_stream(const std::wstring & field, StreamType & str) + { + std::wstring temp; + str.to_string(temp); + + return add(field, temp); + } + + + bool is_null() const; bool is_bool() const; bool is_llong() const; @@ -304,6 +349,59 @@ public: std::string to_str() const; std::wstring to_wstr() const; + void to_list(std::list & output_list, bool clear_list = true) const; + void to_list(std::list & output_list, bool clear_list = true) const; + void to_list(std::vector & output_list, bool clear_list = true) const; + void to_list(std::vector & output_list, bool clear_list = true) const; + + + // returns value from object, field is a key + bool to_bool(const wchar_t * field, bool default_value = false) const; + short to_short(const wchar_t * field, short default_value = 0) const; + int to_int(const wchar_t * field, int default_value = 0) const; + long to_long(const wchar_t * field, long default_value = 0) const; + long long to_llong(const wchar_t * field, long long default_value = 0) const; + long long to_long_long(const wchar_t * field, long long default_value = 0) const; + unsigned short to_ushort(const wchar_t * field, unsigned short default_value = 0) const; + unsigned int to_uint(const wchar_t * field, unsigned int default_value = 0) const; + unsigned long to_ulong(const wchar_t * field, unsigned long default_value = 0) const; + unsigned long long to_ullong(const wchar_t * field, unsigned long long default_value = 0) const; + unsigned long long to_ulong_long(const wchar_t * field, unsigned long long default_value = 0) const; + std::string to_str(const wchar_t * field, const char * default_value = nullptr) const; + std::string to_str(const wchar_t * field, const std::string & default_value) const; + std::wstring to_wstr(const wchar_t * field, const wchar_t * default_value = nullptr) const; + std::wstring to_wstr(const wchar_t * field, const std::wstring & default_value) const; + + bool to_list(const wchar_t * field, std::list & output_list, bool clear_list = true) const; + bool to_list(const wchar_t * field, std::list & output_list, bool clear_list = true) const; + bool to_list(const std::wstring & field, std::list & output_list, bool clear_list = true) const; + bool to_list(const std::wstring & field, std::list & output_list, bool clear_list = true) const; + + bool to_list(const wchar_t * field, std::vector & output_list, bool clear_list = true) const; + bool to_list(const wchar_t * field, std::vector & output_list, bool clear_list = true) const; + bool to_list(const std::wstring & field, std::vector & output_list, bool clear_list = true) const; + bool to_list(const std::wstring & field, std::vector & output_list, bool clear_list = true) const; + + // returns value from object, field is a key + bool to_bool(const std::wstring & field, bool default_value = false) const; + short to_short(const std::wstring & field, short default_value = 0) const; + int to_int(const std::wstring & field, int default_value = 0) const; + long to_long(const std::wstring & field, long default_value = 0) const; + long long to_llong(const std::wstring & field, long long default_value = 0) const; + long long to_long_long(const std::wstring & field, long long default_value = 0) const; + unsigned short to_ushort(const std::wstring & field, unsigned short default_value = 0) const; + unsigned int to_uint(const std::wstring & field, unsigned int default_value = 0) const; + unsigned long to_ulong(const std::wstring & field, unsigned long default_value = 0) const; + unsigned long long to_ullong(const std::wstring & field, unsigned long long default_value = 0) const; + unsigned long long to_ulong_long(const std::wstring & field, unsigned long long default_value = 0) const; + std::string to_str(const std::wstring & field, const char * default_value = nullptr) const; + std::string to_str(const std::wstring & field, const std::string & default_value) const; + std::wstring to_wstr(const std::wstring & field, const wchar_t * default_value = nullptr) const; + std::wstring to_wstr(const std::wstring & field, const std::wstring & default_value) const; + + + bool to_str_list(std::list & output_list) const; + bool to_wstr_list(std::list & output_list) const; bool * get_bool(); @@ -311,11 +409,36 @@ public: long long * get_long_long(); float * get_float(); double * get_double(); - std::string * get_string(); - std::wstring * get_wstring(); + std::string * get_str(); + std::wstring * get_wstr(); ObjectType * get_object(); TableType * get_table(); + bool is_equal(const char * val) const; + bool is_equal(const std::string & val) const; + bool is_equal(const wchar_t * val) const; + bool is_equal(const std::wstring & val) const; + // add these is_equal with std::wstring + + + // what about getters from tables? + // may something like: Space * get_table_item(size_t index)? + // and get_table_bool(size_t index) + // or just only get_bool(size_t index)? + // size_t argument will be only for tables, wchar_t* or std::wstring for objects? + + // getters from object + Space * get_object_field(const wchar_t * field); // may a better name? + bool * get_bool(const wchar_t * field); + long long * get_llong(const wchar_t * field); + long long * get_long_long(const wchar_t * field); + float * get_float(const wchar_t * field); + double * get_double(const wchar_t * field); + std::string * get_str(const wchar_t * field); + std::wstring * get_wstr(const wchar_t * field); + ObjectType * get_object(const wchar_t * field); + TableType * get_table(const wchar_t * field); + // add these getters with std::wstring const bool * get_bool() const; @@ -323,11 +446,32 @@ public: const long long * get_long_long() const; const float * get_float() const; const double * get_double() const; - const std::string * get_string() const; - const std::wstring * get_wstring() const; + const std::string * get_str() const; + const std::wstring * get_wstr() const; const ObjectType * get_object() const; const TableType * get_table() const; + bool has_key(const wchar_t * field) const; // may has_key() would be a better name? + bool has_key(const std::wstring & field) const; + + const Space * get_object_field(const wchar_t * field) const; // may a better name? + const Space * get_object_field(const std::wstring & field) const; // may a better name? + + const bool * get_bool(const wchar_t * field) const; + const long long * get_llong(const wchar_t * field) const; + const long long * get_long_long(const wchar_t * field) const; + const float * get_float(const wchar_t * field) const; + const double * get_double(const wchar_t * field) const; + const std::string * get_str(const wchar_t * field) const; + const std::wstring * get_wstr(const wchar_t * field) const; + const ObjectType * get_object(const wchar_t * field) const; + const TableType * get_table(const wchar_t * field) const; + // add these getters with std::wstring + + + // remove a field from an object + void remove(const wchar_t * field); + void remove(const std::wstring & field); std::string serialize_to_space_str(bool pretty_print = false) const; @@ -353,7 +497,7 @@ public: template - void serialize_to_json_stream(StreamType & str) const + void serialize_to_json_stream(StreamType & str, bool pretty_print = false) const { switch(type) { @@ -396,11 +540,26 @@ public: } + bool is_equal(const wchar_t * field, const char * val) const; + bool is_equal(const wchar_t * field, const std::string & val) const; + bool is_equal(const wchar_t * field, const wchar_t * val) const; + bool is_equal(const wchar_t * field, const std::wstring & val) const; + // add these is_equal with std::wstring + + + Space * find_child_space(const wchar_t * name); + Space * find_child_space(const std::wstring & name); + const Space * find_child_space(const wchar_t * name) const; + const Space * find_child_space(const std::wstring & name) const; + + Space & find_add_child_space(const wchar_t * name); + Space & find_add_child_space(const std::wstring & name); + protected: template - Space & add_generic(ArgType val) + Space & add_generic(const ArgType & val) { initialize_value_table_if_needed(); @@ -412,7 +571,7 @@ protected: template - Space & add_generic(const wchar_t * field, ArgType val) + Space & add_generic(const wchar_t * field, const ArgType & val) { initialize_value_object_if_needed(); @@ -423,6 +582,13 @@ protected: } + template + Space & add_generic(const std::wstring & field, const ArgType & val) + { + return add_generic(field.c_str(), val); + } + + template ArgType to_generic_numeric_signed_value() const { @@ -452,6 +618,129 @@ protected: unsigned long long convert_wstring_to_ulong_long() const; + template + void to_list_str_generic(ListType & output_list, bool clear_list) const + { + if( clear_list ) + output_list.clear(); + + if( type == type_string ) + { + output_list.push_back(value.value_string); + } + else + if( type == type_table ) + { + for(size_t i = 0 ; i < value.value_table.size() ; ++i) + { + output_list.push_back(value.value_table[i]->to_str()); + } + } + else + { + output_list.push_back(to_str()); + } + } + + + template + void to_list_wstr_generic(ListType & output_list, bool clear_list) const + { + if( clear_list ) + output_list.clear(); + + if( type == type_wstring ) + { + output_list.push_back(value.value_wstring); + } + else + if( type == type_table ) + { + for(size_t i = 0 ; i < value.value_table.size() ; ++i) + { + output_list.push_back(value.value_table[i]->to_wstr()); + } + } + else + { + output_list.push_back(to_wstr()); + } + } + + template + bool to_list_generic(const wchar_t * field, ListType & output_list, bool clear_list) const + { + if( clear_list ) + output_list.clear(); + + const Space * space = get_object_field(field); + + if( space ) + { + space->to_list(output_list, false); + return true; + } + + return false; + } + + + template + bool to_list_generic(const std::wstring & field, ListType & output_list, bool clear_list) const + { + if( clear_list ) + output_list.clear(); + + const Space * space = get_object_field(field); + + if( space ) + { + space->to_list(output_list, false); + return true; + } + + return false; + } + + + template + Space * find_child_space_generic(const ArgType & name) + { + if( child_spaces ) + { + for(size_t i = 0 ; i < child_spaces->size() ; ++i) + { + Space * space = (*child_spaces)[i]; + + if( space->name && *space->name == name ) + { + return space; + } + } + } + + return nullptr; + } + + + template + Space * find_child_space_generic(const ArgType & name) const + { + if( child_spaces ) + { + for(size_t i = 0 ; i < child_spaces->size() ; ++i) + { + Space * space = (*child_spaces)[i]; + + if( space->name && *space->name == name ) + { + return space; + } + } + } + + return nullptr; + } template @@ -531,11 +820,14 @@ protected: } else { - StreamType temp_stream; - // input is utf8 but output is wide - UTF8ToWide(input_str, temp_stream, false); - copy_input_stream_to_output(temp_stream, out_str, escape); + copy_input_string_to_output(input_str, out_str, escape); // temporarily + + // !!!!!!!!!!!!!!!!!!! FIXME +// StreamType temp_stream; +// UTF8ToWide(input_str, temp_stream, false); +// +// copy_input_stream_to_output(temp_stream, out_str, escape); } } @@ -862,38 +1154,6 @@ protected: } -public: - - - ///////////////////////////// remove me - - template - void Serialize(Stream & out, bool use_indents = false, bool use_comments = false, int level = 0) const - { - } - - template - void SerializeTableMulti(Stream & out, bool use_indents, int level) const - { - } - - template - static void PrintValue(Stream & out, const StringType & str, bool use_quote = true) - { - } - - template - static void PrintKey(Stream & out, const std::wstring & str) - { - } - - template - static void PrintLevel(Stream & out, bool use_indents, int level) - { - } - ///////////////////////////// - - protected: template @@ -998,6 +1258,7 @@ protected: void copy_value_object(const Value & value_from); void copy_value_table(const Value & value_from); + void initialize(); void initialize_value_null_if_needed(); void initialize_value_bool_if_needed(); void initialize_value_long_if_needed(); diff --git a/space/spaceparser.cpp b/space/spaceparser.cpp index 6ec23e7..4e19a10 100644 --- a/space/spaceparser.cpp +++ b/space/spaceparser.cpp @@ -431,7 +431,7 @@ void SpaceParser::ParseSpace(Space * space) void SpaceParser::ParseTextValue(Space * space) { space->set_empty_wstring(); - std::wstring * str = space->get_wstring(); + std::wstring * str = space->get_wstr(); if( parsing_space ) ReadMultilineTokenQuoted(*str); @@ -444,8 +444,17 @@ void SpaceParser::ParseIntegerValue(Space * space) { const wchar_t * after_str = nullptr; bool was_overflow = false; + int base = 10; - long long val = Toll(token.c_str(), 10, &after_str, &was_overflow, false); + if( parsing_space ) + { + // in Space format when the integer value begins with a zero it means + // this is an octal number + if( !token.empty() && token[0] == '0' ) + base = 8; + } + + long long val = Toll(token.c_str(), base, &after_str, &was_overflow, false); if( was_overflow ) { diff --git a/textstream/textstream.h b/textstream/textstream.h index 35f02cf..9b49589 100644 --- a/textstream/textstream.h +++ b/textstream/textstream.h @@ -471,7 +471,7 @@ template TextStreamBase & TextStreamBase::operator<<(const PT::Space & space) { - space.Serialize(*this, true, false); + space.serialize_to_space_stream(*this, true); return *this; } From a1e8f13f46e866cf9ff5f28fbdf9939ff8a68631 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 8 Apr 2021 17:40:30 +0200 Subject: [PATCH 25/67] fixed: calculating buffer length in Space: sizeof(char) -> sizeof(wchar_t) --- space/space.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/space/space.h b/space/space.h index eaea946..02375e3 100644 --- a/space/space.h +++ b/space/space.h @@ -46,7 +46,7 @@ #include #include "textstream/types.h" #include "convert/inttostr.h" - +#include @@ -877,7 +877,7 @@ protected: void serialize_space_long(StreamType & str) const { wchar_t buffer[50]; - size_t buffer_len = sizeof(buffer) / sizeof(char); + size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); PT::Toa(value.value_long, buffer, buffer_len); serialize_string_buffer(buffer, str, Escape::escape_space); @@ -887,7 +887,7 @@ protected: void serialize_space_float(StreamType & str) const { wchar_t buffer[100]; - size_t buffer_len = sizeof(buffer) / sizeof(char); + size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); int chars_written = std::swprintf(buffer, buffer_len, L"%e", static_cast(value.value_float)); @@ -1057,7 +1057,7 @@ protected: void serialize_json_long(StreamType & str) const { wchar_t buffer[50]; - size_t buffer_len = sizeof(buffer) / sizeof(char); + size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); PT::Toa(value.value_long, buffer, buffer_len); serialize_string_buffer(buffer, str, Escape::escape_json); @@ -1067,7 +1067,7 @@ protected: void serialize_json_float(StreamType & str) const { wchar_t buffer[100]; - size_t buffer_len = sizeof(buffer) / sizeof(char); + size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); int chars_written = std::swprintf(buffer, buffer_len, L"%e", static_cast(value.value_float)); From 5d34db5fcfbade3f933bacf15d58222a7a75a8fd Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 9 Apr 2021 17:49:44 +0200 Subject: [PATCH 26/67] added to Space: - methods for testing a string value if a Space is a string or a table: bool has_value(const char * val) const; bool has_value(const std::string & val) const; bool has_value(const wchar_t * val) const; bool has_value(const std::wstring & val) const; - methods for testing a string value in an object (testing a string or a table): bool has_value(const wchar_t * field, const char * val) const; bool has_value(const wchar_t * field, const std::string & val) const; bool has_value(const wchar_t * field, const wchar_t * val) const; bool has_value(const wchar_t * field, const std::wstring & val) const; - methods for removing a child space: void remove_child_space(const wchar_t * name); void remove_child_space(const std::wstring & name); void remove_child_space(size_t index); --- space/space.cpp | 155 ++++++++++++++++++++++++++++++++++++++++++++++++ space/space.h | 30 +++++++--- 2 files changed, 178 insertions(+), 7 deletions(-) diff --git a/space/space.cpp b/space/space.cpp index ba64913..6130e69 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -1284,6 +1284,8 @@ Space::TableType * Space::get_table() return type == type_table ? &value.value_table : nullptr; } + + bool Space::is_equal(const char * val) const { if( type == type_string ) @@ -1326,6 +1328,65 @@ bool Space::is_equal(const std::wstring & val) const +bool Space::has_value(const char * val) const +{ + if( type == type_string ) + { + return value.value_string == val; + } + + if( type == type_table ) + { + for(size_t i=0 ; i < value.value_table.size() ; ++i) + { + PT::Space * table_item = value.value_table[i]; + + if( table_item->type == type_string ) + { + return table_item->value.value_string == val; + } + } + } + + return false; +} + +bool Space::has_value(const std::string & val) const +{ + return has_value(val.c_str()); +} + + +bool Space::has_value(const wchar_t * val) const +{ + if( type == type_wstring ) + { + return value.value_wstring == val; + } + + if( type == type_table ) + { + for(size_t i=0 ; i < value.value_table.size() ; ++i) + { + PT::Space * table_item = value.value_table[i]; + + if( table_item->type == type_wstring ) + { + return table_item->value.value_wstring == val; + } + } + } + + return false; +} + + +bool Space::has_value(const std::wstring & val) const +{ + return has_value(val.c_str()); +} + + @@ -1618,6 +1679,60 @@ bool Space::is_equal(const wchar_t * field, const std::wstring & val) const +bool Space::has_value(const wchar_t * field, const char * val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->has_value(val); + } + + return false; +} + +bool Space::has_value(const wchar_t * field, const std::string & val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->has_value(val); + } + + return false; +} + + +bool Space::has_value(const wchar_t * field, const wchar_t * val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->has_value(val); + } + + return false; +} + + +bool Space::has_value(const wchar_t * field, const std::wstring & val) const +{ + const Space * space = get_object_field(field); + + if( space ) + { + return space->has_value(val); + } + + return false; +} + + + + + Space * Space::find_child_space(const wchar_t * name) { return find_child_space_generic(name); @@ -1661,6 +1776,46 @@ Space & Space::find_add_child_space(const std::wstring & name) } +void Space::remove_child_space(const wchar_t * name) +{ + if( child_spaces ) + { + for(size_t i=0 ; isize() ; ) + { + PT::Space * child = (*child_spaces)[i]; + + if( child->name && (*child->name) == name ) + { + delete child; + child = nullptr; + child_spaces->erase(child_spaces->begin() + i); + } + else + { + ++i; + } + } + } +} + +void Space::remove_child_space(const std::wstring & name) +{ + return remove_child_space(name.c_str()); +} + + +void Space::remove_child_space(size_t index) +{ + if( child_spaces && index < child_spaces->size() ) + { + PT::Space * child = (*child_spaces)[index]; + delete child; + child = nullptr; + + child_spaces->erase(child_spaces->begin() + index); + } +} + diff --git a/space/space.h b/space/space.h index 02375e3..e8e2c88 100644 --- a/space/space.h +++ b/space/space.h @@ -294,11 +294,6 @@ public: Space & add_empty_space(const std::wstring & field); // IMPROVEME rename me to something better - // for child spaces (used only in Space format) - // rename to something better - Space & add_child_space(const wchar_t * space_name); - - // IMPROVEME add a similar 'set' method and cctor template Space & add_stream(const wchar_t * field, StreamType & str) @@ -414,11 +409,17 @@ public: ObjectType * get_object(); TableType * get_table(); + // may a better name? bool is_equal(const char * val) const; bool is_equal(const std::string & val) const; bool is_equal(const wchar_t * val) const; bool is_equal(const std::wstring & val) const; - // add these is_equal with std::wstring + + // may a better name? + bool has_value(const char * val) const; + bool has_value(const std::string & val) const; + bool has_value(const wchar_t * val) const; + bool has_value(const std::wstring & val) const; // what about getters from tables? @@ -540,21 +541,36 @@ public: } + // add this method with field with std::wstring bool is_equal(const wchar_t * field, const char * val) const; bool is_equal(const wchar_t * field, const std::string & val) const; bool is_equal(const wchar_t * field, const wchar_t * val) const; bool is_equal(const wchar_t * field, const std::wstring & val) const; - // add these is_equal with std::wstring + + // may a better name? + // add this method with field with std::wstring + bool has_value(const wchar_t * field, const char * val) const; + bool has_value(const wchar_t * field, const std::string & val) const; + bool has_value(const wchar_t * field, const wchar_t * val) const; + bool has_value(const wchar_t * field, const std::wstring & val) const; + // for child spaces (used only in Space format) Space * find_child_space(const wchar_t * name); Space * find_child_space(const std::wstring & name); const Space * find_child_space(const wchar_t * name) const; const Space * find_child_space(const std::wstring & name) const; + Space & add_child_space(const wchar_t * space_name); + Space & find_add_child_space(const wchar_t * name); Space & find_add_child_space(const std::wstring & name); + void remove_child_space(const wchar_t * name); + void remove_child_space(const std::wstring & name); + void remove_child_space(size_t index); + + protected: From 297940ff7c6562676130a94ea40888ee48bee7b3 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 12 Apr 2021 18:49:34 +0200 Subject: [PATCH 27/67] fix in SpaceParser when parsing json format: floating point values such as 1.123e+01 where not correctly parsed ('+' character was not correctly parsed) added to Space: some methods for searching a field with ignoring case: Space * get_object_field_nc(const wchar_t * field) Space * get_object_field_nc(const std::wstring & field); const Space * get_object_field_nc(const wchar_t * field) const; const Space * get_object_field_nc(const std::wstring & field) const; --- space/space.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++ space/space.h | 8 +++++++ space/spaceparser.cpp | 2 +- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/space/space.cpp b/space/space.cpp index 6130e69..c1611a9 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -1602,6 +1602,61 @@ const Space::TableType * Space::get_table(const wchar_t * field) const + + +Space * Space::get_object_field_nc(const wchar_t * field) +{ + if( is_object() ) + { + ObjectType::iterator i = value.value_object.begin(); + + while( i != value.value_object.end() ) + { + if( EqualNoCase(field, i->first.c_str()) ) + { + return i->second; + } + } + } + + return nullptr; +} + + +Space * Space::get_object_field_nc(const std::wstring & field) +{ + return get_object_field_nc(field.c_str()); +} + + +const Space * Space::get_object_field_nc(const wchar_t * field) const +{ + if( is_object() ) + { + ObjectType::const_iterator i = value.value_object.cbegin(); + + while( i != value.value_object.cend() ) + { + if( EqualNoCase(field, i->first.c_str()) ) + { + return i->second; + } + } + } + + return nullptr; +} + + +const Space * Space::get_object_field_nc(const std::wstring & field) const +{ + return get_object_field_nc(field.c_str()); +} + + + + + void Space::remove(const wchar_t * field) { remove(std::wstring(field)); diff --git a/space/space.h b/space/space.h index e8e2c88..12c6e6f 100644 --- a/space/space.h +++ b/space/space.h @@ -470,6 +470,14 @@ public: // add these getters with std::wstring + // no case, has O(n) complexity + Space * get_object_field_nc(const wchar_t * field); + Space * get_object_field_nc(const std::wstring & field); + const Space * get_object_field_nc(const wchar_t * field) const; + const Space * get_object_field_nc(const std::wstring & field) const; + + + // remove a field from an object void remove(const wchar_t * field); void remove(const std::wstring & field); diff --git a/space/spaceparser.cpp b/space/spaceparser.cpp index 4e19a10..3c8f9bd 100644 --- a/space/spaceparser.cpp +++ b/space/spaceparser.cpp @@ -737,7 +737,7 @@ bool SpaceParser::is_alfa_numeric_char(int c) return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || - c == '.' || c=='-'; + c == '.' || c=='-' || c=='+'; } From 16f6bdb3588ac790991ea4b737c6edd5b739d8bb Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 14 Apr 2021 17:42:57 +0200 Subject: [PATCH 28/67] fixed: Space::has_value(...) incorrectly compared strings --- space/space.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/space/space.cpp b/space/space.cpp index c1611a9..4db4f1d 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -1343,7 +1343,8 @@ bool Space::has_value(const char * val) const if( table_item->type == type_string ) { - return table_item->value.value_string == val; + if( table_item->value.value_string == val ) + return true; } } } @@ -1372,7 +1373,8 @@ bool Space::has_value(const wchar_t * val) const if( table_item->type == type_wstring ) { - return table_item->value.value_wstring == val; + if( table_item->value.value_wstring == val ) + return true; } } } From f572250572b474bada0cc5e24e97d5511ee02189 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 30 Apr 2021 01:17:29 +0200 Subject: [PATCH 29/67] make depend --- Makefile.dep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.dep b/Makefile.dep index c472605..de16716 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -1,8 +1,8 @@ # DO NOT DELETE +./convert/inttostr.o: ./convert/inttostr.h ./convert/misc.o: ./convert/misc.h ./convert/text.h ./convert/text.o: ./convert/text.h -./convert/inttostr.o: ./convert/inttostr.h ./date/date.o: ./date/date.h convert/inttostr.h ./log/filelog.o: ./log/filelog.h textstream/textstream.h space/space.h ./log/filelog.o: textstream/types.h convert/inttostr.h date/date.h From 96eedd9be9661a1bd6cdfd3241491b854425191f Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 30 Apr 2021 01:17:47 +0200 Subject: [PATCH 30/67] added support for morm::Model to Log: Log & operator<<(morm::Model & model); but we need some kind of a macro to allow this --- log/log.cpp | 10 ++++++++++ log/log.h | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/log/log.cpp b/log/log.cpp index d3903b6..82336e3 100644 --- a/log/log.cpp +++ b/log/log.cpp @@ -41,6 +41,8 @@ #include "date/date.h" #include "utf8/utf8.h" +#include "morm.h" + namespace PT { @@ -311,6 +313,14 @@ Log & Log::operator<<(const PT::Date & date) +Log & Log::operator<<(morm::Model & model) +{ + operator<<(model.to_string()); + return *this; +} + + + Log & Log::operator<<(Manipulators m) { switch(m) diff --git a/log/log.h b/log/log.h index ec1011f..c5d72bb 100644 --- a/log/log.h +++ b/log/log.h @@ -45,6 +45,12 @@ +namespace morm +{ + class Model; +} + + namespace PT { @@ -125,8 +131,14 @@ public: virtual Log & operator<<(const PT::Space & space); virtual Log & operator<<(const PT::Date & date); + virtual Log & operator<<(morm::Model & model); + + virtual Log & operator<<(Manipulators m); + + + virtual Log & LogString(const std::string & value, size_t max_size); virtual Log & LogString(const std::wstring & value, size_t max_size); From 463cec328331e89792334e949dee661723fe52c1 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 7 May 2021 15:53:19 +0200 Subject: [PATCH 31/67] fixed #2: Procedures for reading an utf8 string incorrectly read some utf-8 characters. Those characters were treated as invalid characters. UTF8ToInt_FirstOctet incorrectly checked if the first octed is zero (after removing first bits). This is a case only if the utf-8 character consists of two bytes. For 3 or 4 bytes the first part can have all bits equal zero. --- utf8/utf8.cpp | 42 +++++++++++++++++++++++++++++++++++++++--- utf8/utf8.h | 8 ++++++++ utf8/utf8_private.cpp | 5 +---- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/utf8/utf8.cpp b/utf8/utf8.cpp index b804e1f..6090e59 100644 --- a/utf8/utf8.cpp +++ b/utf8/utf8.cpp @@ -56,6 +56,42 @@ bool UTF8_CheckRange(int c) } +/*! + returns true if 'c' is a correct unicode character + + this method is used when reading from an utf8 string + how_many_bytes - means how many bytes from the utf8 string were read +*/ +bool UTF8_CheckRange(int c, int how_many_bytes) +{ + if( c >= 0x0000 && c <= 0x007f && how_many_bytes == 1 ) + { + return true; + } + + if( c >= 0x0080 && c <= 0x07ff && how_many_bytes == 2 ) + { + return true; + } + + if( c >= 0x0800 && c < 0xD800 && how_many_bytes == 3) + { + return true; + } + + if( c > 0xDFFF && c <= 0xffff && how_many_bytes == 3) + { + return true; + } + + if( c >= 0x10000 && c <= 0x10FFFF && how_many_bytes == 4 ) + { + return true; + } + +return false; +} + /*! @@ -97,7 +133,7 @@ size_t i, len; return i; } - if( UTF8_CheckRange(res) ) + if( UTF8_CheckRange(res, len) ) correct = true; return len; @@ -141,7 +177,7 @@ size_t i, len; return i; } - if( UTF8_CheckRange(res) ) + if( UTF8_CheckRange(res, len) ) correct = true; return len; @@ -210,7 +246,7 @@ unsigned char uz; return i; } - if( UTF8_CheckRange(res) ) + if( UTF8_CheckRange(res, len) ) correct = true; return len; diff --git a/utf8/utf8.h b/utf8/utf8.h index a8c0362..979dd9e 100644 --- a/utf8/utf8.h +++ b/utf8/utf8.h @@ -64,6 +64,14 @@ namespace PT bool UTF8_CheckRange(int c); +/*! + returns true if 'c' is a correct unicode character + + this method is used when reading from an utf8 string + how_many_chars - means how many characters from utf8 string were read +*/ +bool UTF8_CheckRange(int c, int how_many_bytes); + /* * diff --git a/utf8/utf8_private.cpp b/utf8/utf8_private.cpp index cba2dfe..71248d0 100644 --- a/utf8/utf8_private.cpp +++ b/utf8/utf8_private.cpp @@ -52,7 +52,7 @@ bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res) for(len=0 ; (uz & 0x80) != 0 ; ++len) uz <<= 1; - if( len == 1 ) + if( len == 1 || len > 4 ) return false; res = uz; @@ -60,9 +60,6 @@ bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res) if( len > 0 ) res >>= len; - if( res == 0 ) - return false; - if( len == 0 ) len = 1; From b055c46ae8a1939b9362a456badf04fcafac3674 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sat, 8 May 2021 22:37:31 +0200 Subject: [PATCH 32/67] fixed #3: CompareNoCase incorrectly returned that string1 is greater than string2 for some characters when converting from 'char' to 'int' we should first convert to 'unsigned char' and then to 'int' --- convert/text.cpp | 53 ++++++++++++++--------- convert/text.h | 67 ++++++++++++++++++++--------- convert/text_private.h | 96 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 40 deletions(-) create mode 100644 convert/text_private.h diff --git a/convert/text.cpp b/convert/text.cpp index 8fc4370..ebaa175 100644 --- a/convert/text.cpp +++ b/convert/text.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2017-2018, Tomasz Sowa + * Copyright (c) 2017-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -153,42 +153,55 @@ bool IsDigit(wchar_t c, int base, int * digit) -wchar_t ToLower(wchar_t c) +char ToLower(char c) { - if( c >= 'A' && c <= 'Z' ) - return c - 'A' + 'a'; - - return c; + return pt_private::ToLowerGeneric(c); } +wchar_t ToLower(wchar_t c) +{ + return pt_private::ToLowerGeneric(c); +} + + +char ToUpper(char c) +{ + return pt_private::ToUpperGeneric(c); +} wchar_t ToUpper(wchar_t c) { - if( c >= 'a' && c <= 'z' ) - return c - 'a' + 'A'; + return pt_private::ToUpperGeneric(c); - return c; } -void ToLower(std::wstring & s) + + +void ToLower(std::string & str) { - std::wstring::size_type i; - - for(i=0 ; i +#include "text_private.h" @@ -51,6 +51,23 @@ bool IsWhite(wchar_t c, bool check_additional_chars = true, bool treat_new_line_ bool IsDigit(wchar_t c, int base = 10, int * digit = 0); +char ToLower(char c); +wchar_t ToLower(wchar_t c); + +char ToUpper(char c); +wchar_t ToUpper(wchar_t c); + +// rename to something like to_lower_emplace +// and add to_lower which returns string +void ToLower(std::string & str); +void ToLower(std::wstring & str); + +void ToUpper(std::string & str); +void ToUpper(std::wstring & str); + + +//////////////////////////// + template CharType * SkipWhite(CharType * str, bool check_additional_chars = true, bool treat_new_line_as_white = true) { @@ -97,19 +114,6 @@ CharType * SkipWhiteFromBack(CharType * str, bool check_additional_chars = true, } -wchar_t ToLower(wchar_t c); -wchar_t ToUpper(wchar_t c); - - -// change to a template -void ToLower(std::wstring & s); -void ToUpper(std::wstring & s); - - - - - - template int CompareNoCase(const StringType1 * str1, const StringType2 * str2) { @@ -122,7 +126,21 @@ int CompareNoCase(const StringType1 * str1, const StringType2 * str2) if( *str1 == 0 && *str2 == 0 ) return 0; - return (int)ToLower(*str1) - (int)ToLower(*str2); + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = ToLower((wchar_t)(unsigned char)(*str1)); + c2 = ToLower((wchar_t)(unsigned char)(*str2)); + } + else + { + c1 = ToLower(*str1); + c2 = ToLower(*str2); + } + + return c1 - c2; } @@ -154,12 +172,21 @@ int CompareNoCase(const StringType1 * str1_begin, const StringType1 * str1_end, if( str1_begin == str1_end && *str2 == 0 ) return 0; - wchar_t str1_char = 0; + int c1; + int c2; - if( str1_begin < str1_end ) - str1_char = *str1_begin; + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = str1_begin < str1_end ? ToLower((wchar_t)(unsigned char)(*str1_begin)) : 0; + c2 = ToLower((wchar_t)(unsigned char)(*str2)); + } + else + { + c1 = str1_begin < str1_end ? ToLower(*str1_begin) : 0; + c2 = ToLower(*str2); + } - return (int)ToLower(str1_char) - (int)ToLower(*str2); + return c1 - c2; } diff --git a/convert/text_private.h b/convert/text_private.h new file mode 100644 index 0000000..f1007fd --- /dev/null +++ b/convert/text_private.h @@ -0,0 +1,96 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_convert_text_private +#define headerfile_picotools_convert_text_private + +#include + + +namespace PT +{ + +namespace pt_private +{ + +template +CharType ToLowerGeneric(CharType c) +{ + if( c >= 'A' && c <= 'Z' ) + return c - 'A' + 'a'; + + return c; +} + + +template +CharType ToUpperGeneric(CharType c) +{ + if( c >= 'a' && c <= 'z' ) + return c - 'a' + 'A'; + + return c; +} + + +template +void ToLowerStrGeneric(StringType & s) +{ + typename StringType::size_type i; + + for(i=0 ; i +void ToUpperStrGeneric(StringType & s) +{ + typename StringType::size_type i; + + for(i=0 ; i Date: Sat, 8 May 2021 22:40:06 +0200 Subject: [PATCH 33/67] make depend --- Makefile.dep | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Makefile.dep b/Makefile.dep index de16716..4199952 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -1,8 +1,8 @@ # DO NOT DELETE ./convert/inttostr.o: ./convert/inttostr.h -./convert/misc.o: ./convert/misc.h ./convert/text.h -./convert/text.o: ./convert/text.h +./convert/misc.o: ./convert/misc.h ./convert/text.h ./convert/text_private.h +./convert/text.o: ./convert/text.h ./convert/text_private.h ./date/date.o: ./date/date.h convert/inttostr.h ./log/filelog.o: ./log/filelog.h textstream/textstream.h space/space.h ./log/filelog.o: textstream/types.h convert/inttostr.h date/date.h @@ -24,13 +24,15 @@ ./space/space.o: date/date.h membuffer/membuffer.h textstream/types.h ./space/space.o: utf8/utf8_templates.h utf8/utf8_private.h convert/convert.h ./space/space.o: ./convert/inttostr.h convert/patternreplacer.h -./space/space.o: convert/strtoint.h ./convert/text.h ./convert/misc.h +./space/space.o: convert/strtoint.h ./convert/text.h ./convert/text_private.h +./space/space.o: ./convert/misc.h ./space/spaceparser.o: ./space/spaceparser.h ./space/space.h ./space/spaceparser.o: textstream/types.h convert/inttostr.h utf8/utf8.h ./space/spaceparser.o: textstream/textstream.h space/space.h date/date.h ./space/spaceparser.o: membuffer/membuffer.h textstream/types.h ./space/spaceparser.o: utf8/utf8_templates.h utf8/utf8_private.h -./space/spaceparser.o: convert/strtoint.h ./convert/text.h ./convert/misc.h +./space/spaceparser.o: convert/strtoint.h ./convert/text.h +./space/spaceparser.o: ./convert/text_private.h ./convert/misc.h ./utf8/utf8.o: ./utf8/utf8.h textstream/textstream.h space/space.h ./utf8/utf8.o: textstream/types.h convert/inttostr.h date/date.h ./utf8/utf8.o: membuffer/membuffer.h textstream/types.h utf8/utf8_templates.h From 3984c29fbf56883e51ccd90bf3c83ac2e8c465b6 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sun, 9 May 2021 20:11:37 +0200 Subject: [PATCH 34/67] moved all directories to src subdirectory --- Makefile => src/Makefile | 0 Makefile.dep => src/Makefile.dep | 0 {convert => src/convert}/convert.h | 0 {convert => src/convert}/inttostr.cpp | 0 {convert => src/convert}/inttostr.h | 0 {convert => src/convert}/misc.cpp | 0 {convert => src/convert}/misc.h | 0 {convert => src/convert}/patternreplacer.h | 0 {convert => src/convert}/strtoint.h | 0 {convert => src/convert}/text.cpp | 0 {convert => src/convert}/text.h | 0 {convert => src/convert}/text_private.h | 0 {date => src/date}/date.cpp | 0 {date => src/date}/date.h | 0 {log => src/log}/filelog.cpp | 0 {log => src/log}/filelog.h | 0 {log => src/log}/log.cpp | 0 {log => src/log}/log.h | 0 {mainspaceparser => src/mainspaceparser}/mainspaceparser.cpp | 0 {mainspaceparser => src/mainspaceparser}/mainspaceparser.h | 0 {membuffer => src/membuffer}/membuffer.h | 0 {space => src/space}/space.cpp | 0 {space => src/space}/space.h | 0 {space => src/space}/spaceparser.cpp | 0 {space => src/space}/spaceparser.h | 0 {textstream => src/textstream}/textstream.h | 0 {textstream => src/textstream}/types.h | 0 {utf8 => src/utf8}/utf8.cpp | 0 {utf8 => src/utf8}/utf8.h | 0 {utf8 => src/utf8}/utf8_private.cpp | 0 {utf8 => src/utf8}/utf8_private.h | 0 {utf8 => src/utf8}/utf8_templates.h | 0 32 files changed, 0 insertions(+), 0 deletions(-) rename Makefile => src/Makefile (100%) rename Makefile.dep => src/Makefile.dep (100%) rename {convert => src/convert}/convert.h (100%) rename {convert => src/convert}/inttostr.cpp (100%) rename {convert => src/convert}/inttostr.h (100%) rename {convert => src/convert}/misc.cpp (100%) rename {convert => src/convert}/misc.h (100%) rename {convert => src/convert}/patternreplacer.h (100%) rename {convert => src/convert}/strtoint.h (100%) rename {convert => src/convert}/text.cpp (100%) rename {convert => src/convert}/text.h (100%) rename {convert => src/convert}/text_private.h (100%) rename {date => src/date}/date.cpp (100%) rename {date => src/date}/date.h (100%) rename {log => src/log}/filelog.cpp (100%) rename {log => src/log}/filelog.h (100%) rename {log => src/log}/log.cpp (100%) rename {log => src/log}/log.h (100%) rename {mainspaceparser => src/mainspaceparser}/mainspaceparser.cpp (100%) rename {mainspaceparser => src/mainspaceparser}/mainspaceparser.h (100%) rename {membuffer => src/membuffer}/membuffer.h (100%) rename {space => src/space}/space.cpp (100%) rename {space => src/space}/space.h (100%) rename {space => src/space}/spaceparser.cpp (100%) rename {space => src/space}/spaceparser.h (100%) rename {textstream => src/textstream}/textstream.h (100%) rename {textstream => src/textstream}/types.h (100%) rename {utf8 => src/utf8}/utf8.cpp (100%) rename {utf8 => src/utf8}/utf8.h (100%) rename {utf8 => src/utf8}/utf8_private.cpp (100%) rename {utf8 => src/utf8}/utf8_private.h (100%) rename {utf8 => src/utf8}/utf8_templates.h (100%) diff --git a/Makefile b/src/Makefile similarity index 100% rename from Makefile rename to src/Makefile diff --git a/Makefile.dep b/src/Makefile.dep similarity index 100% rename from Makefile.dep rename to src/Makefile.dep diff --git a/convert/convert.h b/src/convert/convert.h similarity index 100% rename from convert/convert.h rename to src/convert/convert.h diff --git a/convert/inttostr.cpp b/src/convert/inttostr.cpp similarity index 100% rename from convert/inttostr.cpp rename to src/convert/inttostr.cpp diff --git a/convert/inttostr.h b/src/convert/inttostr.h similarity index 100% rename from convert/inttostr.h rename to src/convert/inttostr.h diff --git a/convert/misc.cpp b/src/convert/misc.cpp similarity index 100% rename from convert/misc.cpp rename to src/convert/misc.cpp diff --git a/convert/misc.h b/src/convert/misc.h similarity index 100% rename from convert/misc.h rename to src/convert/misc.h diff --git a/convert/patternreplacer.h b/src/convert/patternreplacer.h similarity index 100% rename from convert/patternreplacer.h rename to src/convert/patternreplacer.h diff --git a/convert/strtoint.h b/src/convert/strtoint.h similarity index 100% rename from convert/strtoint.h rename to src/convert/strtoint.h diff --git a/convert/text.cpp b/src/convert/text.cpp similarity index 100% rename from convert/text.cpp rename to src/convert/text.cpp diff --git a/convert/text.h b/src/convert/text.h similarity index 100% rename from convert/text.h rename to src/convert/text.h diff --git a/convert/text_private.h b/src/convert/text_private.h similarity index 100% rename from convert/text_private.h rename to src/convert/text_private.h diff --git a/date/date.cpp b/src/date/date.cpp similarity index 100% rename from date/date.cpp rename to src/date/date.cpp diff --git a/date/date.h b/src/date/date.h similarity index 100% rename from date/date.h rename to src/date/date.h diff --git a/log/filelog.cpp b/src/log/filelog.cpp similarity index 100% rename from log/filelog.cpp rename to src/log/filelog.cpp diff --git a/log/filelog.h b/src/log/filelog.h similarity index 100% rename from log/filelog.h rename to src/log/filelog.h diff --git a/log/log.cpp b/src/log/log.cpp similarity index 100% rename from log/log.cpp rename to src/log/log.cpp diff --git a/log/log.h b/src/log/log.h similarity index 100% rename from log/log.h rename to src/log/log.h diff --git a/mainspaceparser/mainspaceparser.cpp b/src/mainspaceparser/mainspaceparser.cpp similarity index 100% rename from mainspaceparser/mainspaceparser.cpp rename to src/mainspaceparser/mainspaceparser.cpp diff --git a/mainspaceparser/mainspaceparser.h b/src/mainspaceparser/mainspaceparser.h similarity index 100% rename from mainspaceparser/mainspaceparser.h rename to src/mainspaceparser/mainspaceparser.h diff --git a/membuffer/membuffer.h b/src/membuffer/membuffer.h similarity index 100% rename from membuffer/membuffer.h rename to src/membuffer/membuffer.h diff --git a/space/space.cpp b/src/space/space.cpp similarity index 100% rename from space/space.cpp rename to src/space/space.cpp diff --git a/space/space.h b/src/space/space.h similarity index 100% rename from space/space.h rename to src/space/space.h diff --git a/space/spaceparser.cpp b/src/space/spaceparser.cpp similarity index 100% rename from space/spaceparser.cpp rename to src/space/spaceparser.cpp diff --git a/space/spaceparser.h b/src/space/spaceparser.h similarity index 100% rename from space/spaceparser.h rename to src/space/spaceparser.h diff --git a/textstream/textstream.h b/src/textstream/textstream.h similarity index 100% rename from textstream/textstream.h rename to src/textstream/textstream.h diff --git a/textstream/types.h b/src/textstream/types.h similarity index 100% rename from textstream/types.h rename to src/textstream/types.h diff --git a/utf8/utf8.cpp b/src/utf8/utf8.cpp similarity index 100% rename from utf8/utf8.cpp rename to src/utf8/utf8.cpp diff --git a/utf8/utf8.h b/src/utf8/utf8.h similarity index 100% rename from utf8/utf8.h rename to src/utf8/utf8.h diff --git a/utf8/utf8_private.cpp b/src/utf8/utf8_private.cpp similarity index 100% rename from utf8/utf8_private.cpp rename to src/utf8/utf8_private.cpp diff --git a/utf8/utf8_private.h b/src/utf8/utf8_private.h similarity index 100% rename from utf8/utf8_private.h rename to src/utf8/utf8_private.h diff --git a/utf8/utf8_templates.h b/src/utf8/utf8_templates.h similarity index 100% rename from utf8/utf8_templates.h rename to src/utf8/utf8_templates.h From 7abe4b340a1fb943d0a7936dd8b921965e760cff Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:04:12 +0200 Subject: [PATCH 35/67] changes in convert/text functions - changed function names: PascalCase to snake_case - templates functions moved to a seperate file (text_private.h) - as a public api only available functions with char/wchar_t/std::string/std::wstring - ToLower(...) changed to to_lower_emplace(...), similar ToUpper(...) to to_upper_emplace(...) - added functions: std::string to_lower(const std::string & str); std::string to_upper(const std::string & str); and with std::wstring too - functions with postfix 'NoCase' changed to 'nc' --- src/convert/strtoint.h | 14 +- src/convert/text.cpp | 312 ++++++++++++++++++++++++++++++++++--- src/convert/text.h | 284 ++++++++------------------------- src/convert/text_private.h | 225 +++++++++++++++++++++++++- src/space/space.cpp | 4 +- 5 files changed, 585 insertions(+), 254 deletions(-) diff --git a/src/convert/strtoint.h b/src/convert/strtoint.h index 3aae7dc..3324d3a 100644 --- a/src/convert/strtoint.h +++ b/src/convert/strtoint.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2017, Tomasz Sowa + * Copyright (c) 2017-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,9 +59,9 @@ unsigned long long Toull(const CharType * str, int base = 10, const CharType ** SetOverflow(was_overflow, false); if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); - while( !carry && IsDigit(*str, base, &digit) ) + while( !carry && is_digit(*str, base, &digit) ) { #ifdef __GNUC__ carry = __builtin_mul_overflow(res, static_cast(base), &res); @@ -82,7 +82,7 @@ unsigned long long Toull(const CharType * str, int base = 10, const CharType ** { if( after_str ) { - while( IsDigit(*str, base, &digit) ) + while( is_digit(*str, base, &digit) ) { str += 1; } @@ -108,7 +108,7 @@ long long Toll(const CharType * str, int base = 10, const CharType ** after_str SetOverflow(was_overflow, false); if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); if( *str == '-' ) { @@ -230,7 +230,7 @@ template unsigned long long Toull_b(const CharType * str, const CharType ** after_str = 0, bool * was_overflow = 0, bool allow_skip_whitechars = true) { if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); int base = 10; @@ -266,7 +266,7 @@ long long Toll_b(const CharType * str, const CharType ** after_str = 0, bool * w SetOverflow(was_overflow, false); if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); if( *str == '-' ) { diff --git a/src/convert/text.cpp b/src/convert/text.cpp index ebaa175..c8d8fa0 100644 --- a/src/convert/text.cpp +++ b/src/convert/text.cpp @@ -37,6 +37,7 @@ #include #include "text.h" +#include "text_private.h" namespace PT @@ -78,7 +79,7 @@ static const wchar_t white_chars_table[] = { /* if check_additional_chars is false then we are testing only a space (32), tab (9) and a new line (10) (if treat_new_line_as_white is true) */ -bool IsWhite(wchar_t c, bool check_additional_chars, bool treat_new_line_as_white) +bool is_white(wchar_t c, bool check_additional_chars, bool treat_new_line_as_white) { // space (32) and tab (9) are the most common white chars // so we check them at the beginning (optimisation) @@ -119,7 +120,7 @@ return false; -bool IsDigit(wchar_t c, int base, int * digit) +bool is_digit(wchar_t c, int base, int * digit) { int d = 0; @@ -152,54 +153,317 @@ bool IsDigit(wchar_t c, int base, int * digit) } - -char ToLower(char c) +const char * skip_white(const char * str, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToLowerGeneric(c); + return pt_private::skip_white_generic(str, check_additional_chars, treat_new_line_as_white); } -wchar_t ToLower(wchar_t c) +const wchar_t * skip_white(const wchar_t * str, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToLowerGeneric(c); + return pt_private::skip_white_generic(str, check_additional_chars, treat_new_line_as_white); } - -char ToUpper(char c) +const char * skip_white_from_back(const char * str_begin, const char * str_end, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToUpperGeneric(c); + return pt_private::skip_white_from_back_generic(str_begin, str_end, check_additional_chars, treat_new_line_as_white); } -wchar_t ToUpper(wchar_t c) +const wchar_t * skip_white_from_back(const wchar_t * str_begin, const wchar_t * str_end, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToUpperGeneric(c); - + return pt_private::skip_white_from_back_generic(str_begin, str_end, check_additional_chars, treat_new_line_as_white); } - - - -void ToLower(std::string & str) +const char * skip_white_from_back(const char * str, bool check_additional_chars, bool treat_new_line_as_white) { - pt_private::ToLowerStrGeneric(str); + return pt_private::skip_white_from_back_generic(str, check_additional_chars, treat_new_line_as_white); } -void ToLower(std::wstring & str) +const wchar_t * skip_white_from_back(const wchar_t * str, bool check_additional_chars, bool treat_new_line_as_white) { - pt_private::ToLowerStrGeneric(str); + return pt_private::skip_white_from_back_generic(str, check_additional_chars, treat_new_line_as_white); } -void ToUpper(std::string & str) + + +char to_lower(char c) { - pt_private::ToLowerStrGeneric(str); + return pt_private::to_lower_generic(c); } -void ToUpper(std::wstring & str) +wchar_t to_lower(wchar_t c) { - pt_private::ToLowerStrGeneric(str); + return pt_private::to_lower_generic(c); } +char to_upper(char c) +{ + return pt_private::to_upper_generic(c); +} + +wchar_t to_upper(wchar_t c) +{ + return pt_private::to_upper_generic(c); + +} + + + + +void to_lower_emplace(std::string & str) +{ + pt_private::to_lower_str_generic(str); +} + + +void to_lower_emplace(std::wstring & str) +{ + pt_private::to_lower_str_generic(str); +} + + +void to_upper_emplace(std::string & str) +{ + pt_private::to_upper_str_generic(str); +} + + +void to_upper_emplace(std::wstring & str) +{ + pt_private::to_upper_str_generic(str); +} + + + + + +std::string to_lower(const std::string & str) +{ + std::string res(str); + to_lower_emplace(res); + + return res; +} + + +std::wstring to_lower(const std::wstring & str) +{ + std::wstring res(str); + to_lower_emplace(res); + + return res; +} + + +std::string to_upper(const std::string & str) +{ + std::string res(str); + to_upper_emplace(res); + + return res; +} + + +std::wstring to_upper(const std::wstring & str) +{ + std::wstring res(str); + to_upper_emplace(res); + + return res; +} + + + +int compare(const char * str1, const char * str2) +{ + return pt_private::compare_generic(str1, str2); +} + +int compare(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_generic(str1, str2); +} + +int compare(const std::string & str1, const std::string & str2) +{ + return pt_private::compare_str_generic(str1, str2); +} + +int compare(const std::wstring & str1, const std::wstring & str2) +{ + return pt_private::compare_str_generic(str1, str2); +} + +int compare(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2); +} + +int compare(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2); +} + + + + + + + +int compare_nc(const char * str1, const char * str2) +{ + return pt_private::compare_nc_generic(str1, str2); +} + +int compare_nc(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1, str2); +} + +int compare_nc(const std::string & str1, const std::string & str2) +{ + return pt_private::compare_nc_str_generic(str1, str2); +} + +int compare_nc(const std::wstring & str1, const std::wstring & str2) +{ + return pt_private::compare_nc_str_generic(str1, str2); +} + +int compare_nc(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2); +} + +int compare_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2); +} + + +bool is_equal(const char * str1, const char * str2) +{ + return pt_private::compare_generic(str1, str2) == 0; +} + +bool is_equal(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_generic(str1, str2) == 0; +} + + +bool is_equal(const std::string & str1, const std::string & str2) +{ + return is_equal(str1.c_str(), str2.c_str()); +} + + +bool is_equal(const std::wstring & str1, const std::wstring & str2) +{ + return is_equal(str1.c_str(), str2.c_str()); +} + + + +bool is_equal(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2) == 0; +} + + +bool is_equal(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2) == 0; +} + + +bool is_equal_nc(const char * str1, const char * str2) +{ + return pt_private::compare_nc_generic(str1, str2) == 0; +} + + +bool is_equal_nc(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1, str2) == 0; +} + + +bool is_equal_nc(const std::string & str1, const std::string & str2) +{ + return is_equal_nc(str1.c_str(), str2.c_str()); +} + + +bool is_equal_nc(const std::wstring & str1, const std::wstring & str2) +{ + return is_equal_nc(str1.c_str(), str2.c_str()); +} + + +bool is_equal_nc(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2) == 0; +} + + +bool is_equal_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2) == 0; +} + + + + +bool is_substr(const char * short_str, const char * long_str) +{ + return pt_private::is_substr_generic(short_str, long_str); +} + + +bool is_substr(const wchar_t * short_str, const wchar_t * long_str) +{ + return pt_private::is_substr_generic(short_str, long_str); +} + + +bool is_substr(const std::string & short_str, const std::string & long_str) +{ + return is_substr(short_str.c_str(), long_str.c_str()); +} + + +bool is_substr(const std::wstring & short_str, const std::wstring & long_str) +{ + return is_substr(short_str.c_str(), long_str.c_str()); +} + + +bool is_substr_nc(const char * short_str, const char * long_str) +{ + return pt_private::is_substr_nc_generic(short_str, long_str); +} + +bool is_substr_nc(const wchar_t * short_str, const wchar_t * long_str) +{ + return pt_private::is_substr_nc_generic(short_str, long_str); +} + + +bool is_substr_nc(const std::string & short_str, const std::string & long_str) +{ + return pt_private::is_substr_nc_generic(short_str.c_str(), long_str.c_str()); +} + + +bool is_substr_nc(const std::wstring & short_str, const std::wstring & long_str) +{ + return pt_private::is_substr_nc_generic(short_str.c_str(), long_str.c_str()); +} + + + diff --git a/src/convert/text.h b/src/convert/text.h index d5b0532..d698047 100644 --- a/src/convert/text.h +++ b/src/convert/text.h @@ -38,46 +38,18 @@ #ifndef headerfile_picotools_convert_text #define headerfile_picotools_convert_text -#include "text_private.h" - +#include namespace PT { -bool IsWhite(wchar_t c, bool check_additional_chars = true, bool treat_new_line_as_white = true); +bool is_white(wchar_t c, bool check_additional_chars = true, bool treat_new_line_as_white = true); +bool is_digit(wchar_t c, int base = 10, int * digit = 0); +const char * skip_white(const char * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); +const wchar_t * skip_white(const wchar_t * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); -bool IsDigit(wchar_t c, int base = 10, int * digit = 0); - - -char ToLower(char c); -wchar_t ToLower(wchar_t c); - -char ToUpper(char c); -wchar_t ToUpper(wchar_t c); - -// rename to something like to_lower_emplace -// and add to_lower which returns string -void ToLower(std::string & str); -void ToLower(std::wstring & str); - -void ToUpper(std::string & str); -void ToUpper(std::wstring & str); - - -//////////////////////////// - -template -CharType * SkipWhite(CharType * str, bool check_additional_chars = true, bool treat_new_line_as_white = true) -{ - while( IsWhite(static_cast(*str), check_additional_chars, treat_new_line_as_white) ) - { - str += 1; - } - - return str; -} /* @@ -88,205 +60,87 @@ CharType * SkipWhite(CharType * str, bool check_additional_chars = true, bool tr * or to the last+one if there is no any white characters * */ -template -CharType * SkipWhiteFromBack(CharType * str_begin, CharType * str_end, bool check_additional_chars = true, bool treat_new_line_as_white = true) -{ - while( str_end > str_begin && IsWhite(static_cast(*(str_end-1)), check_additional_chars, treat_new_line_as_white) ) - { - str_end -= 1; - } +const char * skip_white_from_back(const char * str_begin, const char * str_end, bool check_additional_chars = true, bool treat_new_line_as_white = true); +const wchar_t * skip_white_from_back(const wchar_t * str_begin, const wchar_t * str_end, bool check_additional_chars = true, bool treat_new_line_as_white = true); - return str_end; -} - - -template -CharType * SkipWhiteFromBack(CharType * str, bool check_additional_chars = true, bool treat_new_line_as_white = true) -{ - CharType * str_begin = str; - - while( *str != 0 ) - { - str += 1; - } - - return SkipWhiteFromBack(str_begin, str, check_additional_chars, treat_new_line_as_white); -} - - -template -int CompareNoCase(const StringType1 * str1, const StringType2 * str2) -{ - while( *str1 && *str2 && ToLower(*str1) == ToLower(*str2) ) - { - ++str1; - ++str2; - } - - if( *str1 == 0 && *str2 == 0 ) - return 0; - - int c1; - int c2; - - if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) - { - c1 = ToLower((wchar_t)(unsigned char)(*str1)); - c2 = ToLower((wchar_t)(unsigned char)(*str2)); - } - else - { - c1 = ToLower(*str1); - c2 = ToLower(*str2); - } - - return c1 - c2; -} - - -template -int CompareNoCase(const StringType1 & str1, const StringType2 & str2) -{ - return CompareNoCase(str1.c_str(), str2.c_str()); -} - - -template -int CompareNoCasep(const StringType1 * str1, const StringType2 * str2) -{ - return CompareNoCase(str1, str2); -} +const char * skip_white_from_back(const char * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); +const wchar_t * skip_white_from_back(const wchar_t * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); +char to_lower(char c); +wchar_t to_lower(wchar_t c); -template -int CompareNoCase(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) -{ - while( str1_begin < str1_end && *str2 && ToLower(*str1_begin) == ToLower(*str2) ) - { - ++str1_begin; - ++str2; - } +char to_upper(char c); +wchar_t to_upper(wchar_t c); - if( str1_begin == str1_end && *str2 == 0 ) - return 0; +void to_lower_emplace(std::string & str); +void to_lower_emplace(std::wstring & str); - int c1; - int c2; +void to_upper_emplace(std::string & str); +void to_upper_emplace(std::wstring & str); - if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) - { - c1 = str1_begin < str1_end ? ToLower((wchar_t)(unsigned char)(*str1_begin)) : 0; - c2 = ToLower((wchar_t)(unsigned char)(*str2)); - } - else - { - c1 = str1_begin < str1_end ? ToLower(*str1_begin) : 0; - c2 = ToLower(*str2); - } +std::string to_lower(const std::string & str); +std::wstring to_lower(const std::wstring & str); - return c1 - c2; -} +std::string to_upper(const std::string & str); +std::wstring to_upper(const std::wstring & str); + + +int compare(const char * str1, const char * str2); +int compare(const wchar_t * str1, const wchar_t * str2); + +int compare(const std::string & str1, const std::string & str2); +int compare(const std::wstring & str1, const std::wstring & str2); + +int compare(const char * str1_begin, const char * str1_end, const char * str2); +int compare(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); + + +/* + * compare no case + */ +int compare_nc(const char * str1, const char * str2); +int compare_nc(const wchar_t * str1, const wchar_t * str2); + +int compare_nc(const std::string & str1, const std::string & str2); +int compare_nc(const std::wstring & str1, const std::wstring & str2); + +int compare_nc(const char * str1_begin, const char * str1_end, const char * str2); +int compare_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); +bool is_equal(const char * str1, const char * str2); +bool is_equal(const wchar_t * str1, const wchar_t * str2); + +bool is_equal(const std::string & str1, const std::string & str2); +bool is_equal(const std::wstring & str1, const std::wstring & str2); + +bool is_equal(const char * str1_begin, const char * str1_end, const char * str2); +bool is_equal(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); + +bool is_equal_nc(const char * str1, const char * str2); +bool is_equal_nc(const wchar_t * str1, const wchar_t * str2); + +bool is_equal_nc(const std::string & str1, const std::string & str2); +bool is_equal_nc(const std::wstring & str1, const std::wstring & str2); + +bool is_equal_nc(const char * str1_begin, const char * str1_end, const char * str2); +bool is_equal_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); -template -bool EqualNoCase(const StringType1 * str1, const StringType2 * str2) -{ - return CompareNoCase(str1, str2) == 0; -} +bool is_substr(const char * short_str, const char * long_str); +bool is_substr(const wchar_t * short_str, const wchar_t * long_str); +bool is_substr(const std::string & short_str, const std::string & long_str); +bool is_substr(const std::wstring & short_str, const std::wstring & long_str); -template -bool EqualNoCase(const StringType1 & str1, const StringType2 & str2) -{ - return EqualNoCase(str1.c_str(), str2.c_str()); -} - - -template -bool EqualNoCasep(const StringType1 * str1, const StringType2 * str2) -{ - return EqualNoCase(str1, str2); -} - - - -template -bool EqualNoCase(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) -{ - return CompareNoCase(str1_begin, str1_end, str2) == 0; -} - - - - - - - -template -bool IsSubStringp(const StringType1 * short_str, const StringType2 * long_str) -{ - while( *short_str && *long_str && wchar_t(*short_str) == wchar_t(*long_str) ) - { - ++short_str; - ++long_str; - } - - if( *short_str == 0 ) - return true; - -return false; -} - - -template -bool IsSubString(const StringType1 * short_str, const StringType2 * long_str) -{ - return IsSubStringp(short_str, long_str); -} - - -template -bool IsSubString(const StringType1 & short_str, const StringType2 & long_str) -{ - return IsSubStringp(short_str.c_str(), long_str.c_str()); -} - - -template -bool IsSubStringNoCasep(const StringType1 * short_str, const StringType2 * long_str) -{ - while( *short_str && *long_str && ToLower(*short_str) == ToLower(*long_str) ) - { - ++short_str; - ++long_str; - } - - if( *short_str == 0 ) - return true; - -return false; -} - - -template -bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_str) -{ - return IsSubStringNoCasep(short_str, long_str); -} - - -template -bool IsSubStringNoCase(const StringType1 & short_str, const StringType2 & long_str) -{ - return IsSubStringNoCasep(short_str.c_str(), long_str.c_str()); -} - +bool is_substr_nc(const char * short_str, const char * long_str); +bool is_substr_nc(const wchar_t * short_str, const wchar_t * long_str); +bool is_substr_nc(const std::string & short_str, const std::string & long_str); +bool is_substr_nc(const std::wstring & short_str, const std::wstring & long_str); diff --git a/src/convert/text_private.h b/src/convert/text_private.h index f1007fd..5957367 100644 --- a/src/convert/text_private.h +++ b/src/convert/text_private.h @@ -39,6 +39,7 @@ #define headerfile_picotools_convert_text_private #include +#include "text.h" namespace PT @@ -48,7 +49,7 @@ namespace pt_private { template -CharType ToLowerGeneric(CharType c) +CharType to_lower_generic(CharType c) { if( c >= 'A' && c <= 'Z' ) return c - 'A' + 'a'; @@ -58,7 +59,7 @@ CharType ToLowerGeneric(CharType c) template -CharType ToUpperGeneric(CharType c) +CharType to_upper_generic(CharType c) { if( c >= 'a' && c <= 'z' ) return c - 'a' + 'A'; @@ -68,25 +69,237 @@ CharType ToUpperGeneric(CharType c) template -void ToLowerStrGeneric(StringType & s) +void to_lower_str_generic(StringType & s) { typename StringType::size_type i; for(i=0 ; i -void ToUpperStrGeneric(StringType & s) +void to_upper_str_generic(StringType & s) { typename StringType::size_type i; for(i=0 ; i +CharType * skip_white_generic(CharType * str, bool check_additional_chars, bool treat_new_line_as_white) +{ + while( is_white(static_cast(*str), check_additional_chars, treat_new_line_as_white) ) + { + str += 1; + } + + return str; +} + + +template +CharType * skip_white_from_back_generic(CharType * str_begin, CharType * str_end, bool check_additional_chars, bool treat_new_line_as_white) +{ + while( str_end > str_begin && is_white(static_cast(*(str_end-1)), check_additional_chars, treat_new_line_as_white) ) + { + str_end -= 1; + } + + return str_end; +} + + +template +CharType * skip_white_from_back_generic(CharType * str, bool check_additional_chars, bool treat_new_line_as_white) +{ + CharType * str_begin = str; + + while( *str != 0 ) + { + str += 1; + } + + return skip_white_from_back_generic(str_begin, str, check_additional_chars, treat_new_line_as_white); +} + + + + +template +int compare_generic(const StringType1 * str1, const StringType2 * str2) +{ + while( *str1 && *str2 && *str1 == *str2 ) + { + ++str1; + ++str2; + } + + if( *str1 == 0 && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = (wchar_t)(unsigned char)(*str1); + c2 = (wchar_t)(unsigned char)(*str2); + } + else + { + c1 = *str1; + c2 = *str2; + } + + return c1 - c2; +} + + +template +int compare_str_generic(const StringType1 & str1, const StringType2 & str2) +{ + return compare_generic(str1.c_str(), str2.c_str()); +} + + +template +int compare_generic(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) +{ + while( str1_begin < str1_end && *str2 && *str1_begin == *str2 ) + { + ++str1_begin; + ++str2; + } + + if( str1_begin == str1_end && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = str1_begin < str1_end ? (wchar_t)(unsigned char)(*str1_begin) : 0; + c2 = (wchar_t)(unsigned char)(*str2); + } + else + { + c1 = str1_begin < str1_end ? *str1_begin : 0; + c2 = *str2; + } + + return c1 - c2; +} + + + +template +int compare_nc_generic(const StringType1 * str1, const StringType2 * str2) +{ + while( *str1 && *str2 && to_lower(*str1) == to_lower(*str2) ) + { + ++str1; + ++str2; + } + + if( *str1 == 0 && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = to_lower((wchar_t)(unsigned char)(*str1)); + c2 = to_lower((wchar_t)(unsigned char)(*str2)); + } + else + { + c1 = to_lower(*str1); + c2 = to_lower(*str2); + } + + return c1 - c2; +} + + +template +int compare_nc_str_generic(const StringType1 & str1, const StringType2 & str2) +{ + return compare_nc(str1.c_str(), str2.c_str()); +} + + +template +int compare_nc_generic(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) +{ + while( str1_begin < str1_end && *str2 && to_lower(*str1_begin) == to_lower(*str2) ) + { + ++str1_begin; + ++str2; + } + + if( str1_begin == str1_end && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = str1_begin < str1_end ? to_lower((wchar_t)(unsigned char)(*str1_begin)) : 0; + c2 = to_lower((wchar_t)(unsigned char)(*str2)); + } + else + { + c1 = str1_begin < str1_end ? to_lower(*str1_begin) : 0; + c2 = to_lower(*str2); + } + + return c1 - c2; +} + + + + +template +bool is_substr_generic(const StringType1 * short_str, const StringType2 * long_str) +{ + while( *short_str && *long_str && *short_str == *long_str ) + { + ++short_str; + ++long_str; + } + + if( *short_str == 0 ) + return true; + + return false; +} + + + +template +bool is_substr_nc_generic(const StringType1 * short_str, const StringType2 * long_str) +{ + while( *short_str && *long_str && to_lower(*short_str) == to_lower(*long_str) ) + { + ++short_str; + ++long_str; + } + + if( *short_str == 0 ) + return true; + + return false; +} + + + + } // namespace pt_private } // namespace PT diff --git a/src/space/space.cpp b/src/space/space.cpp index 4db4f1d..0e53374 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -1614,7 +1614,7 @@ Space * Space::get_object_field_nc(const wchar_t * field) while( i != value.value_object.end() ) { - if( EqualNoCase(field, i->first.c_str()) ) + if( is_equal_nc(field, i->first.c_str()) ) { return i->second; } @@ -1639,7 +1639,7 @@ const Space * Space::get_object_field_nc(const wchar_t * field) const while( i != value.value_object.cend() ) { - if( EqualNoCase(field, i->first.c_str()) ) + if( is_equal_nc(field, i->first.c_str()) ) { return i->second; } From adee7d134fb6a98df18a6276fbf28be738f7c576 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:05:55 +0200 Subject: [PATCH 36/67] added macro PT_HAS_MORM in Log class where operator<<(morm::Model & model) is used --- src/log/log.cpp | 9 +++++---- src/log/log.h | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/log/log.cpp b/src/log/log.cpp index 82336e3..757c9cb 100644 --- a/src/log/log.cpp +++ b/src/log/log.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2018, Tomasz Sowa + * Copyright (c) 2018-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,8 +41,9 @@ #include "date/date.h" #include "utf8/utf8.h" +#ifdef PT_HAS_MORM #include "morm.h" - +#endif namespace PT { @@ -312,13 +313,13 @@ Log & Log::operator<<(const PT::Date & date) } - +#ifdef PT_HAS_MORM Log & Log::operator<<(morm::Model & model) { operator<<(model.to_string()); return *this; } - +#endif Log & Log::operator<<(Manipulators m) diff --git a/src/log/log.h b/src/log/log.h index c5d72bb..891fb6d 100644 --- a/src/log/log.h +++ b/src/log/log.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2018, Tomasz Sowa + * Copyright (c) 2018-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -131,8 +131,9 @@ public: virtual Log & operator<<(const PT::Space & space); virtual Log & operator<<(const PT::Date & date); +#ifdef PT_HAS_MORM virtual Log & operator<<(morm::Model & model); - +#endif virtual Log & operator<<(Manipulators m); From b3cd4d5f7f936a1cd0c5c5c8b360db47a29fc23e Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:07:08 +0200 Subject: [PATCH 37/67] removed definition of CXX and CXXFLAGS from Makefile --- src/Makefile | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/Makefile b/src/Makefile index 058a006..683b0d1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,23 +3,12 @@ objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles)) -CXX = g++10 -#CXX = clang++ -#CXXFLAGS = -fsanitize=address -O0 -g3 -gdwarf-2 -O0 -std=c++14 -I../ttmath -I../pikotools -Wl,-rpath=/usr/local/lib/gcc5/ -Wall -pedantic -Wextra -#CXXFLAGS = -O0 -g3 -gdwarf-2 -O0 -std=c++17 -I../ttmath -I../pikotools -Wl,-rpath=/usr/local/lib/gcc7/ -Wall -pedantic -Wextra -CXXFLAGS = -Wl,-rpath=/usr/local/lib/gcc10/ -O0 -g3 -std=c++20 -I../pikotools -Wall -pedantic - - ifndef CXX -CXX = clang++ +CXX = g++ endif ifndef CXXFLAGS -CXXFLAGS = -Wall -O2 -I/usr/local/include -endif - -ifndef LDFLAGS -LDFLAGS = -L/usr/local/lib +CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../src -I/usr/local/include endif ifndef AR @@ -27,10 +16,6 @@ AR = ar endif -#export CXX -#export CXXFLAGS -#export LDFLAGS -#export AR libname = pikotools.a From cd9e501f48f6d0693c77c5fd98c79c76bb02932c Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:08:19 +0200 Subject: [PATCH 38/67] make depend --- src/Makefile.dep | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Makefile.dep b/src/Makefile.dep index 4199952..26b3fcd 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -1,7 +1,7 @@ # DO NOT DELETE ./convert/inttostr.o: ./convert/inttostr.h -./convert/misc.o: ./convert/misc.h ./convert/text.h ./convert/text_private.h +./convert/misc.o: ./convert/misc.h ./convert/text.h ./convert/text.o: ./convert/text.h ./convert/text_private.h ./date/date.o: ./date/date.h convert/inttostr.h ./log/filelog.o: ./log/filelog.h textstream/textstream.h space/space.h @@ -24,15 +24,13 @@ ./space/space.o: date/date.h membuffer/membuffer.h textstream/types.h ./space/space.o: utf8/utf8_templates.h utf8/utf8_private.h convert/convert.h ./space/space.o: ./convert/inttostr.h convert/patternreplacer.h -./space/space.o: convert/strtoint.h ./convert/text.h ./convert/text_private.h -./space/space.o: ./convert/misc.h +./space/space.o: convert/strtoint.h ./convert/text.h ./convert/misc.h ./space/spaceparser.o: ./space/spaceparser.h ./space/space.h ./space/spaceparser.o: textstream/types.h convert/inttostr.h utf8/utf8.h ./space/spaceparser.o: textstream/textstream.h space/space.h date/date.h ./space/spaceparser.o: membuffer/membuffer.h textstream/types.h ./space/spaceparser.o: utf8/utf8_templates.h utf8/utf8_private.h -./space/spaceparser.o: convert/strtoint.h ./convert/text.h -./space/spaceparser.o: ./convert/text_private.h ./convert/misc.h +./space/spaceparser.o: convert/strtoint.h ./convert/text.h ./convert/misc.h ./utf8/utf8.o: ./utf8/utf8.h textstream/textstream.h space/space.h ./utf8/utf8.o: textstream/types.h convert/inttostr.h date/date.h ./utf8/utf8.o: membuffer/membuffer.h textstream/types.h utf8/utf8_templates.h From ce81670bb6dd47e46adc31b49a41b323b3757817 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:08:50 +0200 Subject: [PATCH 39/67] added 'tests' directory with tests for the pikotools library currently only tests for convert/text functions --- tests/Makefile | 46 + tests/Makefile.dep | 11 + tests/convert.cpp | 1985 ++++++++++++++++++++++++++++++++++++++++++++ tests/convert.h | 61 ++ tests/main.cpp | 67 ++ tests/test.cpp | 110 +++ tests/test.h | 92 ++ 7 files changed, 2372 insertions(+) create mode 100644 tests/Makefile create mode 100644 tests/Makefile.dep create mode 100644 tests/convert.cpp create mode 100644 tests/convert.h create mode 100644 tests/main.cpp create mode 100644 tests/test.cpp create mode 100644 tests/test.h diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..bd4e83f --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,46 @@ +sourcefiles:=$(shell find . -name "*.cpp") +objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles)) + + +ifndef CXX +CXX = g++ +endif + +ifndef CXXFLAGS +CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../src -I/usr/local/include +endif + + + +progname = tests + + +all: $(progname) pikotools + + +$(progname): $(objfiles) pikotools + $(CXX) $(CXXFLAGS) -o $(progname) $(objfiles) ../src/pikotools.a + + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) -o $@ $< + + +pikotools: FORCE + $(MAKE) -C ../src + + +FORCE: + + +clean: + rm -f $(objfiles) + rm -f $(progname) + + +depend: + makedepend -Y. -I../src -f- $(sourcefiles) > Makefile.dep + + +-include Makefile.dep + diff --git a/tests/Makefile.dep b/tests/Makefile.dep new file mode 100644 index 0000000..d69f60e --- /dev/null +++ b/tests/Makefile.dep @@ -0,0 +1,11 @@ +# DO NOT DELETE + +./main.o: convert.h +./convert.o: convert.h test.h ../src/convert/convert.h +./convert.o: ../src/convert/inttostr.h ../src/convert/patternreplacer.h +./convert.o: ../src/textstream/textstream.h ../src/space/space.h +./convert.o: ../src/textstream/types.h ../src/convert/inttostr.h +./convert.o: ../src/date/date.h ../src/membuffer/membuffer.h +./convert.o: ../src/textstream/types.h ../src/convert/strtoint.h +./convert.o: ../src/convert/text.h ../src/convert/misc.h +./test.o: test.h diff --git a/tests/convert.cpp b/tests/convert.cpp new file mode 100644 index 0000000..7106d95 --- /dev/null +++ b/tests/convert.cpp @@ -0,0 +1,1985 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "convert.h" +#include "test.h" +#include "convert/convert.h" + + +namespace pt +{ + +// remove me in the future (when PT will be changed to pt) +using namespace PT; + + +namespace pt_convert_tests +{ + +void test_text1() +{ + reset_test_counter("is_white"); + + test(PT::is_white(0), false); + test(PT::is_white(1), false); + test(PT::is_white(9), true); + test(PT::is_white(10), true); + test(PT::is_white(30), false); + test(PT::is_white(32), true); + test(PT::is_white(40), false); + test(PT::is_white('a'), false); + test(PT::is_white(0xabcd), false); + + test(PT::is_white(5, false, false), false); + test(PT::is_white(9, false, false), true); + test(PT::is_white(10, false, false), false); + test(PT::is_white(31, false, false), false); + test(PT::is_white(32, false, false), true); + test(PT::is_white('z', false, false), false); + test(PT::is_white(0xbbcc, false, false), false); + test(PT::is_white(0xffff, false, false), false); + test(PT::is_white(0x10ffff, false, false), false); + + test(PT::is_white(0x000B, false, false), false); + test(PT::is_white(0x00A0, false, false), false); + test(PT::is_white(0x2001, false, false), false); + test(PT::is_white(0x2009, false, false), false); + test(PT::is_white(0xFEFF, false, false), false); + + test(PT::is_white(0x000B, true, false), true); + test(PT::is_white(0x00A0, true, false), true); + test(PT::is_white(0x2001, true, false), true); + test(PT::is_white(0x2009, true, false), true); + test(PT::is_white(0xFEFF, true, false), true); +} + + +void test_text2() +{ + reset_test_counter("is_digit"); + + int digit; + + test(PT::is_digit(0, 10, &digit), false); + test(PT::is_digit(1, 10, &digit), false); + test(PT::is_digit(10, 10, &digit), false); + test(PT::is_digit(32, 10, &digit), false); + test(PT::is_digit('z', 10, &digit), false); + test(PT::is_digit('x', 10, &digit), false); + + test(PT::is_digit('0', 2, &digit), true); + test(digit, 0); + + test(PT::is_digit('1', 2, &digit), true); + test(digit, 1); + + test(PT::is_digit('2', 2, &digit), false); + + + test(PT::is_digit('0', 8, &digit), true); + test(digit, 0); + + test(PT::is_digit('7', 8, &digit), true); + test(digit, 7); + + test(PT::is_digit('8', 8, &digit), false); + + + test(PT::is_digit('0', 10, &digit), true); + test(digit, 0); + + test(PT::is_digit('1', 10, &digit), true); + test(digit, 1); + + test(PT::is_digit('8', 10, &digit), true); + test(digit, 8); + + test(PT::is_digit('9', 10, &digit), true); + test(digit, 9); + + test(PT::is_digit('a', 10, &digit), false); + + + test(PT::is_digit('a', 16, &digit), true); + test(digit, 0x0a); + + test(PT::is_digit('c', 16, &digit), true); + test(digit, 0x0c); + + test(PT::is_digit('f', 16, &digit), true); + test(digit, 0x0f); + + test(PT::is_digit('g', 16, &digit), false); +} + + +void test_text3() +{ + reset_test_counter("skip_white"); + + test(PT::skip_white(""), ""); + test(PT::skip_white(" "), ""); + test(PT::skip_white("\n \n"), ""); + test(PT::skip_white("hello world"), "hello world"); + test(PT::skip_white(" hello world"), "hello world"); + test(PT::skip_white(" hello world"), "hello world"); + test(PT::skip_white(" hello world"), "hello world"); + test(PT::skip_white(" hello world"), "hello world"); + + test(PT::skip_white("\n\nhello world"), "hello world"); + test(PT::skip_white("\n\nhello world", true, true), "hello world"); + test(PT::skip_white("\n\nhello world", true, false), "\n\nhello world"); + test(PT::skip_white("\n\n \n\n \t\t\n\nhello world", true, true), "hello world"); + + test(PT::skip_white(L" hello world"), L"hello world"); + test(PT::skip_white(L" hello world"), L"hello world"); + test(PT::skip_white(L" hello world"), L"hello world"); + test(PT::skip_white(L" hello world"), L"hello world"); + + test(PT::skip_white(L"\n\nhello world", true, true), L"hello world"); + test(PT::skip_white(L"\n\nhello world", true, false), L"\n\nhello world"); + test(PT::skip_white(L"\n\n \n\n \t\t\n\nhello world", true, true), L"hello world"); + + test(PT::skip_white(L"\x000B hello world", true, true), L"hello world"); + test(PT::skip_white(L"\x000B hello world", false, true), L"\x000B hello world"); + + test(PT::skip_white(L"\x2029 hello world", true, true), L"hello world"); + test(PT::skip_white(L"\x2029 hello world", false, true), L"\x2029 hello world"); +} + + + +void test_text4() +{ + reset_test_counter("skip_white_from_back"); + + test(PT::skip_white_from_back(""), ""); + test(PT::skip_white_from_back(" "), " "); + test(PT::skip_white_from_back("\n \n"), "\n \n"); + + test(PT::skip_white_from_back("hello world"), ""); + test(PT::skip_white_from_back("hello world "), " "); + test(PT::skip_white_from_back("hello world "), " "); + test(PT::skip_white_from_back("hello world "), " "); + + test(PT::skip_white_from_back("hello world\n\n"), "\n\n"); + test(PT::skip_white_from_back("hello world\n\n", true, true), "\n\n"); + test(PT::skip_white_from_back("hello world\n\n", true, false), ""); + test(PT::skip_white_from_back("hello world\n\n \n\n \t\t\n\n", true, true), "\n\n \n\n \t\t\n\n"); + + + test(PT::skip_white_from_back(L"hello world "), L" "); + test(PT::skip_white_from_back(L"hello world "), L" "); + test(PT::skip_white_from_back(L"hello world\n\n\n\t\t\t "), L"\n\n\n\t\t\t "); + test(PT::skip_white_from_back(L"hello world "), L" "); + + test(PT::skip_white_from_back(L"hello world\n\n", true, true), L"\n\n"); + test(PT::skip_white_from_back(L"hello world\n\n", true, false), L""); + test(PT::skip_white_from_back(L"hello world\n\n \n\n \t\t\n\n", true, true), L"\n\n \n\n \t\t\n\n"); + + test(PT::skip_white_from_back(L"hello world \x000B", true, true), L" \x000B"); + test(PT::skip_white_from_back(L"hello world \x000B", false, true), L""); + + test(PT::skip_white_from_back(L"hello world \x2029", true, true), L" \x2029"); + test(PT::skip_white_from_back(L"hello world \x2029", false, true), L""); +} + + +void test_text5() +{ + reset_test_counter("to_lower"); + + test(PT::to_lower((char)0), (char)0); + test(PT::to_lower((char)32), (char)32); + test(PT::to_lower((char)127), (char)127); + test(PT::to_lower((char)128), (char)128); + test(PT::to_lower((char)200), (char)200); + test(PT::to_lower((char)255), (char)255); + + test(PT::to_lower('a'), 'a'); + test(PT::to_lower('c'), 'c'); + test(PT::to_lower('t'), 't'); + test(PT::to_lower('z'), 'z'); + test(PT::to_lower('0'), '0'); + test(PT::to_lower('A'), 'a'); + test(PT::to_lower('C'), 'c'); + test(PT::to_lower('X'), 'x'); + test(PT::to_lower('Z'), 'z'); + test(PT::to_lower('@'), '@'); + test(PT::to_lower('['), '['); + test(PT::to_lower('`'), '`'); + test(PT::to_lower('{'), '{'); + + test(PT::to_lower((wchar_t)0), (wchar_t)0); + test(PT::to_lower((wchar_t)32), (wchar_t)32); + test(PT::to_lower((wchar_t)127), (wchar_t)127); + test(PT::to_lower((wchar_t)128), (wchar_t)128); + test(PT::to_lower((wchar_t)200), (wchar_t)200); + test(PT::to_lower((wchar_t)255), (wchar_t)255); + + test(PT::to_lower(L'a'), L'a'); + test(PT::to_lower(L't'), L't'); + test(PT::to_lower(L'z'), L'z'); + test(PT::to_lower(L'0'), L'0'); + test(PT::to_lower(L'A'), L'a'); + test(PT::to_lower(L'C'), L'c'); + test(PT::to_lower(L'X'), L'x'); + test(PT::to_lower(L'Z'), L'z'); + test(PT::to_lower(L'@'), L'@'); + test(PT::to_lower(L'['), L'['); +} + + +void test_text6() +{ + reset_test_counter("to_upper"); + + test(PT::to_upper((char)0), (char)0); + test(PT::to_upper((char)32), (char)32); + test(PT::to_upper((char)127), (char)127); + test(PT::to_upper((char)128), (char)128); + test(PT::to_upper((char)200), (char)200); + test(PT::to_upper((char)255), (char)255); + + test(PT::to_upper('a'), 'A'); + test(PT::to_upper('c'), 'C'); + test(PT::to_upper('t'), 'T'); + test(PT::to_upper('z'), 'Z'); + test(PT::to_upper('0'), '0'); + test(PT::to_upper('A'), 'A'); + test(PT::to_upper('C'), 'C'); + test(PT::to_upper('X'), 'X'); + test(PT::to_upper('Z'), 'Z'); + test(PT::to_upper('@'), '@'); + test(PT::to_upper('['), '['); + test(PT::to_upper('`'), '`'); + test(PT::to_upper('{'), '{'); + + test(PT::to_upper((wchar_t)0), (wchar_t)0); + test(PT::to_upper((wchar_t)32), (wchar_t)32); + test(PT::to_upper((wchar_t)127), (wchar_t)127); + test(PT::to_upper((wchar_t)128), (wchar_t)128); + test(PT::to_upper((wchar_t)200), (wchar_t)200); + test(PT::to_upper((wchar_t)255), (wchar_t)255); + + test(PT::to_upper(L'a'), L'A'); + test(PT::to_upper(L't'), L'T'); + test(PT::to_upper(L'z'), L'Z'); + test(PT::to_upper(L'0'), L'0'); + test(PT::to_upper(L'A'), L'A'); + test(PT::to_upper(L'C'), L'C'); + test(PT::to_upper(L'X'), L'X'); + test(PT::to_upper(L'Z'), L'Z'); + test(PT::to_upper(L'@'), L'@'); + test(PT::to_upper(L'['), L'['); +} + + +void test_text7() +{ + reset_test_counter("to_lower_emplace std::string"); + std::string str1, str2; + + str1 = "abcdefghijklm nopqrstuvwxyz"; + str2 = str1; + to_lower_emplace(str1); + test(str1, str2); + + str1 += "A"; + str2 += "a"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += "B"; + str2 += "b"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += "@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + str2 += "@[`{cdefghijklmnopqrstuvwxyz"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += "0123456789"; + str2 += "0123456789"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += "[];'\\!@#$%^&*()_+"; + str2 += "[];'\\!@#$%^&*()_+"; + to_lower_emplace(str1); + test(str1, str2); +} + + +void test_text8() +{ + reset_test_counter("to_lower_emplace std::wstring"); + std::wstring str1, str2; + + str1 = L"abcdefghijklm nopqrstuvwxyz"; + str2 = str1; + to_lower_emplace(str1); + test(str1, str2); + + str1 += L"A"; + str2 += L"a"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += L"B"; + str2 += L"b"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += L"@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + str2 += L"@[`{cdefghijklmnopqrstuvwxyz"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += L"0123456789"; + str2 += L"0123456789"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += L"[];'\\!@#$%^&*()_+"; + str2 += L"[];'\\!@#$%^&*()_+"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += L"\xabcd \xf000"; + str2 += L"\xabcd \xf000"; + to_lower_emplace(str1); + test(str1, str2); + + str1 += L"\x0000 \x1234"; + str2 += L"\x0000 \x1234"; + to_lower_emplace(str1); + test(str1, str2); +} + + +void test_text9() +{ + reset_test_counter("to_upper_emplace std::string"); + std::string str1, str2; + + str1 = "ABCDEFGHIJKLM NOPQRSTUVWXYZ"; + str2 = str1; + to_upper_emplace(str1); + test(str1, str2); + + str1 += "a"; + str2 += "A"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += "b"; + str2 += "B"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += "@[`{cdefghijklmnopqrstuvwxyz"; + str2 += "@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += "0123456789"; + str2 += "0123456789"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += "[];'\\!@#$%^&*()_+"; + str2 += "[];'\\!@#$%^&*()_+"; + to_upper_emplace(str1); + test(str1, str2); +} + + +void test_text10() +{ + reset_test_counter("to_upper_emplace std::wstring"); + std::wstring str1, str2; + + str1 = L"ABCDEFGHIJKLM NOPQRSTUVWXYZ"; + str2 = str1; + to_upper_emplace(str1); + test(str1, str2); + + str1 += L"a"; + str2 += L"A"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += L"b"; + str2 += L"B"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += L"@[`{cdefghijklmnopqrstuvwxyz"; + str2 += L"@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += L"0123456789"; + str2 += L"0123456789"; + to_upper_emplace(str1); + test(str1, str2); + + str1 += L"[];'\\!@#$%^&*()_+"; + str2 += L"[];'\\!@#$%^&*()_+"; + to_upper_emplace(str1); + test(str1, str2); +} + + + +void test_text11() +{ + reset_test_counter("to_lower std::string"); + std::string str1, str2; + + str1 = "abcdefghijklm nopqrstuvwxyz"; + str2 = str1; + test(PT::to_lower(str1), str2); + + str1 += "A"; + str2 += "a"; + test(PT::to_lower(str1), str2); + + str1 += "B"; + str2 += "b"; + test(PT::to_lower(str1), str2); + + str1 += "@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + str2 += "@[`{cdefghijklmnopqrstuvwxyz"; + test(PT::to_lower(str1), str2); + + str1 += "0123456789"; + str2 += "0123456789"; + test(PT::to_lower(str1), str2); + + str1 += "[];'\\!@#$%^&*()_+"; + str2 += "[];'\\!@#$%^&*()_+"; + test(PT::to_lower(str1), str2); +} + + +void test_text12() +{ + reset_test_counter("to_lower std::wstring"); + std::wstring str1, str2; + + str1 = L"abcdefghijklm nopqrstuvwxyz"; + str2 = str1; + test(PT::to_lower(str1), str2); + + str1 += L"A"; + str2 += L"a"; + test(PT::to_lower(str1), str2); + + str1 += L"B"; + str2 += L"b"; + test(PT::to_lower(str1), str2); + + str1 += L"@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + str2 += L"@[`{cdefghijklmnopqrstuvwxyz"; + test(PT::to_lower(str1), str2); + + str1 += L"0123456789"; + str2 += L"0123456789"; + test(PT::to_lower(str1), str2); + + str1 += L"[];'\\!@#$%^&*()_+"; + str2 += L"[];'\\!@#$%^&*()_+"; + test(PT::to_lower(str1), str2); +} + + +void test_text13() +{ + reset_test_counter("to_upper std::string"); + std::string str1, str2; + + str1 = "ABCDEFGHIJKLM NOPQRSTUVWXYZ"; + str2 = str1; + test(PT::to_upper(str1), str2); + + str1 += "a"; + str2 += "A"; + test(PT::to_upper(str1), str2); + + str1 += "b"; + str2 += "B"; + test(PT::to_upper(str1), str2); + + str1 += "@[`{cdefghijklmnopqrstuvwxyz"; + str2 += "@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + test(PT::to_upper(str1), str2); + + str1 += "0123456789"; + str2 += "0123456789"; + test(PT::to_upper(str1), str2); + + str1 += "[];'\\!@#$%^&*()_+"; + str2 += "[];'\\!@#$%^&*()_+"; + test(PT::to_upper(str1), str2); +} + + +void test_text14() +{ + reset_test_counter("to_upper std::wstring"); + std::wstring str1, str2; + + str1 = L"ABCDEFGHIJKLM NOPQRSTUVWXYZ"; + str2 = str1; + test(PT::to_upper(str1), str2); + + str1 += L"a"; + str2 += L"A"; + test(PT::to_upper(str1), str2); + + str1 += L"b"; + str2 += L"B"; + test(PT::to_upper(str1), str2); + + str1 += L"@[`{cdefghijklmnopqrstuvwxyz"; + str2 += L"@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; + test(PT::to_upper(str1), str2); + + str1 += L"0123456789"; + str2 += L"0123456789"; + test(PT::to_upper(str1), str2); + + str1 += L"[];'\\!@#$%^&*()_+"; + str2 += L"[];'\\!@#$%^&*()_+"; + test(PT::to_upper(str1), str2); +} + + +void test_text15() +{ + reset_test_counter("compare const char *"); + + test(PT::compare("", "") == 0, true); + test(PT::compare("a", "a") == 0, true); + test(PT::compare("abc", "abc") == 0, true); + test(PT::compare("ABC", "ABC") == 0, true); + test(PT::compare("hello world", "hello world") == 0, true); + test(PT::compare("hello world", "HELLO WORLD") > 0, true); + test(PT::compare("HELLO WORLD", "hello world") < 0, true); + test(PT::compare("HEllo WOrld", "heLLO woRLD") < 0, true); + test(PT::compare("heLLO woRLD", "HEllo WOrld") > 0, true); + + test(PT::compare("a", "b") < 0, true); + test(PT::compare("b", "c") < 0, true); + test(PT::compare("x", "z") < 0, true); + test(PT::compare("hello world", "xhelloworld") < 0, true); + + test(PT::compare("c", "b") > 0, true); + test(PT::compare("d", "c") > 0, true); + test(PT::compare("z", "x") > 0, true); + test(PT::compare("xhello world", "helloworld") > 0, true); + + test(PT::compare("abc8", "abc9") < 0, true); + test(PT::compare("abc9", "abc8") > 0, true); + test(PT::compare("abc8abc", "abc9abc") < 0, true); + test(PT::compare("abc9abc", "abc8abc") > 0, true); + test(PT::compare("abc9abc", "abc8") > 0, true); + test(PT::compare("abc8abc", "abc9") < 0, true); + test(PT::compare("abc8", "abc9abc") < 0, true); + test(PT::compare("abc9", "abc8abc") > 0, true); + + char foo[] = {"abc"}; + char bar[] = {"abc"}; + test(PT::compare(foo, bar) == 0, true); + + foo[0] = (char)(unsigned char)127; + bar[0] = (char)(unsigned char)128; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (char)(unsigned char)128; + bar[0] = (char)(unsigned char)127; + test(PT::compare(foo, bar) > 0, true); + + foo[0] = (char)(unsigned char)1; + bar[0] = (char)(unsigned char)255; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (char)(unsigned char)255; + bar[0] = (char)(unsigned char)1; + test(PT::compare(foo, bar) > 0, true); + + foo[0] = (char)(unsigned char)0; + bar[0] = (char)(unsigned char)0; + test(PT::compare(foo, bar) == 0, true); + + foo[0] = (char)(unsigned char)0; + bar[0] = (char)(unsigned char)1; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (char)(unsigned char)1; + bar[0] = (char)(unsigned char)0; + test(PT::compare(foo, bar) > 0, true); +} + + + +void test_text16() +{ + reset_test_counter("compare const wchar_t *"); + + test(PT::compare(L"", L"") == 0, true); + test(PT::compare(L"a", L"a") == 0, true); + test(PT::compare(L"abc", L"abc") == 0, true); + test(PT::compare(L"ABC", L"ABC") == 0, true); + test(PT::compare(L"hello world", L"hello world") == 0, true); + test(PT::compare(L"hello world", L"HELLO WORLD") > 0, true); + test(PT::compare(L"HELLO WORLD", L"hello world") < 0, true); + test(PT::compare(L"HEllo WOrld", L"heLLO woRLD") < 0, true); + test(PT::compare(L"heLLO woRLD", L"HEllo WOrld") > 0, true); + + test(PT::compare(L"a", L"b") < 0, true); + test(PT::compare(L"b", L"c") < 0, true); + test(PT::compare(L"x", L"z") < 0, true); + test(PT::compare(L"hello world", L"xhelloworld") < 0, true); + + test(PT::compare(L"c", L"b") > 0, true); + test(PT::compare(L"d", L"c") > 0, true); + test(PT::compare(L"z", L"x") > 0, true); + test(PT::compare(L"xhello world", L"helloworld") > 0, true); + + test(PT::compare(L"abc8", L"abc9") < 0, true); + test(PT::compare(L"abc9", L"abc8") > 0, true); + test(PT::compare(L"abc8abc", L"abc9abc") < 0, true); + test(PT::compare(L"abc9abc", L"abc8abc") > 0, true); + test(PT::compare(L"abc9abc", L"abc8") > 0, true); + test(PT::compare(L"abc8abc", L"abc9") < 0, true); + test(PT::compare(L"abc8", L"abc9abc") < 0, true); + test(PT::compare(L"abc9", L"abc8abc") > 0, true); + + wchar_t foo[] = {L"abc"}; + wchar_t bar[] = {L"abc"}; + test(PT::compare(foo, bar) == 0, true); + + foo[0] = (wchar_t)127; + bar[0] = (wchar_t)128; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (wchar_t)128; + bar[0] = (wchar_t)127; + test(PT::compare(foo, bar) > 0, true); + + foo[0] = (wchar_t)1; + bar[0] = (wchar_t)255; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (wchar_t)255; + bar[0] = (wchar_t)1; + test(PT::compare(foo, bar) > 0, true); + + foo[0] = (wchar_t)0; + bar[0] = (wchar_t)0; + test(PT::compare(foo, bar) == 0, true); + + foo[0] = (wchar_t)0; + bar[0] = (wchar_t)1; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (wchar_t)1; + bar[0] = (wchar_t)0; + test(PT::compare(foo, bar) > 0, true); + + foo[0] = (wchar_t)1; + bar[0] = (wchar_t)0xffff; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (wchar_t)127; + bar[0] = (wchar_t)0xffff; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (wchar_t)128; + bar[0] = (wchar_t)0xffff; + test(PT::compare(foo, bar) < 0, true); + + foo[0] = (wchar_t)0xffff; + bar[0] = (wchar_t)1; + test(PT::compare(foo, bar) > 0, true); + + foo[0] = (wchar_t)0xffff; + bar[0] = (wchar_t)127; + test(PT::compare(foo, bar) > 0, true); + + foo[0] = (wchar_t)0xffff; + bar[0] = (wchar_t)128; + test(PT::compare(foo, bar) > 0, true); +} + +void test_text17() +{ + reset_test_counter("compare std::string"); + + std::string str1, str2; + test(PT::compare(str1, str2) == 0, true); + + str1 = "abc"; + str2 = "abc"; + test(PT::compare(str1, str2) == 0, true); + + str1 = "aBc"; + str2 = "abc"; + test(PT::compare(str1, str2) < 0, true); + + str1 = "abc"; + str2 = "aBc"; + test(PT::compare(str1, str2) > 0, true); + + str1 = "xyz"; + str2 = "abc"; + test(PT::compare(str1, str2) > 0, true); + + str1 = "abc"; + str2 = "xyz"; + test(PT::compare(str1, str2) < 0, true); + + str1 = "abc1"; + str2 = "abc2"; + test(PT::compare(str1, str2) < 0, true); + + str1 = "abc9"; + str2 = "abc8"; + test(PT::compare(str1, str2) > 0, true); +} + +void test_text18() +{ + reset_test_counter("compare std::wstring"); + + std::wstring str1, str2; + test(PT::compare(str1, str2) == 0, true); + + str1 = L"abc"; + str2 = L"abc"; + test(PT::compare(str1, str2) == 0, true); + + str1 = L"aBc"; + str2 = L"abc"; + test(PT::compare(str1, str2) < 0, true); + + str1 = L"abc"; + str2 = L"aBc"; + test(PT::compare(str1, str2) > 0, true); + + str1 = L"xyz"; + str2 = L"abc"; + test(PT::compare(str1, str2) > 0, true); + + str1 = L"abc"; + str2 = L"xyz"; + test(PT::compare(str1, str2) < 0, true); + + str1 = L"abc1"; + str2 = L"abc2"; + test(PT::compare(str1, str2) < 0, true); + + str1 = L"abc9"; + str2 = L"abc8"; + test(PT::compare(str1, str2) > 0, true); +} + +void test_text19() +{ + reset_test_counter("compare const char* str1_begin, str1_end, str2"); + + char foo[] = {"abcdef"}; + char bar[] = {"abcdef"}; + size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero + + test(PT::compare(foo, foo + len, bar) == 0, true); + test(PT::compare(foo, foo + len - 1, bar) < 0, true); + + foo[len - 1] = (char)(unsigned char)127; + bar[len - 1] = (char)(unsigned char)128; + test(PT::compare(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (char)(unsigned char)128; + bar[len - 1] = (char)(unsigned char)127; + test(PT::compare(foo, foo + len, bar) > 0, true); + + foo[len - 1] = (char)(unsigned char)1; + bar[len - 1] = (char)(unsigned char)255; + test(PT::compare(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (char)(unsigned char)255; + bar[len - 1] = (char)(unsigned char)1; + test(PT::compare(foo, foo + len, bar) > 0, true); + + foo[len - 1] = 'f'; + bar[len - 1] = 'f'; + bar[3] = 'X'; + test(PT::compare(foo, foo + len, bar) > 0, true); + foo[3] = 'A'; + test(PT::compare(foo, foo + len, bar) < 0, true); +} + +void test_text20() +{ + reset_test_counter("compare const wchar_t * str1_begin, str1_end, str2"); + + wchar_t foo[] = {L"abcdef"}; + wchar_t bar[] = {L"abcdef"}; + size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero + + test(PT::compare(foo, foo + len, bar) == 0, true); + test(PT::compare(foo, foo + len - 1, bar) < 0, true); + + foo[len - 1] = (wchar_t)127; + bar[len - 1] = (wchar_t)128; + test(PT::compare(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (wchar_t)128; + bar[len - 1] = (wchar_t)127; + test(PT::compare(foo, foo + len, bar) > 0, true); + + foo[len - 1] = (wchar_t)1; + bar[len - 1] = (wchar_t)255; + test(PT::compare(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (wchar_t)255; + bar[len - 1] = (wchar_t)1; + test(PT::compare(foo, foo + len, bar) > 0, true); + + foo[len - 1] = (wchar_t)1; + bar[len - 1] = (wchar_t)0xffff; + test(PT::compare(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (wchar_t)0xffff; + bar[len - 1] = (wchar_t)1; + test(PT::compare(foo, foo + len, bar) > 0, true); + + foo[len - 1] = L'f'; + bar[len - 1] = L'f'; + bar[3] = L'X'; + test(PT::compare(foo, foo + len, bar) > 0, true); + foo[3] = L'A'; + test(PT::compare(foo, foo + len, bar) < 0, true); +} + + + +void test_text21() +{ + reset_test_counter("compare_nc const char *"); + + test(PT::compare_nc("", "") == 0, true); + test(PT::compare_nc("a", "a") == 0, true); + test(PT::compare_nc("abc", "abc") == 0, true); + test(PT::compare_nc("ABC", "ABC") == 0, true); + test(PT::compare_nc("hello world", "hello world") == 0, true); + test(PT::compare_nc("hello world", "HELLO WORLD") == 0, true); + test(PT::compare_nc("HELLO WORLD", "hello world") == 0, true); + test(PT::compare_nc("HEllo WOrld", "heLLO woRLD") == 0, true); + test(PT::compare_nc("heLLO woRLD", "HEllo WOrld")== 0, true); + + test(PT::compare_nc("a", "b") < 0, true); + test(PT::compare_nc("b", "c") < 0, true); + test(PT::compare_nc("x", "z") < 0, true); + test(PT::compare_nc("hello world", "xhelloworld") < 0, true); + + test(PT::compare_nc("c", "b") > 0, true); + test(PT::compare_nc("d", "c") > 0, true); + test(PT::compare_nc("z", "x") > 0, true); + test(PT::compare_nc("xhello world", "helloworld") > 0, true); + + test(PT::compare_nc("abc8", "abc9") < 0, true); + test(PT::compare_nc("abc9", "abc8") > 0, true); + test(PT::compare_nc("abc8abc", "abc9abc") < 0, true); + test(PT::compare_nc("abc9abc", "abc8abc") > 0, true); + test(PT::compare_nc("abc9abc", "abc8") > 0, true); + test(PT::compare_nc("abc8abc", "abc9") < 0, true); + test(PT::compare_nc("abc8", "abc9abc") < 0, true); + test(PT::compare_nc("abc9", "abc8abc") > 0, true); + + char foo[] = {"abc"}; + char bar[] = {"abc"}; + test(PT::compare_nc(foo, bar) == 0, true); + + foo[0] = (char)(unsigned char)127; + bar[0] = (char)(unsigned char)128; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (char)(unsigned char)128; + bar[0] = (char)(unsigned char)127; + test(PT::compare_nc(foo, bar) > 0, true); + + foo[0] = (char)(unsigned char)1; + bar[0] = (char)(unsigned char)255; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (char)(unsigned char)255; + bar[0] = (char)(unsigned char)1; + test(PT::compare_nc(foo, bar) > 0, true); + + foo[0] = (char)(unsigned char)0; + bar[0] = (char)(unsigned char)0; + test(PT::compare_nc(foo, bar) == 0, true); + + foo[0] = (char)(unsigned char)0; + bar[0] = (char)(unsigned char)1; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (char)(unsigned char)1; + bar[0] = (char)(unsigned char)0; + test(PT::compare_nc(foo, bar) > 0, true); +} + + + +void test_text22() +{ + reset_test_counter("compare_nc const wchar_t *"); + + test(PT::compare_nc(L"", L"") == 0, true); + test(PT::compare_nc(L"a", L"a") == 0, true); + test(PT::compare_nc(L"abc", L"abc") == 0, true); + test(PT::compare_nc(L"ABC", L"ABC") == 0, true); + test(PT::compare_nc(L"hello world", L"hello world") == 0, true); + test(PT::compare_nc(L"hello world", L"HELLO WORLD") == 0, true); + test(PT::compare_nc(L"HELLO WORLD", L"hello world") == 0, true); + test(PT::compare_nc(L"HEllo WOrld", L"heLLO woRLD") == 0, true); + test(PT::compare_nc(L"heLLO woRLD", L"HEllo WOrld") == 0, true); + + test(PT::compare_nc(L"a", L"b") < 0, true); + test(PT::compare_nc(L"b", L"c") < 0, true); + test(PT::compare_nc(L"x", L"z") < 0, true); + test(PT::compare_nc(L"hello world", L"xhelloworld") < 0, true); + + test(PT::compare_nc(L"c", L"b") > 0, true); + test(PT::compare_nc(L"d", L"c") > 0, true); + test(PT::compare_nc(L"z", L"x") > 0, true); + test(PT::compare_nc(L"xhello world", L"helloworld") > 0, true); + + test(PT::compare_nc(L"abc8", L"abc9") < 0, true); + test(PT::compare_nc(L"abc9", L"abc8") > 0, true); + test(PT::compare_nc(L"abc8abc", L"abc9abc") < 0, true); + test(PT::compare_nc(L"abc9abc", L"abc8abc") > 0, true); + test(PT::compare_nc(L"abc9abc", L"abc8") > 0, true); + test(PT::compare_nc(L"abc8abc", L"abc9") < 0, true); + test(PT::compare_nc(L"abc8", L"abc9abc") < 0, true); + test(PT::compare_nc(L"abc9", L"abc8abc") > 0, true); + + wchar_t foo[] = {L"abc"}; + wchar_t bar[] = {L"abc"}; + test(PT::compare_nc(foo, bar) == 0, true); + + foo[0] = (wchar_t)127; + bar[0] = (wchar_t)128; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (wchar_t)128; + bar[0] = (wchar_t)127; + test(PT::compare_nc(foo, bar) > 0, true); + + foo[0] = (wchar_t)1; + bar[0] = (wchar_t)255; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (wchar_t)255; + bar[0] = (wchar_t)1; + test(PT::compare_nc(foo, bar) > 0, true); + + foo[0] = (wchar_t)0; + bar[0] = (wchar_t)0; + test(PT::compare_nc(foo, bar) == 0, true); + + foo[0] = (wchar_t)0; + bar[0] = (wchar_t)1; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (wchar_t)1; + bar[0] = (wchar_t)0; + test(PT::compare_nc(foo, bar) > 0, true); + + foo[0] = (wchar_t)1; + bar[0] = (wchar_t)0xffff; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (wchar_t)127; + bar[0] = (wchar_t)0xffff; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (wchar_t)128; + bar[0] = (wchar_t)0xffff; + test(PT::compare_nc(foo, bar) < 0, true); + + foo[0] = (wchar_t)0xffff; + bar[0] = (wchar_t)1; + test(PT::compare_nc(foo, bar) > 0, true); + + foo[0] = (wchar_t)0xffff; + bar[0] = (wchar_t)127; + test(PT::compare_nc(foo, bar) > 0, true); + + foo[0] = (wchar_t)0xffff; + bar[0] = (wchar_t)128; + test(PT::compare_nc(foo, bar) > 0, true); +} + +void test_text23() +{ + reset_test_counter("compare_nc std::string"); + + std::string str1, str2; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = "abc"; + str2 = "abc"; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = "aBc"; + str2 = "abc"; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = "abc"; + str2 = "aBc"; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = "xyz"; + str2 = "abc"; + test(PT::compare_nc(str1, str2) > 0, true); + + str1 = "abc"; + str2 = "xyz"; + test(PT::compare_nc(str1, str2) < 0, true); + + str1 = "abc1"; + str2 = "abc2"; + test(PT::compare_nc(str1, str2) < 0, true); + + str1 = "abc9"; + str2 = "abc8"; + test(PT::compare_nc(str1, str2) > 0, true); +} + +void test_text24() +{ + reset_test_counter("compare_nc std::wstring"); + + std::wstring str1, str2; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = L"abc"; + str2 = L"abc"; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = L"aBc"; + str2 = L"abc"; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = L"abc"; + str2 = L"aBc"; + test(PT::compare_nc(str1, str2) == 0, true); + + str1 = L"xyz"; + str2 = L"abc"; + test(PT::compare_nc(str1, str2) > 0, true); + + str1 = L"abc"; + str2 = L"xyz"; + test(PT::compare_nc(str1, str2) < 0, true); + + str1 = L"abc1"; + str2 = L"abc2"; + test(PT::compare_nc(str1, str2) < 0, true); + + str1 = L"abc9"; + str2 = L"abc8"; + test(PT::compare_nc(str1, str2) > 0, true); +} + +void test_text25() +{ + reset_test_counter("compare_nc const char* str1_begin, str1_end, str2"); + + char foo[] = {"abcdef"}; + char bar[] = {"abcdef"}; + size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero + + test(PT::compare_nc(foo, foo + len, bar) == 0, true); + test(PT::compare_nc(foo, foo + len - 1, bar) < 0, true); + + foo[len - 1] = (char)(unsigned char)127; + bar[len - 1] = (char)(unsigned char)128; + test(PT::compare_nc(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (char)(unsigned char)128; + bar[len - 1] = (char)(unsigned char)127; + test(PT::compare_nc(foo, foo + len, bar) > 0, true); + + foo[len - 1] = (char)(unsigned char)1; + bar[len - 1] = (char)(unsigned char)255; + test(PT::compare_nc(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (char)(unsigned char)255; + bar[len - 1] = (char)(unsigned char)1; + test(PT::compare_nc(foo, foo + len, bar) > 0, true); + + foo[len - 1] = 'f'; + bar[len - 1] = 'f'; + bar[3] = 'X'; + test(PT::compare_nc(foo, foo + len, bar) < 0, true); + foo[3] = 'Z'; + test(PT::compare_nc(foo, foo + len, bar) > 0, true); +} + +void test_text26() +{ + reset_test_counter("compare_nc const wchar_t * str1_begin, str1_end, str2"); + + wchar_t foo[] = {L"abcdef"}; + wchar_t bar[] = {L"abcdef"}; + size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero + + test(PT::compare_nc(foo, foo + len, bar) == 0, true); + test(PT::compare_nc(foo, foo + len - 1, bar) < 0, true); + + foo[len - 1] = (wchar_t)127; + bar[len - 1] = (wchar_t)128; + test(PT::compare_nc(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (wchar_t)128; + bar[len - 1] = (wchar_t)127; + test(PT::compare_nc(foo, foo + len, bar) > 0, true); + + foo[len - 1] = (wchar_t)1; + bar[len - 1] = (wchar_t)255; + test(PT::compare_nc(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (wchar_t)255; + bar[len - 1] = (wchar_t)1; + test(PT::compare_nc(foo, foo + len, bar) > 0, true); + + foo[len - 1] = (wchar_t)1; + bar[len - 1] = (wchar_t)0xffff; + test(PT::compare_nc(foo, foo + len, bar) < 0, true); + + foo[len - 1] = (wchar_t)0xffff; + bar[len - 1] = (wchar_t)1; + test(PT::compare_nc(foo, foo + len, bar) > 0, true); + + foo[len - 1] = L'f'; + bar[len - 1] = L'f'; + bar[3] = L'X'; + test(PT::compare_nc(foo, foo + len, bar) < 0, true); + foo[3] = L'Z'; + test(PT::compare_nc(foo, foo + len, bar) > 0, true); +} + + +void test_text27() +{ + reset_test_counter("is_equal char *"); + + test(is_equal("", ""), true); + test(is_equal("", "abc"), false); + test(is_equal("abc", ""), false); + test(is_equal("abc", "abc"), true); + test(is_equal("aBc", "aBc"), true); + test(is_equal("aBc", "abc"), false); + test(is_equal("abc", "aBc"), false); + test(is_equal("abc", "defgh"), false); + test(is_equal("defgh", "abc"), false); +} + +void test_text28() +{ + reset_test_counter("is_equal wchar_t *"); + + test(is_equal(L"", L""), true); + test(is_equal(L"", L"abc"), false); + test(is_equal(L"abc", L""), false); + test(is_equal(L"abc", L"abc"), true); + test(is_equal(L"aBc", L"aBc"), true); + test(is_equal(L"aBc", L"abc"), false); + test(is_equal(L"abc", L"aBc"), false); + test(is_equal(L"abc", L"defgh"), false); + test(is_equal(L"defgh", L"abc"), false); +} + +void test_text29() +{ + reset_test_counter("is_equal std::string"); + + std::string str1, str2; + test(is_equal(str1, str2), true); + + str2 = "xyz"; + test(is_equal(str1, str2), false); + + str1 = "xyz"; + str2 = ""; + test(is_equal(str1, str2), false); + + str1 = "xyz"; + str2 = "xYz"; + test(is_equal(str1, str2), false); + + str1 = "xYz"; + str2 = "xyz"; + test(is_equal(str1, str2), false); + + str1 = "abcxyz"; + str2 = "abc"; + test(is_equal(str1, str2), false); + + str1 = "abc"; + str2 = "abcxyz"; + test(is_equal(str1, str2), false); + + str1 = "xyzabc"; + str2 = "abc"; + test(is_equal(str1, str2), false); + + str1 = "abc"; + str2 = "xyzabc"; + test(is_equal(str1, str2), false); + + str1 = "xyz"; + str2 = "xyz"; + test(is_equal(str1, str2), true); +} + + +void test_text30() +{ + reset_test_counter("is_equal std::wstring"); + + std::wstring str1, str2; + test(is_equal(str1, str2), true); + + str2 = L"xyz"; + test(is_equal(str1, str2), false); + + str1 = L"xyz"; + str2 = L""; + test(is_equal(str1, str2), false); + + str1 = L"xyz"; + str2 = L"xYz"; + test(is_equal(str1, str2), false); + + str1 = L"xYz"; + str2 = L"xyz"; + test(is_equal(str1, str2), false); + + str1 = L"abcxyz"; + str2 = L"abc"; + test(is_equal(str1, str2), false); + + str1 = L"abc"; + str2 = L"abcxyz"; + test(is_equal(str1, str2), false); + + str1 = L"xyzabc"; + str2 = L"abc"; + test(is_equal(str1, str2), false); + + str1 = L"abc"; + str2 = L"xyzabc"; + test(is_equal(str1, str2), false); + + str1 = L"xyz"; + str2 = L"xyz"; + test(is_equal(str1, str2), true); +} + + +void test_text31() +{ + reset_test_counter("is_equal const char*, str1_begin, str1_end, str2"); + + char foo[] = {"ABCDEF"}; + char bar[] = {"ABCDEF"}; + size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero + + test(PT::is_equal(foo, foo + len, bar), true); + test(PT::is_equal(foo, foo + len - 1, bar), false); + + foo[len - 1] = (char)(unsigned char)127; + bar[len - 1] = (char)(unsigned char)128; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = (char)(unsigned char)128; + bar[len - 1] = (char)(unsigned char)127; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = (char)(unsigned char)1; + bar[len - 1] = (char)(unsigned char)255; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = (char)(unsigned char)255; + bar[len - 1] = (char)(unsigned char)1; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = 'f'; + bar[len - 1] = 'f'; + bar[3] = 'X'; + test(PT::is_equal(foo, foo + len, bar), false); + foo[3] = 'A'; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[3] = '1'; + bar[3] = '1'; + test(PT::is_equal(foo, foo + len, bar), true); +} + + +void test_text32() +{ + reset_test_counter("is_equal const wchar_t*, str1_begin, str1_end, str2"); + + wchar_t foo[] = {L"ABCDEF"}; + wchar_t bar[] = {L"ABCDEF"}; + size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero + + test(PT::is_equal(foo, foo + len, bar), true); + test(PT::is_equal(foo, foo + len - 1, bar), false); + + foo[len - 1] = (wchar_t)127; + bar[len - 1] = (wchar_t)128; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = (wchar_t)128; + bar[len - 1] = (wchar_t)127; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = (wchar_t)1; + bar[len - 1] = (wchar_t)255; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = (wchar_t)255; + bar[len - 1] = (wchar_t)1; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[len - 1] = L'f'; + bar[len - 1] = L'f'; + bar[3] = L'X'; + test(PT::is_equal(foo, foo + len, bar), false); + foo[3] = L'A'; + test(PT::is_equal(foo, foo + len, bar), false); + + foo[3] = L'1'; + bar[3] = L'1'; + test(PT::is_equal(foo, foo + len, bar), true); +} + + + +void test_text33() +{ + reset_test_counter("is_equal_nc char *"); + + test(is_equal_nc("", ""), true); + test(is_equal_nc("", "abc"), false); + test(is_equal_nc("abc", ""), false); + test(is_equal_nc("abc", "abc"), true); + test(is_equal_nc("aBc", "aBc"), true); + test(is_equal_nc("aBc", "abc"), true); + test(is_equal_nc("abc", "aBc"), true); + test(is_equal_nc("abc", "defgh"), false); + test(is_equal_nc("defgh", "abc"), false); +} + +void test_text34() +{ + reset_test_counter("is_equal_nc wchar_t *"); + + test(is_equal_nc(L"", L""), true); + test(is_equal_nc(L"", L"abc"), false); + test(is_equal_nc(L"abc", L""), false); + test(is_equal_nc(L"abc", L"abc"), true); + test(is_equal_nc(L"aBc", L"aBc"), true); + test(is_equal_nc(L"aBc", L"abc"), true); + test(is_equal_nc(L"abc", L"aBc"), true); + test(is_equal_nc(L"abc", L"defgh"), false); + test(is_equal_nc(L"defgh", L"abc"), false); +} + +void test_text35() +{ + reset_test_counter("is_equal_nc std::string"); + + std::string str1, str2; + test(is_equal_nc(str1, str2), true); + + str2 = "xyz"; + test(is_equal_nc(str1, str2), false); + + str1 = "xyz"; + str2 = ""; + test(is_equal_nc(str1, str2), false); + + str1 = "xyz"; + str2 = "xYz"; + test(is_equal_nc(str1, str2), true); + + str1 = "xYz"; + str2 = "xyz"; + test(is_equal_nc(str1, str2), true); + + str1 = "abcxyz"; + str2 = "abc"; + test(is_equal_nc(str1, str2), false); + + str1 = "abc"; + str2 = "abcxyz"; + test(is_equal_nc(str1, str2), false); + + str1 = "xyzabc"; + str2 = "abc"; + test(is_equal_nc(str1, str2), false); + + str1 = "abc"; + str2 = "xyzabc"; + test(is_equal_nc(str1, str2), false); + + str1 = "xyz"; + str2 = "xyz"; + test(is_equal_nc(str1, str2), true); +} + + +void test_text36() +{ + reset_test_counter("is_equal_nc std::wstring"); + + std::wstring str1, str2; + test(is_equal_nc(str1, str2), true); + + str2 = L"xyz"; + test(is_equal_nc(str1, str2), false); + + str1 = L"xyz"; + str2 = L""; + test(is_equal_nc(str1, str2), false); + + str1 = L"xyz"; + str2 = L"xYz"; + test(is_equal_nc(str1, str2), true); + + str1 = L"xYz"; + str2 = L"xyz"; + test(is_equal_nc(str1, str2), true); + + str1 = L"abcxyz"; + str2 = L"abc"; + test(is_equal_nc(str1, str2), false); + + str1 = L"abc"; + str2 = L"abcxyz"; + test(is_equal_nc(str1, str2), false); + + str1 = L"xyzabc"; + str2 = L"abc"; + test(is_equal_nc(str1, str2), false); + + str1 = L"abc"; + str2 = L"xyzabc"; + test(is_equal_nc(str1, str2), false); + + str1 = L"xyz"; + str2 = L"xyz"; + test(is_equal_nc(str1, str2), true); +} + + +void test_text37() +{ + reset_test_counter("is_equal_nc const char*, str1_begin, str1_end, str2"); + + char foo[] = {"ABCDEF"}; + char bar[] = {"ABCDEF"}; + size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero + + test(PT::is_equal_nc(foo, foo + len, bar), true); + test(PT::is_equal_nc(foo, foo + len - 1, bar), false); + + foo[len - 1] = (char)(unsigned char)127; + bar[len - 1] = (char)(unsigned char)128; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = (char)(unsigned char)128; + bar[len - 1] = (char)(unsigned char)127; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = (char)(unsigned char)1; + bar[len - 1] = (char)(unsigned char)255; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = (char)(unsigned char)255; + bar[len - 1] = (char)(unsigned char)1; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = 'f'; + bar[len - 1] = 'f'; + bar[3] = 'X'; + test(PT::is_equal_nc(foo, foo + len, bar), false); + foo[3] = 'A'; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[3] = '1'; + bar[3] = '1'; + test(PT::is_equal_nc(foo, foo + len, bar), true); + + foo[3] = 'h'; + bar[3] = 'H'; + test(PT::is_equal_nc(foo, foo + len, bar), true); + + foo[3] = 'H'; + bar[3] = 'h'; + test(PT::is_equal_nc(foo, foo + len, bar), true); +} + + +void test_text38() +{ + reset_test_counter("is_equal_nc const wchar_t*, str1_begin, str1_end, str2"); + + wchar_t foo[] = {L"ABCDEF"}; + wchar_t bar[] = {L"ABCDEF"}; + size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero + + test(PT::is_equal_nc(foo, foo + len, bar), true); + test(PT::is_equal_nc(foo, foo + len - 1, bar), false); + + foo[len - 1] = (wchar_t)127; + bar[len - 1] = (wchar_t)128; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = (wchar_t)128; + bar[len - 1] = (wchar_t)127; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = (wchar_t)1; + bar[len - 1] = (wchar_t)255; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = (wchar_t)255; + bar[len - 1] = (wchar_t)1; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[len - 1] = L'f'; + bar[len - 1] = L'f'; + bar[3] = L'X'; + test(PT::is_equal_nc(foo, foo + len, bar), false); + foo[3] = L'A'; + test(PT::is_equal_nc(foo, foo + len, bar), false); + + foo[3] = L'1'; + bar[3] = L'1'; + test(PT::is_equal_nc(foo, foo + len, bar), true); + + foo[3] = L'h'; + bar[3] = L'H'; + test(PT::is_equal_nc(foo, foo + len, bar), true); + + foo[3] = L'H'; + bar[3] = L'h'; + test(PT::is_equal_nc(foo, foo + len, bar), true); +} + + +void test_text39() +{ + reset_test_counter("is_substr const char *"); + + test(PT::is_substr("", ""), true); + test(PT::is_substr("", "a"), true); + test(PT::is_substr("a", ""), false); + test(PT::is_substr("a", "a"), true); + test(PT::is_substr("a", "ab"), true); + test(PT::is_substr("abc", "abb"), false); + test(PT::is_substr("abc", "abcd"), true); + test(PT::is_substr("XYZ", "XYZabc"), true); + test(PT::is_substr("XYZ", "xYz"), false); + test(PT::is_substr("hello world", "hello world"), true); + test(PT::is_substr("hello world", "abc hello world"), false); + test(PT::is_substr("hello world", "hello worldabc"), true); + test(PT::is_substr("Hello World", "hello world"), false); + test(PT::is_substr("hello world", "Hello World"), false); +} + + +void test_text40() +{ + reset_test_counter("is_substr const wchar_t *"); + + test(PT::is_substr(L"", L""), true); + test(PT::is_substr(L"", L"a"), true); + test(PT::is_substr(L"a", L""), false); + test(PT::is_substr(L"a", L"a"), true); + test(PT::is_substr(L"a", L"ab"), true); + test(PT::is_substr(L"abc", L"abb"), false); + test(PT::is_substr(L"abc", L"abcd"), true); + test(PT::is_substr(L"XYZ", L"XYZabc"), true); + test(PT::is_substr(L"XYZ", L"xYz"), false); + test(PT::is_substr(L"hello world", L"hello world"), true); + test(PT::is_substr(L"hello world", L"abc hello world"), false); + test(PT::is_substr(L"hello world", L"hello worldabc"), true); + test(PT::is_substr(L"Hello World", L"hello world"), false); + test(PT::is_substr(L"hello world", L"Hello World"), false); +} + + + +void test_text41() +{ + reset_test_counter("is_substr std::string"); + + std::string str1, str2; + test(PT::is_substr(str1, str2), true); + + str1 = ""; + str2 = "a"; + test(PT::is_substr(str1, str2), true); + + str1 = "a"; + str2 = "a"; + test(PT::is_substr(str1, str2), true); + + str1 = "a"; + str2 = ""; + test(PT::is_substr(str1, str2), false); + + str1 = "abcd"; + str2 = "abcd"; + test(PT::is_substr(str1, str2), true); + + str1 = "abcdefg"; + str2 = "abcd"; + test(PT::is_substr(str1, str2), false); + + str1 = "abcd"; + str2 = "abcdefg"; + test(PT::is_substr(str1, str2), true); + + str1 = "aBCd"; + str2 = "abcd"; + test(PT::is_substr(str1, str2), false); + + str1 = "abcd"; + str2 = "aBCd"; + test(PT::is_substr(str1, str2), false); + + str1 = "aBCdefg"; + str2 = "abcd"; + test(PT::is_substr(str1, str2), false); + + str1 = "aBCd"; + str2 = "abcdefg"; + test(PT::is_substr(str1, str2), false); + + str1 = "abcd"; + str2 = "aBCdefg"; + test(PT::is_substr(str1, str2), false); +} + + +void test_text42() +{ + reset_test_counter("is_substr std::wstring"); + + std::wstring str1, str2; + test(PT::is_substr(str1, str2), true); + + str1 = L""; + str2 = L"a"; + test(PT::is_substr(str1, str2), true); + + str1 = L"a"; + str2 = L"a"; + test(PT::is_substr(str1, str2), true); + + str1 = L"a"; + str2 = L""; + test(PT::is_substr(str1, str2), false); + + str1 = L"abcd"; + str2 = L"abcd"; + test(PT::is_substr(str1, str2), true); + + str1 = L"abcdefg"; + str2 = L"abcd"; + test(PT::is_substr(str1, str2), false); + + str1 = L"abcd"; + str2 = L"abcdefg"; + test(PT::is_substr(str1, str2), true); + + str1 = L"aBCd"; + str2 = L"abcd"; + test(PT::is_substr(str1, str2), false); + + str1 = L"abcd"; + str2 = L"aBCd"; + test(PT::is_substr(str1, str2), false); + + str1 = L"aBCdefg"; + str2 = L"abcd"; + test(PT::is_substr(str1, str2), false); + + str1 = L"aBCd"; + str2 = L"abcdefg"; + test(PT::is_substr(str1, str2), false); + + str1 = L"abcd"; + str2 = L"aBCdefg"; + test(PT::is_substr(str1, str2), false); +} + + + +void test_text43() +{ + reset_test_counter("is_substr_nc const char *"); + + test(PT::is_substr_nc("", ""), true); + test(PT::is_substr_nc("", "a"), true); + test(PT::is_substr_nc("a", ""), false); + test(PT::is_substr_nc("a", "a"), true); + test(PT::is_substr_nc("a", "ab"), true); + test(PT::is_substr_nc("abc", "abb"), false); + test(PT::is_substr_nc("abc", "abcd"), true); + test(PT::is_substr_nc("XYZ", "XYZabc"), true); + test(PT::is_substr_nc("XYZ", "xYz"), true); + test(PT::is_substr_nc("hello world", "hello world"), true); + test(PT::is_substr_nc("hello world", "abc hello world"), false); + test(PT::is_substr_nc("hello world", "hello worldabc"), true); + test(PT::is_substr_nc("Hello World", "hello world"), true); + test(PT::is_substr_nc("hello world", "Hello World"), true); +} + + +void test_text44() +{ + reset_test_counter("is_substr_nc const wchar_t *"); + + test(PT::is_substr_nc(L"", L""), true); + test(PT::is_substr_nc(L"", L"a"), true); + test(PT::is_substr_nc(L"a", L""), false); + test(PT::is_substr_nc(L"a", L"a"), true); + test(PT::is_substr_nc(L"a", L"ab"), true); + test(PT::is_substr_nc(L"abc", L"abb"), false); + test(PT::is_substr_nc(L"abc", L"abcd"), true); + test(PT::is_substr_nc(L"XYZ", L"XYZabc"), true); + test(PT::is_substr_nc(L"XYZ", L"xYz"), true); + test(PT::is_substr_nc(L"hello world", L"hello world"), true); + test(PT::is_substr_nc(L"hello world", L"abc hello world"), false); + test(PT::is_substr_nc(L"hello world", L"hello worldabc"), true); + test(PT::is_substr_nc(L"Hello World", L"hello world"), true); + test(PT::is_substr_nc(L"hello world", L"Hello World"), true); +} + + + +void test_text45() +{ + reset_test_counter("is_substr_nc std::string"); + + std::string str1, str2; + test(PT::is_substr_nc(str1, str2), true); + + str1 = ""; + str2 = "a"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = "a"; + str2 = "a"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = "a"; + str2 = ""; + test(PT::is_substr_nc(str1, str2), false); + + str1 = "abcd"; + str2 = "abcd"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = "abcdefg"; + str2 = "abcd"; + test(PT::is_substr_nc(str1, str2), false); + + str1 = "abcd"; + str2 = "abcdefg"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = "aBCd"; + str2 = "abcd"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = "abcd"; + str2 = "aBCd"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = "aBCdefg"; + str2 = "abcd"; + test(PT::is_substr_nc(str1, str2), false); + + str1 = "aBCd"; + str2 = "abcdefg"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = "abcd"; + str2 = "aBCdefg"; + test(PT::is_substr_nc(str1, str2), true); +} + + + +void test_text46() +{ + reset_test_counter("is_substr_nc std::wstring"); + + std::wstring str1, str2; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L""; + str2 = L"a"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L"a"; + str2 = L"a"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L"a"; + str2 = L""; + test(PT::is_substr_nc(str1, str2), false); + + str1 = L"abcd"; + str2 = L"abcd"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L"abcdefg"; + str2 = L"abcd"; + test(PT::is_substr_nc(str1, str2), false); + + str1 = L"abcd"; + str2 = L"abcdefg"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L"aBCd"; + str2 = L"abcd"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L"abcd"; + str2 = L"aBCd"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L"aBCdefg"; + str2 = L"abcd"; + test(PT::is_substr_nc(str1, str2), false); + + str1 = L"aBCd"; + str2 = L"abcdefg"; + test(PT::is_substr_nc(str1, str2), true); + + str1 = L"abcd"; + str2 = L"aBCdefg"; + test(PT::is_substr_nc(str1, str2), true); +} + + + + +void make_tests() +{ + test_text1(); + test_text2(); + test_text3(); + test_text4(); + test_text5(); + test_text6(); + test_text7(); + test_text8(); + test_text9(); + test_text10(); + test_text11(); + test_text12(); + test_text13(); + test_text14(); + test_text15(); + test_text16(); + test_text17(); + test_text18(); + test_text19(); + test_text20(); + test_text21(); + test_text22(); + test_text23(); + test_text24(); + test_text25(); + test_text26(); + test_text27(); + test_text28(); + test_text29(); + test_text30(); + test_text31(); + test_text32(); + test_text33(); + test_text34(); + test_text35(); + test_text36(); + test_text37(); + test_text38(); + test_text39(); + test_text40(); + test_text41(); + test_text42(); + test_text43(); + test_text44(); + test_text45(); + test_text46(); +} + + +} + +} + + diff --git a/tests/convert.h b/tests/convert.h new file mode 100644 index 0000000..431697e --- /dev/null +++ b/tests/convert.h @@ -0,0 +1,61 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_tests_convert +#define headerfile_picotools_tests_convert + +namespace pt +{ + +namespace pt_convert_tests +{ + + + + + +void make_tests(); + + + + + +} + +} + +#endif diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 0000000..3d5cc58 --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,67 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "convert.h" +#include + + +namespace pt +{ +bool was_error = false; +int test_counter = 0; +const char * test_msg = nullptr; +} + + +int main() +{ + pt::pt_convert_tests::make_tests(); + + + if( pt::was_error ) + { + std::cout << "some of the tests failed" << std::endl; + } + else + { + std::cout << "*********************************" << std::endl; + std::cout << "* all tests passed successfully *" << std::endl; + std::cout << "*********************************" << std::endl; + } + + return !pt::was_error ? 0 : 1; +} diff --git a/tests/test.cpp b/tests/test.cpp new file mode 100644 index 0000000..2547c1a --- /dev/null +++ b/tests/test.cpp @@ -0,0 +1,110 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test.h" + + + +namespace pt +{ + + +void reset_test_counter() +{ + test_counter = 1; + test_msg = nullptr; +} + + +void reset_test_counter(const char * msg) +{ + test_counter = 1; + test_msg = msg; +} + + +void test_status(bool status) +{ + if( status ) + { + std::cout << " OK"; + } + else + { + std::cout << " Fail"; + was_error = true; + } + + std::cout << std::endl; +} + + +template<> +bool test(const char * test_msg, const char * provided, const char * expected) +{ + std::cout << "test " << test_counter << ": "; + + if( test_msg ) + std::cout << test_msg; + + bool status = (std::strcmp(provided, expected) == 0); + test_status(status); + test_counter += 1; + + return status; +} + + +template<> +bool test(const char * test_msg, const wchar_t * provided, const wchar_t * expected) +{ + std::cout << "test " << test_counter << ": "; + + if( test_msg ) + std::cout << test_msg; + + bool status = (std::wcscmp(provided, expected) == 0); + test_status(status); + test_counter += 1; + + return status; +} + + +} + + diff --git a/tests/test.h b/tests/test.h new file mode 100644 index 0000000..46d9da2 --- /dev/null +++ b/tests/test.h @@ -0,0 +1,92 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_tests_test +#define headerfile_picotools_tests_test + +#include +#include + + + +namespace pt +{ +extern int test_counter; +extern const char * test_msg; +extern bool was_error; + + +void test_status(bool status); +void reset_test_counter(); +void reset_test_counter(const char * msg); + + + +template +bool test(const char * test_msg, type_t provided, type_t expected) +{ + std::cout << "test " << test_counter << ": "; + + if( test_msg ) + std::cout << test_msg; + + bool status = provided == expected; + test_status(status); + test_counter += 1; + + return status; +} + + +template +bool test(type_t provided, type_t expected) +{ + return test(test_msg, provided, expected); +} + + +template<> +bool test(const char * test_msg, const char * provided, const char * expected); + +template<> +bool test(const char * test_msg, const wchar_t * provided, const wchar_t * expected); + + + +} + +#endif From 7bdc4d2fc7789169c7cda8c1cb47ec15be7f5155 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:10:10 +0200 Subject: [PATCH 40/67] added global Makefile --- Makefile | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..70cc850 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ + + +export CXX +export CXXFLAGS +export AR + + +all: src tests + + +src: FORCE + $(MAKE) -C src + + +tests: FORCE + $(MAKE) -C tests + + +clean: FORCE + $(MAKE) -C src clean + $(MAKE) -C tests clean + + +depend: FORCE + $(MAKE) -C src depend + $(MAKE) -C tests depend + + +FORCE: + From d3dd74b3d474b47b8763fcf247339178635cd47d Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:16:54 +0200 Subject: [PATCH 41/67] added tests/tests to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2da86a3..5b52685 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .settings/ *.o *.a +tests/tests From 1260b303bc444a17b76b1ac42b2dced40e3e65f7 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 21:24:37 +0200 Subject: [PATCH 42/67] added ./m to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5b52685..e66d9ce 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.o *.a tests/tests +m From 3d6c4e27c0856eedc5994f0823727fe8c149e953 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sat, 15 May 2021 18:34:10 +0200 Subject: [PATCH 43/67] added .editorconfig file with tab style and tab size information https://editorconfig.org/ --- .editorconfig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e34073d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# EditorConfig +# https://editorconfig.org/ +# https://editorconfig-specification.readthedocs.io/ + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# 4 space indentation +[*.{h,cpp,html,css,js,conf,txt}] +indent_style = tab +indent_size = 4 + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab +indent_size = 4 From 77d7bb5e64b18d9b353669e5218ef8c71997fa4f Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 17 May 2021 03:08:32 +0200 Subject: [PATCH 44/67] fixed in Space: set_empty_string(), set_empty_wstring(), set_empty_table() and set_empty_object() didn't clear its object if the same kind of object already existed --- src/space/space.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- src/space/space.h | 7 +++++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/space/space.cpp b/src/space/space.cpp index 0e53374..531d7e5 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -187,24 +187,53 @@ void Space::set_null() initialize_value_null_if_needed(); } + void Space::set_empty_string() { - initialize_value_string_if_needed(); + if( type == type_string ) + { + value.value_string.clear(); + } + else + { + initialize_value_string_if_needed(); + } } void Space::set_empty_wstring() { - initialize_value_wstring_if_needed(); + if( type == type_wstring ) + { + value.value_wstring.clear(); + } + else + { + initialize_value_wstring_if_needed(); + } } void Space::set_empty_table() { - initialize_value_table_if_needed(); + if( type == type_table ) + { + value.value_table.clear(); + } + else + { + initialize_value_table_if_needed(); + } } void Space::set_empty_object() { - initialize_value_object_if_needed(); + if( type == type_object ) + { + value.value_object.clear(); + } + else + { + initialize_value_object_if_needed(); + } } @@ -1542,6 +1571,11 @@ const Space * Space::get_object_field(const wchar_t * field) const } +Space * Space::get_object_field(const std::wstring & field) +{ + return get_object_field(field.c_str()); +} + const Space * Space::get_object_field(const std::wstring & field) const { return get_object_field(field.c_str()); diff --git a/src/space/space.h b/src/space/space.h index 12c6e6f..b9de2c2 100644 --- a/src/space/space.h +++ b/src/space/space.h @@ -430,6 +430,11 @@ public: // getters from object Space * get_object_field(const wchar_t * field); // may a better name? + const Space * get_object_field(const wchar_t * field) const; // may a better name? + Space * get_object_field(const std::wstring & field); + const Space * get_object_field(const std::wstring & field) const; // may a better name? + + bool * get_bool(const wchar_t * field); long long * get_llong(const wchar_t * field); long long * get_long_long(const wchar_t * field); @@ -455,8 +460,6 @@ public: bool has_key(const wchar_t * field) const; // may has_key() would be a better name? bool has_key(const std::wstring & field) const; - const Space * get_object_field(const wchar_t * field) const; // may a better name? - const Space * get_object_field(const std::wstring & field) const; // may a better name? const bool * get_bool(const wchar_t * field) const; const long long * get_llong(const wchar_t * field) const; From ac691bccb7bcdc382e7a8448d9776603a729116b Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 17 May 2021 03:09:21 +0200 Subject: [PATCH 45/67] updated MainSpaceParser to the new Space format, changed api to snake case now we can: - parse short options, those beginning with a hypnen '-' - parse long options, those beginning with two hyphens '--' - long options can have arguments in two forms: - either with an equal sign, e.g.: --opion-name=argument - or with a space, e.g: --option argument in the latter case we can have more than one argument, e.g: --option argument1 argument2 - parse non-option arguments, those after two hyphens to the end of a string, e.g: -- arg1 arg2 --- src/mainspaceparser/mainspaceparser.cpp | 402 +++++++++++++++--------- src/mainspaceparser/mainspaceparser.h | 109 +++++-- 2 files changed, 333 insertions(+), 178 deletions(-) diff --git a/src/mainspaceparser/mainspaceparser.cpp b/src/mainspaceparser/mainspaceparser.cpp index e86d491..cfd2f79 100644 --- a/src/mainspaceparser/mainspaceparser.cpp +++ b/src/mainspaceparser/mainspaceparser.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2016-2017, Tomasz Sowa + * Copyright (c) 2016-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,100 +40,131 @@ #include "utf8/utf8.h" #include -// REMOVE ME -#include namespace PT { -#ifdef nonexisting_value MainSpaceParser::MainSpaceParser() { space = 0; - options_space = 0; - use_utf8 = true; + arguments_required_space = 0; + should_use_utf8 = true; last_status = status_ok; + non_option_arguments_name = L"args"; } MainSpaceParser::~MainSpaceParser() { - - } -void MainSpaceParser::UTF8(bool utf8) +void MainSpaceParser::use_utf8(bool utf8) { - use_utf8 = utf8; + should_use_utf8 = utf8; } -void MainSpaceParser::SetSpace(Space & space_ref) +void MainSpaceParser::set_non_options_arguments_name(const wchar_t * name) { - space = &space_ref; - options_space = 0; + non_option_arguments_name = name; } -std::wstring & MainSpaceParser::GetErrorToken() +void MainSpaceParser::set_non_options_arguments_name(const std::wstring & name) { - return last_error_token; + non_option_arguments_name = name; } -MainSpaceParser::Status MainSpaceParser::Parse(int argc, const char ** argv) -{ - if( !space ) - { - return status_space_not_assigned; - } - options_space = space->FindSpace(L"options"); - last_status = status_ok; - last_error_token.clear(); +std::wstring & MainSpaceParser::get_wrong_option() +{ + return last_error_option; +} + +MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Space & out_space) +{ + space = &out_space; + arguments_required_space = nullptr; + + return parse(argc, argv); +} + + +MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Space & out_space, const Space & options) +{ + space = &out_space; + arguments_required_space = &options;; + + return parse(argc, argv); +} + + +MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv) +{ + last_status = status_ok; + last_error_option.clear(); for(size_t i=1 ; i < (size_t)argc && last_status == status_ok ; ) { - Parse((size_t)argc, argv, i); + parse((size_t)argc, argv, i); } + options.clear(); + option.clear(); + argument.clear(); + arguments.clear(); + return last_status; } -void MainSpaceParser::Parse(size_t argc, const char ** argv, size_t & argv_index) +void MainSpaceParser::parse(size_t argc, const char ** argv, size_t & argv_index) { const char * pchar = argv[argv_index]; if( *pchar == '-' ) { + if( *(pchar+1) == '-' && *(pchar+2) == 0 ) + { + // two hyphens only "--" + argv_index += 1; + parse_non_option_arguments(argc, argv, argv_index); + } + else if( *(pchar+1) == '-' ) { - ParseMultiArgument(argc, argv, argv_index); + // two hyphens and a string, such as "--abc" + parse_long_option(argc, argv, argv_index); + } + else + if( *(pchar+1) != 0 ) + { + // one hyphen and a string, such as "-abc" + parse_short_option(argc, argv, argv_index); } else { - ParseSingleArgument(argc, argv, argv_index); + parse_non_option_arguments(argc, argv, argv_index); } } else { - last_status = status_syntax_error; - ConvertStr(pchar, last_error_token); + parse_non_option_arguments(argc, argv, argv_index); } } -void MainSpaceParser::ConvertStr(const char * src, std::wstring & dst) +void MainSpaceParser::convert_str(const char * src, std::wstring & dst) { - if( use_utf8 ) + if( should_use_utf8 ) { - PT::UTF8ToWide(src,dst); + PT::UTF8ToWide(src, dst); } else { @@ -145,154 +176,219 @@ void MainSpaceParser::ConvertStr(const char * src, std::wstring & dst) } -void MainSpaceParser::ParseSingleArgument(size_t argc, const char ** argv, size_t & argv_index) +void MainSpaceParser::convert_str(const char * src, size_t len, std::wstring & dst) { - ConvertStr(argv[argv_index] + 1, wide_arg); - const wchar_t * wide_pchar = wide_arg.c_str(); - - temp_list_val.clear(); - bool was_option = false; - argv_index += 1; - - for( ; *wide_pchar && !was_option ; ++wide_pchar ) + if( should_use_utf8 ) { - temp_arg = *wide_pchar; - size_t opt_size = RequireOption(temp_arg); - - if( opt_size > 0 ) - { - was_option = true; - - if( *(wide_pchar+1) ) - { - temp_val = wide_pchar + 1; - temp_list_val.push_back(temp_val); - opt_size -= 1; - } - - for( ; opt_size > 0 && argv_index < argc ; --opt_size, ++argv_index) - { - ConvertStr(argv[argv_index], temp_val); - temp_list_val.push_back(temp_val); - } - - if( opt_size > 0 ) - { - last_status = status_reading_eof; - last_error_token.clear(); - } - } - - temp_val.clear(); - AddValueToItem(temp_arg, temp_val, temp_list_val); - } -} - - -void MainSpaceParser::ParseMultiArgument(size_t argc, const char ** argv, size_t & argv_index) -{ - ConvertStr(argv[argv_index] + 2, temp_arg); - argv_index += 1; - - size_t opt_size = RequireOption(temp_arg); - temp_list_val.clear(); - - if( opt_size > 0 ) - { - for( ; opt_size > 0 && argv_index < argc ; --opt_size, ++argv_index) - { - ConvertStr(argv[argv_index], temp_val); - temp_list_val.push_back(temp_val); - } - - if( opt_size > 0 ) - { - last_status = status_reading_eof; - last_error_token.clear(); - } - } - - temp_val.clear(); - AddValueToItem(temp_arg, temp_val, temp_list_val); -} - - - -void MainSpaceParser::AddValueToItem(const std::wstring & name, const std::wstring & empty_value, const std::vector & list) -{ - std::wstring * val = space->GetFirstValue(name); - - if( !val ) - { - if( list.empty() ) - space->Add(name, empty_value); - else - if( list.size() == 1 ) - space->Add(name, list[0]); - else - space->table[name] = list; // !! IMPROVE ME there'll be a new api in space + PT::UTF8ToWide(src, len, dst); } else { - PT::Space::Table::iterator i = space->table.find(name); - PT::Space::Value * table_value; + dst.clear(); - if( i == space->table.end() ) + for(size_t i=0 ; i < len ; ++i) + dst += (wchar_t)(unsigned char)src[i]; + } +} + + +void MainSpaceParser::convert_str(const std::wstring & src, Space & space) +{ + if( should_use_utf8 ) + { + space.set_empty_wstring(); + space.value.value_wstring = src; + } + else + { + space.set_empty_string(); + std::string & dst = space.value.value_string; + + dst.clear(); + + for(size_t i=0 ; i < src.size() ; ++i) + dst += (char)src[i]; + } +} + + +void MainSpaceParser::parse_short_option(size_t argc, const char ** argv, size_t & argv_index) +{ + convert_str(argv[argv_index] + 1, options); + const wchar_t * options_pchar = options.c_str(); + + arguments.clear(); + bool was_argument = false; + argv_index += 1; + + for( ; *options_pchar && !was_argument && last_status == status_ok ; ++options_pchar ) + { + option = *options_pchar; + size_t args_len = how_many_arguments_required(option); + + if( args_len > 0 ) { - table_value = &space->table[name]; - table_value->push_back(*val); - //space->table_single.erase(name); + was_argument = true; + + if( *(options_pchar+1) ) + { + // first argument is directly behind the option + argument = options_pchar + 1; + arguments.push_back(argument); + args_len -= 1; + } + + parse_arguments(argc, argv, argv_index, args_len); + } + + add_option_to_space(option, arguments); + } +} + + +void MainSpaceParser::parse_long_option(size_t argc, const char ** argv, size_t & argv_index) +{ + const char * option_begin = argv[argv_index] + 2; // skip first two hyphens -- + const char * option_end = option_begin; + bool is_equal_form = false; // is the option in the form with equal sign, such as: option=argument + + while( *option_end != 0 && *option_end != '=' ) + { + option_end += 1; + } + + if( *option_end == '=' ) + { + is_equal_form = true; + convert_str(option_begin, option_end - option_begin, option); + convert_str(option_end + 1, argument); + } + else + { + convert_str(option_begin, option); + } + + argv_index += 1; + size_t args_len = how_many_arguments_required(option); + arguments.clear(); + + if( is_equal_form ) + { + if( args_len == 0 ) + { + if( !argument.empty() ) + { + // report an error + last_status = status_argument_provided; + last_error_option = option; + } + } + else + if( args_len == 1 ) + { + // argument can be empty in such a case: option= + // we treat it as if the argument would not be provided + if( !argument.empty() ) + { + arguments.push_back(argument); + args_len -= 1; + } } else { - table_value = &i->second; + // args_len is > 1 but when using option=argument form + // we can provide only one argument + last_status = status_argument_not_provided; + last_error_option = option; } + } - if( list.empty() ) - { - table_value->push_back(empty_value); - } - else - { - for(const auto & list_item : list) - table_value->push_back(list_item); - } + if( last_status == status_ok ) + { + parse_arguments(argc, argv, argv_index, args_len); + add_option_to_space(option, arguments); + } +} + + +void MainSpaceParser::parse_arguments(size_t argc, const char ** argv, size_t & argv_index, size_t args_len) +{ + for( ; args_len > 0 && argv_index < argc ; --args_len, ++argv_index) + { + convert_str(argv[argv_index], argument); + arguments.push_back(argument); + } + + if( args_len > 0 ) + { + last_status = status_argument_not_provided; + last_error_option = option; } } -size_t MainSpaceParser::RequireOption(const std::wstring & arg) +void MainSpaceParser::parse_non_option_arguments(size_t argc, const char ** argv, size_t & argv_index) +{ + Space * table_with_args = new Space(); + table_with_args->set_empty_table(); + + for( ; argv_index < argc ; ++argv_index) + { + convert_str(argv[argv_index], argument); + table_with_args->add(argument); + } + + space->add(non_option_arguments_name, table_with_args); +} + + +void MainSpaceParser::add_option_to_space(const std::wstring & option, const std::vector & arguments) +{ + Space * option_table = space->get_object_field(option); + + if( !option_table ) + { + option_table = &space->add_empty_space(option); + } + + if( !option_table->is_table()) + { + option_table->set_empty_table(); + } + + Space * arguments_table = new Space(); + arguments_table->set_empty_table(); + + for(const std::wstring & arg : arguments) + { + Space & space_arg = arguments_table->add_empty_space(); + convert_str(arg, space_arg); + } + + option_table->add(arguments_table); +} + + + +size_t MainSpaceParser::how_many_arguments_required(const std::wstring & arg) { size_t res = 0; - if( options_space ) + if( arguments_required_space && arguments_required_space->is_object() ) { - std::wstring * val = options_space->GetFirstValue(arg); + long res_long = arguments_required_space->to_llong(arg, 0); - if( val ) - { - /* - * IMPLEMENT ME - * add a converter to convert/inttostr.h - * - */ + if( res_long < 0 ) + res_long = 0; - long res_long = wcstol(val->c_str(), 0, 10); - - if( res_long < 0 ) - res_long = 0; - - res = (size_t)res_long; - - //std::wcout << L"argument " << arg << L" needs " << res << L" options" << std::endl; - } + res = (size_t)res_long; + // argument 'arg' needs 'res' options } return res; } -#endif } // namespace diff --git a/src/mainspaceparser/mainspaceparser.h b/src/mainspaceparser/mainspaceparser.h index bddc4bf..a7d9215 100644 --- a/src/mainspaceparser/mainspaceparser.h +++ b/src/mainspaceparser/mainspaceparser.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2016, Tomasz Sowa + * Copyright (c) 2016-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,13 +46,12 @@ namespace PT { -#ifdef nonexisting_value - /* - a very little parser for main(int argc, char ** argv) parameters - look in sample/sample.cpp how to use the parser -*/ + * a very little parser for parsing main(int argc, char ** argv) parameters + * + * + */ class MainSpaceParser { public: @@ -60,42 +59,102 @@ public: MainSpaceParser(); ~MainSpaceParser(); + + /* + * status_ok - all argument have been parsed correctly + * + * status_argument_provided - an argument have been provided but was not requested + * this can be in situation when using long form with equal sign, such as: --option=argument + * and in 'options' space the option either was not set or have zero requested arguments + * + * status_argument_not_provided - an argument or arguments are required but were not provided + * this can be returned in two situations: + * 1. when using long form with equal sign, such as: --option=argument and in 'options' space + * you have requested more than one argument + * 2. when reading arguments and the input strings ended + * + */ enum Status { status_ok = 0, - status_space_not_assigned = 1, - status_syntax_error = 2, - status_reading_eof = 3 /* CHANGE ME give a better name */ + status_argument_provided = 1, + status_argument_not_provided = 2, }; - void SetSpace(Space & space); - Status Parse(int argc, const char ** argv); - void UTF8(bool utf8); + /* + * the name of a field in the output Struct space for non-option arguments (those after two hypens --) + * default: L"args" + * they will be set as a table of strings/wstrings + * + */ + void set_non_options_arguments_name(const wchar_t * name); + void set_non_options_arguments_name(const std::wstring & name); + + + /* + * parse parameters + * argc argv have the same meaning as in the main(int argc, const char ** argv) method + * the first argument from argv is usualy the name of the program and is skip by this parser + * + * return value: look at the description of the Status enum + * + */ + Status parse(int argc, const char ** argv, Space & out_space); + Status parse(int argc, const char ** argv, Space & out_space, const Space & options); + + + /* + * whether or not options arguments should be converted from utf8 char* strings to wide strings (std::wstring) + * default true + * + * if true all arguments in Space struct will be saved as std::wstring + * if false all arguments will be std::string (they are read as they are without checking + * whether correct utf8 characters are encountered) + * + * arguments are always held as std::wstring (in such a case is defined ObjectType in Space struct) + * when using use_utf8(false) characters will not be treated as an utf8 string but just all 8bit char bytes + * will be copied to std::wstring + * + */ + void use_utf8(bool utf8); + + + /* + * return the last option name which was incorrectly parsed + * or an empty string if status was equal to status_ok + */ + std::wstring & get_wrong_option(); - std::wstring & GetErrorToken(); private: Space * space; - Space * options_space; - std::wstring wide_arg, temp_arg, temp_val; - std::vector temp_list_val; - bool use_utf8; + const Space * arguments_required_space; + std::wstring non_option_arguments_name; + std::wstring options, option, argument; + std::vector arguments; + bool should_use_utf8; Status last_status; - std::wstring last_error_token; + std::wstring last_error_option; - void ConvertStr(const char * src, std::wstring & dst); - void Parse(size_t argc, const char ** argv, size_t & argv_index); - void ParseSingleArgument(size_t argc, const char ** argv, size_t & argv_index); - void ParseMultiArgument(size_t argc, const char ** argv, size_t & argv_index); - size_t RequireOption(const std::wstring & arg); - void AddValueToItem(const std::wstring & name, const std::wstring & empty_value, const std::vector & list); + void convert_str(const char * src, std::wstring & dst); + void convert_str(const char * src, size_t len, std::wstring & dst); + void convert_str(const std::wstring & src, Space & space); + + Status parse(int argc, const char ** argv); + void parse(size_t argc, const char ** argv, size_t & argv_index); + void parse_short_option(size_t argc, const char ** argv, size_t & argv_index); + void parse_long_option(size_t argc, const char ** argv, size_t & argv_index); + void parse_arguments(size_t argc, const char ** argv, size_t & argv_index, size_t args_len); + void parse_non_option_arguments(size_t argc, const char ** argv, size_t & argv_index); + size_t how_many_arguments_required(const std::wstring & arg); + void add_option_to_space(const std::wstring & option, const std::vector & arguments); }; -#endif + } // namespace From da6a36a205d6f45b180d3e79b2567119714c336b Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 17 May 2021 03:19:47 +0200 Subject: [PATCH 46/67] start creating tests for MainSpaceParser --- tests/main.cpp | 3 +- tests/mainargsparser.cpp | 143 +++++++++++++++++++++++++++++++++++++++ tests/mainargsparser.h | 62 +++++++++++++++++ 3 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 tests/mainargsparser.cpp create mode 100644 tests/mainargsparser.h diff --git a/tests/main.cpp b/tests/main.cpp index 3d5cc58..f0db839 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -36,6 +36,7 @@ */ #include "convert.h" +#include "mainargsparser.h" #include @@ -50,7 +51,7 @@ const char * test_msg = nullptr; int main() { pt::pt_convert_tests::make_tests(); - + pt::pt_mainargsparser_tests::make_tests(); if( pt::was_error ) { diff --git a/tests/mainargsparser.cpp b/tests/mainargsparser.cpp new file mode 100644 index 0000000..2876422 --- /dev/null +++ b/tests/mainargsparser.cpp @@ -0,0 +1,143 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "mainargsparser.h" +#include "test.h" +#include "mainspaceparser/mainspaceparser.h" +#include "utf8/utf8.h" + + +namespace pt +{ + +// remove me in the future (when PT will be changed to pt) +using namespace PT; + + +namespace pt_mainargsparser_tests +{ + +void test_text1() +{ + reset_test_counter("mainargsparser"); + + MainSpaceParser parser; + Space space; + + const char * argv[] = { + "program_name", + "-a", + "-", + "-b", + "-c", + "-d", + "param for d", + "-b", + "--long", + "--foo", + "foo-one", + "foo-two", + "--long-param", + "--bar", + "bar1", + "bar2", + "bar3", + "-x", + "--piggy2=swinka2", + "--swinka3", + "--bar", + "xbar1", + "xbar2", + "xbar3", + }; + + + + + MainSpaceParser::Status status; + + + Space params; + params.add(L"d", 1); + params.add(L"foo", 2); + params.add(L"bar", 3); + params.add(L"piggy", 1); + params.add(L"piggy2", 1); + + size_t len = sizeof(argv) / sizeof(const char *); + + status = parser.parse(len, argv, space, params); + + + if( status != MainSpaceParser::status_ok ) + { + std::wstring & err = parser.get_wrong_option(); + std::string err_str; + WideToUTF8(err, err_str); + std::cout << "blad: " << (int)status << ": " << err_str << std::endl; + } + + test(status, MainSpaceParser::status_ok); + std::cout << space.serialize_to_json_str() << std::endl; + +} + + + + + + + + + + +void make_tests() +{ + test_text1(); +// test_text2(); +// test_text3(); +// test_text4(); +// test_text5(); +} + + +} + + +} + diff --git a/tests/mainargsparser.h b/tests/mainargsparser.h new file mode 100644 index 0000000..c2b20a0 --- /dev/null +++ b/tests/mainargsparser.h @@ -0,0 +1,62 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_tests_mainargsparser +#define headerfile_picotools_tests_mainargsparser + + +namespace pt +{ + +namespace pt_mainargsparser_tests +{ + + + + + +void make_tests(); + + + + + +} + +} + +#endif From fe82f63efb08462b25d6ae21a7dbcac739bd186f Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 17 May 2021 03:20:51 +0200 Subject: [PATCH 47/67] changed the way of building in Makefiles --- Makefile | 10 +++++++++- tests/Makefile | 15 +++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 70cc850..ff5b96b 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ export CXXFLAGS export AR -all: src tests +all: src src: FORCE @@ -13,9 +13,15 @@ src: FORCE tests: FORCE + $(MAKE) -C src $(MAKE) -C tests +tests-gcc10: FORCE + env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src + env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests + + clean: FORCE $(MAKE) -C src clean $(MAKE) -C tests clean @@ -26,5 +32,7 @@ depend: FORCE $(MAKE) -C tests depend + + FORCE: diff --git a/tests/Makefile b/tests/Makefile index bd4e83f..6d6de49 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -11,27 +11,23 @@ CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../src -I/usr/local/include endif - progname = tests +pikotoolslibfile = ../src/pikotools.a -all: $(progname) pikotools +all: $(progname) -$(progname): $(objfiles) pikotools - $(CXX) $(CXXFLAGS) -o $(progname) $(objfiles) ../src/pikotools.a +$(progname): $(objfiles) FORCE + $(CXX) $(CXXFLAGS) -o $(progname) $(objfiles) $(pikotoolslibfile) %.o: %.cpp $(CXX) -c $(CXXFLAGS) -o $@ $< -pikotools: FORCE - $(MAKE) -C ../src -FORCE: - clean: rm -f $(objfiles) @@ -42,5 +38,8 @@ depend: makedepend -Y. -I../src -f- $(sourcefiles) > Makefile.dep +FORCE: + + -include Makefile.dep From 91300bb245e913918125452864c5a7b5e536baa7 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 17 May 2021 03:21:00 +0200 Subject: [PATCH 48/67] make depend --- tests/Makefile.dep | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/Makefile.dep b/tests/Makefile.dep index d69f60e..a6f9e9c 100644 --- a/tests/Makefile.dep +++ b/tests/Makefile.dep @@ -1,6 +1,6 @@ # DO NOT DELETE -./main.o: convert.h +./main.o: convert.h mainargsparser.h ./convert.o: convert.h test.h ../src/convert/convert.h ./convert.o: ../src/convert/inttostr.h ../src/convert/patternreplacer.h ./convert.o: ../src/textstream/textstream.h ../src/space/space.h @@ -9,3 +9,10 @@ ./convert.o: ../src/textstream/types.h ../src/convert/strtoint.h ./convert.o: ../src/convert/text.h ../src/convert/misc.h ./test.o: test.h +./mainargsparser.o: mainargsparser.h test.h +./mainargsparser.o: ../src/mainspaceparser/mainspaceparser.h +./mainargsparser.o: ../src/space/space.h ../src/textstream/types.h +./mainargsparser.o: ../src/convert/inttostr.h ../src/utf8/utf8.h +./mainargsparser.o: ../src/textstream/textstream.h ../src/date/date.h +./mainargsparser.o: ../src/membuffer/membuffer.h ../src/textstream/types.h +./mainargsparser.o: ../src/utf8/utf8_templates.h ../src/utf8/utf8_private.h From a5c88334520abfd24c8b3d31ab2c3096783f2c69 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 18 May 2021 22:57:26 +0200 Subject: [PATCH 49/67] added tests for MainSpaceParser --- src/mainspaceparser/mainspaceparser.cpp | 5 +- src/mainspaceparser/mainspaceparser.h | 2 +- tests/main.cpp | 3 +- tests/mainargsparser.cpp | 310 +++++++++++++++++++----- 4 files changed, 257 insertions(+), 63 deletions(-) diff --git a/src/mainspaceparser/mainspaceparser.cpp b/src/mainspaceparser/mainspaceparser.cpp index cfd2f79..7691a1f 100644 --- a/src/mainspaceparser/mainspaceparser.cpp +++ b/src/mainspaceparser/mainspaceparser.cpp @@ -96,10 +96,10 @@ MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Spa } -MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Space & out_space, const Space & options) +MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Space & out_space, const Space & arguments) { space = &out_space; - arguments_required_space = &options;; + arguments_required_space = &arguments;; return parse(argc, argv); } @@ -109,6 +109,7 @@ MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv) { last_status = status_ok; last_error_option.clear(); + space->set_empty_object(); for(size_t i=1 ; i < (size_t)argc && last_status == status_ok ; ) { diff --git a/src/mainspaceparser/mainspaceparser.h b/src/mainspaceparser/mainspaceparser.h index a7d9215..9c817d3 100644 --- a/src/mainspaceparser/mainspaceparser.h +++ b/src/mainspaceparser/mainspaceparser.h @@ -101,7 +101,7 @@ public: * */ Status parse(int argc, const char ** argv, Space & out_space); - Status parse(int argc, const char ** argv, Space & out_space, const Space & options); + Status parse(int argc, const char ** argv, Space & out_space, const Space & arguments); /* diff --git a/tests/main.cpp b/tests/main.cpp index f0db839..6ef5b07 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -40,6 +40,7 @@ #include + namespace pt { bool was_error = false; @@ -48,7 +49,7 @@ const char * test_msg = nullptr; } -int main() +int main(int argc, const char ** argv) { pt::pt_convert_tests::make_tests(); pt::pt_mainargsparser_tests::make_tests(); diff --git a/tests/mainargsparser.cpp b/tests/mainargsparser.cpp index 2876422..6763364 100644 --- a/tests/mainargsparser.cpp +++ b/tests/mainargsparser.cpp @@ -40,7 +40,7 @@ #include "test.h" #include "mainspaceparser/mainspaceparser.h" #include "utf8/utf8.h" - +#include "convert/convert.h" namespace pt { @@ -52,87 +52,279 @@ using namespace PT; namespace pt_mainargsparser_tests { -void test_text1() +struct MainSpaceParserOutputTest +{ + MainSpaceParser::Status status; + const char * option_err; + const char * json; +}; + + +void print_status(MainSpaceParser::Status status) +{ + if( status == MainSpaceParser::status_ok ) + { + std::cout << "MainSpaceParser::status_ok"; + } + else + if( status == MainSpaceParser::status_argument_not_provided ) + { + std::cout << "MainSpaceParser::status_argument_not_provided"; + } + else + if( status == MainSpaceParser::status_argument_provided ) + { + std::cout << "MainSpaceParser::status_argument_provided"; + } +} + + +bool has_space_in_str(const char * arg) +{ + while( *arg ) + { + if( PT::is_white((wchar_t)*arg) ) + return true; + + arg += 1; + } + + return false; +} + + +void print_args(int to_index, const char ** argv) +{ + for(int i=0 ; i <= to_index ; ++i) + { + bool has_space = has_space_in_str(argv[i]); + + if( has_space ) + std::cout << "\""; + + std::cout << argv[i]; + + if( has_space ) + std::cout << "\""; + + std::cout << " "; + } + + std::cout << std::endl; +} + + + +void test_mainargsparser(size_t len, const char ** argv, const Space & arguments_required, MainSpaceParserOutputTest * output) { reset_test_counter("mainargsparser"); + std::cout << "Testing MainArgsParser" << std::endl; MainSpaceParser parser; Space space; - const char * argv[] = { - "program_name", - "-a", - "-", - "-b", - "-c", - "-d", - "param for d", - "-b", - "--long", - "--foo", - "foo-one", - "foo-two", - "--long-param", - "--bar", - "bar1", - "bar2", - "bar3", - "-x", - "--piggy2=swinka2", - "--swinka3", - "--bar", - "xbar1", - "xbar2", - "xbar3", - }; + /* + * set to true when creating new tests (you can copy console output to the cpp file) + */ + bool prepare_tests = false; - - - - MainSpaceParser::Status status; - - - Space params; - params.add(L"d", 1); - params.add(L"foo", 2); - params.add(L"bar", 3); - params.add(L"piggy", 1); - params.add(L"piggy2", 1); - - size_t len = sizeof(argv) / sizeof(const char *); - - status = parser.parse(len, argv, space, params); - - - if( status != MainSpaceParser::status_ok ) + for(size_t i = 0 ; i < len ; ++i) { - std::wstring & err = parser.get_wrong_option(); + if( !prepare_tests ) + print_args(i, argv); + + MainSpaceParser::Status status = parser.parse(i + 1, argv, space, arguments_required); + + std::wstring & err_wstr = parser.get_wrong_option(); std::string err_str; - WideToUTF8(err, err_str); - std::cout << "blad: " << (int)status << ": " << err_str << std::endl; + WideToUTF8(err_wstr, err_str); + + std::string json; + space.serialize_to_json_to(json); + + std::cout << "{"; + print_status(status); + std::cout << ", " << "\"" << err_str << "\", " << "R\"json(" << json << ")json\"" << "}," << std::endl; + + if( !prepare_tests ) + { + test("status", status, output[i].status); + test("err_arg", err_str.c_str(), output[i].option_err); + test("json", json.c_str(), output[i].json); + } } - - test(status, MainSpaceParser::status_ok); - std::cout << space.serialize_to_json_str() << std::endl; - } +void test_mainargsparser1() +{ + const char * argv[] = { + "program_name", + "-a", + "-b", + "-c", + "-d", + "argument for d", + "-b", + "--long", + "--foo", + "foo-one", + "foo-two", + "--long-option", + "--bar", + "bar1", + "bar2", + "bar3", + "-x", + "--piggy2=option_for_piggy2", + "--piggy3", + "--bar", + "xbar1", + "xbar2", + "xbar3", + "--piggy2 another_option_for_piggy2", + "--", + "non-option-argument1", + "non-option-argument2", + "non-option-argument3", + }; + + MainSpaceParserOutputTest output[] = { + {MainSpaceParser::status_ok, "", R"json({})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[]],"c":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "d", R"json({"a":[[]],"b":[[]],"c":[[]],"d":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[]],"c":[[]],"d":[["argument for d"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"long":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "foo", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[[]],"long":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "foo", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one"]],"long":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":[],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1","non-option-argument2"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1","non-option-argument2","non-option-argument3"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + }; + + Space arguments_required; + arguments_required.add(L"d", 1); + arguments_required.add(L"foo", 2); + arguments_required.add(L"bar", 3); + arguments_required.add(L"piggy", 1); + arguments_required.add(L"piggy2", 1); + + size_t len = sizeof(argv) / sizeof(const char *); + test_mainargsparser(len, argv, arguments_required, output); +} +void test_mainargsparser2() +{ + const char * argv[] = { + "program_name", + "--long1", + "--long2=with-argument", + "--long3", + "-a", + "--=option-for-empty-argument", + "-b", + "arg b 1", + "arg b 2", + "-c", + "-f file-name with spaces", + "--xxx", + "arg 1", + "arg 2", + "arg 3", + "-", /* first non-option argument */ + "non-option-argument2", + "non-option-argument3", + "non-option-argument4", + }; + + MainSpaceParserOutputTest output[] = { + {MainSpaceParser::status_ok, "", R"json({})json"}, + {MainSpaceParser::status_ok, "", R"json({"long1":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"long1":[[]],"long2":[["with-argument"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"a":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "b", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "b", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[[]]})json"}, + {MainSpaceParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1"]]})json"}, + {MainSpaceParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2","non-option-argument3"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2","non-option-argument3","non-option-argument4"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + }; + + Space arguments_required; + arguments_required.add(L"long2", 1); + arguments_required.add(L"b", 2); + arguments_required.add(L"f", 1); + arguments_required.add(L"xxx", 3); + arguments_required.add(L"", 1); + + size_t len = sizeof(argv) / sizeof(const char *); + test_mainargsparser(len, argv, arguments_required, output); +} + + + +void test_mainargsparser3() +{ + const char * argv[] = { + "program_name", + "--long1", + "--long2=with-argument", + "--long3", + }; + + MainSpaceParserOutputTest output[] = { + {MainSpaceParser::status_ok, "", R"json({})json"}, + {MainSpaceParser::status_ok, "", R"json({"long1":[[]]})json"}, + {MainSpaceParser::status_argument_provided, "long2", R"json({"long1":[[]]})json"}, + {MainSpaceParser::status_argument_provided, "long2", R"json({"long1":[[]]})json"}, + }; + + Space arguments_required; + arguments_required.add(L"non-existing", 1); + + size_t len = sizeof(argv) / sizeof(const char *); + test_mainargsparser(len, argv, arguments_required, output); +} + void make_tests() { - test_text1(); -// test_text2(); -// test_text3(); -// test_text4(); -// test_text5(); + test_mainargsparser1(); + test_mainargsparser2(); + test_mainargsparser3(); } From 96e60c526f616925d237a57d127567a740afc838 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 18 May 2021 23:50:42 +0200 Subject: [PATCH 50/67] moved files: mainspaceparser/mainspaceparser.(h|cpp) -> mainoptions/mainoptionsparser.(h|cpp) --- .../mainspaceparser.cpp => mainoptions/mainoptionsparser.cpp} | 0 .../mainspaceparser.h => mainoptions/mainoptionsparser.h} | 0 tests/{mainargsparser.cpp => mainoptionsparser.cpp} | 0 tests/{mainargsparser.h => mainoptionsparser.h} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/{mainspaceparser/mainspaceparser.cpp => mainoptions/mainoptionsparser.cpp} (100%) rename src/{mainspaceparser/mainspaceparser.h => mainoptions/mainoptionsparser.h} (100%) rename tests/{mainargsparser.cpp => mainoptionsparser.cpp} (100%) rename tests/{mainargsparser.h => mainoptionsparser.h} (100%) diff --git a/src/mainspaceparser/mainspaceparser.cpp b/src/mainoptions/mainoptionsparser.cpp similarity index 100% rename from src/mainspaceparser/mainspaceparser.cpp rename to src/mainoptions/mainoptionsparser.cpp diff --git a/src/mainspaceparser/mainspaceparser.h b/src/mainoptions/mainoptionsparser.h similarity index 100% rename from src/mainspaceparser/mainspaceparser.h rename to src/mainoptions/mainoptionsparser.h diff --git a/tests/mainargsparser.cpp b/tests/mainoptionsparser.cpp similarity index 100% rename from tests/mainargsparser.cpp rename to tests/mainoptionsparser.cpp diff --git a/tests/mainargsparser.h b/tests/mainoptionsparser.h similarity index 100% rename from tests/mainargsparser.h rename to tests/mainoptionsparser.h From ad4e8078ae4ee871572f8b8993ce848680662c6f Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 18 May 2021 23:57:58 +0200 Subject: [PATCH 51/67] MainSpaceParser class has been renamed to MainOptionsParser --- src/mainoptions/mainoptionsparser.cpp | 40 +++---- src/mainoptions/mainoptionsparser.h | 10 +- tests/main.cpp | 4 +- tests/mainoptionsparser.cpp | 158 +++++++++++++------------- tests/mainoptionsparser.h | 6 +- 5 files changed, 109 insertions(+), 109 deletions(-) diff --git a/src/mainoptions/mainoptionsparser.cpp b/src/mainoptions/mainoptionsparser.cpp index 7691a1f..05044bd 100644 --- a/src/mainoptions/mainoptionsparser.cpp +++ b/src/mainoptions/mainoptionsparser.cpp @@ -36,7 +36,7 @@ */ -#include "mainspaceparser.h" +#include "mainoptionsparser.h" #include "utf8/utf8.h" #include @@ -47,7 +47,7 @@ namespace PT -MainSpaceParser::MainSpaceParser() +MainOptionsParser::MainOptionsParser() { space = 0; arguments_required_space = 0; @@ -58,36 +58,36 @@ MainSpaceParser::MainSpaceParser() -MainSpaceParser::~MainSpaceParser() +MainOptionsParser::~MainOptionsParser() { } -void MainSpaceParser::use_utf8(bool utf8) +void MainOptionsParser::use_utf8(bool utf8) { should_use_utf8 = utf8; } -void MainSpaceParser::set_non_options_arguments_name(const wchar_t * name) +void MainOptionsParser::set_non_options_arguments_name(const wchar_t * name) { non_option_arguments_name = name; } -void MainSpaceParser::set_non_options_arguments_name(const std::wstring & name) +void MainOptionsParser::set_non_options_arguments_name(const std::wstring & name) { non_option_arguments_name = name; } -std::wstring & MainSpaceParser::get_wrong_option() +std::wstring & MainOptionsParser::get_wrong_option() { return last_error_option; } -MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Space & out_space) +MainOptionsParser::Status MainOptionsParser::parse(int argc, const char ** argv, Space & out_space) { space = &out_space; arguments_required_space = nullptr; @@ -96,7 +96,7 @@ MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Spa } -MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Space & out_space, const Space & arguments) +MainOptionsParser::Status MainOptionsParser::parse(int argc, const char ** argv, Space & out_space, const Space & arguments) { space = &out_space; arguments_required_space = &arguments;; @@ -105,7 +105,7 @@ MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv, Spa } -MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv) +MainOptionsParser::Status MainOptionsParser::parse(int argc, const char ** argv) { last_status = status_ok; last_error_option.clear(); @@ -125,7 +125,7 @@ MainSpaceParser::Status MainSpaceParser::parse(int argc, const char ** argv) } -void MainSpaceParser::parse(size_t argc, const char ** argv, size_t & argv_index) +void MainOptionsParser::parse(size_t argc, const char ** argv, size_t & argv_index) { const char * pchar = argv[argv_index]; @@ -161,7 +161,7 @@ void MainSpaceParser::parse(size_t argc, const char ** argv, size_t & argv_index } -void MainSpaceParser::convert_str(const char * src, std::wstring & dst) +void MainOptionsParser::convert_str(const char * src, std::wstring & dst) { if( should_use_utf8 ) { @@ -177,7 +177,7 @@ void MainSpaceParser::convert_str(const char * src, std::wstring & dst) } -void MainSpaceParser::convert_str(const char * src, size_t len, std::wstring & dst) +void MainOptionsParser::convert_str(const char * src, size_t len, std::wstring & dst) { if( should_use_utf8 ) { @@ -193,7 +193,7 @@ void MainSpaceParser::convert_str(const char * src, size_t len, std::wstring & d } -void MainSpaceParser::convert_str(const std::wstring & src, Space & space) +void MainOptionsParser::convert_str(const std::wstring & src, Space & space) { if( should_use_utf8 ) { @@ -213,7 +213,7 @@ void MainSpaceParser::convert_str(const std::wstring & src, Space & space) } -void MainSpaceParser::parse_short_option(size_t argc, const char ** argv, size_t & argv_index) +void MainOptionsParser::parse_short_option(size_t argc, const char ** argv, size_t & argv_index) { convert_str(argv[argv_index] + 1, options); const wchar_t * options_pchar = options.c_str(); @@ -247,7 +247,7 @@ void MainSpaceParser::parse_short_option(size_t argc, const char ** argv, size_t } -void MainSpaceParser::parse_long_option(size_t argc, const char ** argv, size_t & argv_index) +void MainOptionsParser::parse_long_option(size_t argc, const char ** argv, size_t & argv_index) { const char * option_begin = argv[argv_index] + 2; // skip first two hyphens -- const char * option_end = option_begin; @@ -312,7 +312,7 @@ void MainSpaceParser::parse_long_option(size_t argc, const char ** argv, size_t } -void MainSpaceParser::parse_arguments(size_t argc, const char ** argv, size_t & argv_index, size_t args_len) +void MainOptionsParser::parse_arguments(size_t argc, const char ** argv, size_t & argv_index, size_t args_len) { for( ; args_len > 0 && argv_index < argc ; --args_len, ++argv_index) { @@ -329,7 +329,7 @@ void MainSpaceParser::parse_arguments(size_t argc, const char ** argv, size_t & -void MainSpaceParser::parse_non_option_arguments(size_t argc, const char ** argv, size_t & argv_index) +void MainOptionsParser::parse_non_option_arguments(size_t argc, const char ** argv, size_t & argv_index) { Space * table_with_args = new Space(); table_with_args->set_empty_table(); @@ -344,7 +344,7 @@ void MainSpaceParser::parse_non_option_arguments(size_t argc, const char ** argv } -void MainSpaceParser::add_option_to_space(const std::wstring & option, const std::vector & arguments) +void MainOptionsParser::add_option_to_space(const std::wstring & option, const std::vector & arguments) { Space * option_table = space->get_object_field(option); @@ -372,7 +372,7 @@ void MainSpaceParser::add_option_to_space(const std::wstring & option, const std -size_t MainSpaceParser::how_many_arguments_required(const std::wstring & arg) +size_t MainOptionsParser::how_many_arguments_required(const std::wstring & arg) { size_t res = 0; diff --git a/src/mainoptions/mainoptionsparser.h b/src/mainoptions/mainoptionsparser.h index 9c817d3..97d0147 100644 --- a/src/mainoptions/mainoptionsparser.h +++ b/src/mainoptions/mainoptionsparser.h @@ -35,8 +35,8 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef headerfile_picotools_mainspaceparser_mainparser -#define headerfile_picotools_mainspaceparser_mainparser +#ifndef headerfile_picotools_mainoptions_mainoptionsparser +#define headerfile_picotools_mainoptions_mainoptionsparser #include "space/space.h" #include @@ -52,12 +52,12 @@ namespace PT * * */ -class MainSpaceParser +class MainOptionsParser { public: - MainSpaceParser(); - ~MainSpaceParser(); + MainOptionsParser(); + ~MainOptionsParser(); /* diff --git a/tests/main.cpp b/tests/main.cpp index 6ef5b07..d539e48 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -36,7 +36,7 @@ */ #include "convert.h" -#include "mainargsparser.h" +#include "mainoptionsparser.h" #include @@ -52,7 +52,7 @@ const char * test_msg = nullptr; int main(int argc, const char ** argv) { pt::pt_convert_tests::make_tests(); - pt::pt_mainargsparser_tests::make_tests(); + pt::pt_mainoptions_tests::make_tests(); if( pt::was_error ) { diff --git a/tests/mainoptionsparser.cpp b/tests/mainoptionsparser.cpp index 6763364..646b9a7 100644 --- a/tests/mainoptionsparser.cpp +++ b/tests/mainoptionsparser.cpp @@ -36,9 +36,9 @@ */ #include -#include "mainargsparser.h" +#include "mainoptionsparser.h" #include "test.h" -#include "mainspaceparser/mainspaceparser.h" +#include "mainoptions/mainoptionsparser.h" #include "utf8/utf8.h" #include "convert/convert.h" @@ -49,32 +49,32 @@ namespace pt using namespace PT; -namespace pt_mainargsparser_tests +namespace pt_mainoptions_tests { -struct MainSpaceParserOutputTest +struct MainOptionsParserOutputTest { - MainSpaceParser::Status status; + MainOptionsParser::Status status; const char * option_err; const char * json; }; -void print_status(MainSpaceParser::Status status) +void print_status(MainOptionsParser::Status status) { - if( status == MainSpaceParser::status_ok ) + if( status == MainOptionsParser::status_ok ) { - std::cout << "MainSpaceParser::status_ok"; + std::cout << "MainOptionsParser::status_ok"; } else - if( status == MainSpaceParser::status_argument_not_provided ) + if( status == MainOptionsParser::status_argument_not_provided ) { - std::cout << "MainSpaceParser::status_argument_not_provided"; + std::cout << "MainOptionsParser::status_argument_not_provided"; } else - if( status == MainSpaceParser::status_argument_provided ) + if( status == MainOptionsParser::status_argument_provided ) { - std::cout << "MainSpaceParser::status_argument_provided"; + std::cout << "MainOptionsParser::status_argument_provided"; } } @@ -115,12 +115,12 @@ void print_args(int to_index, const char ** argv) -void test_mainargsparser(size_t len, const char ** argv, const Space & arguments_required, MainSpaceParserOutputTest * output) +void test_mainoptionsparser(size_t len, const char ** argv, const Space & arguments_required, MainOptionsParserOutputTest * output) { - reset_test_counter("mainargsparser"); + reset_test_counter("mainoptionsparser"); std::cout << "Testing MainArgsParser" << std::endl; - MainSpaceParser parser; + MainOptionsParser parser; Space space; /* @@ -133,7 +133,7 @@ void test_mainargsparser(size_t len, const char ** argv, const Space & arguments if( !prepare_tests ) print_args(i, argv); - MainSpaceParser::Status status = parser.parse(i + 1, argv, space, arguments_required); + MainOptionsParser::Status status = parser.parse(i + 1, argv, space, arguments_required); std::wstring & err_wstr = parser.get_wrong_option(); std::string err_str; @@ -158,7 +158,7 @@ void test_mainargsparser(size_t len, const char ** argv, const Space & arguments -void test_mainargsparser1() +void test_mainoptionsparser1() { const char * argv[] = { "program_name", @@ -191,35 +191,35 @@ void test_mainargsparser1() "non-option-argument3", }; - MainSpaceParserOutputTest output[] = { - {MainSpaceParser::status_ok, "", R"json({})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[]],"c":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "d", R"json({"a":[[]],"b":[[]],"c":[[]],"d":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[]],"c":[[]],"d":[["argument for d"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"long":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "foo", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[[]],"long":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "foo", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one"]],"long":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":[],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1","non-option-argument2"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1","non-option-argument2","non-option-argument3"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + MainOptionsParserOutputTest output[] = { + {MainOptionsParser::status_ok, "", R"json({})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[]],"c":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "d", R"json({"a":[[]],"b":[[]],"c":[[]],"d":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[]],"c":[[]],"d":[["argument for d"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"long":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "foo", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[[]],"long":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "foo", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one"]],"long":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],[]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "bar", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"args":[],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1","non-option-argument2"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"args":["non-option-argument1","non-option-argument2","non-option-argument3"],"b":[[],[]],"bar":[["bar1","bar2","bar3"],["xbar1","xbar2","xbar3"]],"c":[[]],"d":[["argument for d"]],"foo":[["foo-one","foo-two"]],"long":[[]],"long-option":[[]],"piggy2":[["option_for_piggy2"]],"piggy2 another_option_for_piggy2":[[]],"piggy3":[[]],"x":[[]]})json"}, }; Space arguments_required; @@ -230,12 +230,12 @@ void test_mainargsparser1() arguments_required.add(L"piggy2", 1); size_t len = sizeof(argv) / sizeof(const char *); - test_mainargsparser(len, argv, arguments_required, output); + test_mainoptionsparser(len, argv, arguments_required, output); } -void test_mainargsparser2() +void test_mainoptionsparser2() { const char * argv[] = { "program_name", @@ -259,26 +259,26 @@ void test_mainargsparser2() "non-option-argument4", }; - MainSpaceParserOutputTest output[] = { - {MainSpaceParser::status_ok, "", R"json({})json"}, - {MainSpaceParser::status_ok, "", R"json({"long1":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"long1":[[]],"long2":[["with-argument"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"a":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "b", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "b", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[[]]})json"}, - {MainSpaceParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1"]]})json"}, - {MainSpaceParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2","non-option-argument3"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, - {MainSpaceParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2","non-option-argument3","non-option-argument4"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + MainOptionsParserOutputTest output[] = { + {MainOptionsParser::status_ok, "", R"json({})json"}, + {MainOptionsParser::status_ok, "", R"json({"long1":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"long1":[[]],"long2":[["with-argument"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"a":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "b", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "b", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[[]]})json"}, + {MainOptionsParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1"]]})json"}, + {MainOptionsParser::status_argument_not_provided, "xxx", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2","non-option-argument3"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, + {MainOptionsParser::status_ok, "", R"json({"":[["option-for-empty-argument"]],"a":[[]],"args":["-","non-option-argument2","non-option-argument3","non-option-argument4"],"b":[["arg b 1","arg b 2"]],"c":[[]],"f":[[" file-name with spaces"]],"long1":[[]],"long2":[["with-argument"]],"long3":[[]],"xxx":[["arg 1","arg 2","arg 3"]]})json"}, }; Space arguments_required; @@ -289,12 +289,12 @@ void test_mainargsparser2() arguments_required.add(L"", 1); size_t len = sizeof(argv) / sizeof(const char *); - test_mainargsparser(len, argv, arguments_required, output); + test_mainoptionsparser(len, argv, arguments_required, output); } -void test_mainargsparser3() +void test_mainoptionsparser3() { const char * argv[] = { "program_name", @@ -303,18 +303,18 @@ void test_mainargsparser3() "--long3", }; - MainSpaceParserOutputTest output[] = { - {MainSpaceParser::status_ok, "", R"json({})json"}, - {MainSpaceParser::status_ok, "", R"json({"long1":[[]]})json"}, - {MainSpaceParser::status_argument_provided, "long2", R"json({"long1":[[]]})json"}, - {MainSpaceParser::status_argument_provided, "long2", R"json({"long1":[[]]})json"}, + MainOptionsParserOutputTest output[] = { + {MainOptionsParser::status_ok, "", R"json({})json"}, + {MainOptionsParser::status_ok, "", R"json({"long1":[[]]})json"}, + {MainOptionsParser::status_argument_provided, "long2", R"json({"long1":[[]]})json"}, + {MainOptionsParser::status_argument_provided, "long2", R"json({"long1":[[]]})json"}, }; Space arguments_required; arguments_required.add(L"non-existing", 1); size_t len = sizeof(argv) / sizeof(const char *); - test_mainargsparser(len, argv, arguments_required, output); + test_mainoptionsparser(len, argv, arguments_required, output); } @@ -322,9 +322,9 @@ void test_mainargsparser3() void make_tests() { - test_mainargsparser1(); - test_mainargsparser2(); - test_mainargsparser3(); + test_mainoptionsparser1(); + test_mainoptionsparser2(); + test_mainoptionsparser3(); } diff --git a/tests/mainoptionsparser.h b/tests/mainoptionsparser.h index c2b20a0..45c0d0c 100644 --- a/tests/mainoptionsparser.h +++ b/tests/mainoptionsparser.h @@ -35,14 +35,14 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef headerfile_picotools_tests_mainargsparser -#define headerfile_picotools_tests_mainargsparser +#ifndef headerfile_picotools_tests_mainoptionsparser +#define headerfile_picotools_tests_mainoptionsparser namespace pt { -namespace pt_mainargsparser_tests +namespace pt_mainoptions_tests { From db93586c0edfdb120d29ecc8598f2b49ae5151b1 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 18 May 2021 23:58:17 +0200 Subject: [PATCH 52/67] make depend --- src/Makefile.dep | 13 ++++++------- tests/Makefile.dep | 21 +++++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Makefile.dep b/src/Makefile.dep index 26b3fcd..e37f93c 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -12,13 +12,6 @@ ./log/log.o: textstream/types.h convert/inttostr.h date/date.h ./log/log.o: membuffer/membuffer.h textstream/types.h ./log/filelog.h ./log/log.o: utf8/utf8.h utf8/utf8_templates.h utf8/utf8_private.h -./mainspaceparser/mainspaceparser.o: ./mainspaceparser/mainspaceparser.h -./mainspaceparser/mainspaceparser.o: space/space.h textstream/types.h -./mainspaceparser/mainspaceparser.o: convert/inttostr.h utf8/utf8.h -./mainspaceparser/mainspaceparser.o: textstream/textstream.h date/date.h -./mainspaceparser/mainspaceparser.o: membuffer/membuffer.h textstream/types.h -./mainspaceparser/mainspaceparser.o: utf8/utf8_templates.h -./mainspaceparser/mainspaceparser.o: utf8/utf8_private.h ./space/space.o: ./space/space.h textstream/types.h convert/inttostr.h ./space/space.o: utf8/utf8.h textstream/textstream.h space/space.h ./space/space.o: date/date.h membuffer/membuffer.h textstream/types.h @@ -38,3 +31,9 @@ ./utf8/utf8_private.o: utf8/utf8_private.h textstream/textstream.h ./utf8/utf8_private.o: space/space.h textstream/types.h convert/inttostr.h ./utf8/utf8_private.o: date/date.h membuffer/membuffer.h textstream/types.h +./mainoptions/mainoptionsparser.o: ./mainoptions/mainoptionsparser.h +./mainoptions/mainoptionsparser.o: space/space.h textstream/types.h +./mainoptions/mainoptionsparser.o: convert/inttostr.h utf8/utf8.h +./mainoptions/mainoptionsparser.o: textstream/textstream.h date/date.h +./mainoptions/mainoptionsparser.o: membuffer/membuffer.h textstream/types.h +./mainoptions/mainoptionsparser.o: utf8/utf8_templates.h utf8/utf8_private.h diff --git a/tests/Makefile.dep b/tests/Makefile.dep index a6f9e9c..827f046 100644 --- a/tests/Makefile.dep +++ b/tests/Makefile.dep @@ -1,6 +1,6 @@ # DO NOT DELETE -./main.o: convert.h mainargsparser.h +./main.o: convert.h mainoptionsparser.h ./convert.o: convert.h test.h ../src/convert/convert.h ./convert.o: ../src/convert/inttostr.h ../src/convert/patternreplacer.h ./convert.o: ../src/textstream/textstream.h ../src/space/space.h @@ -9,10 +9,15 @@ ./convert.o: ../src/textstream/types.h ../src/convert/strtoint.h ./convert.o: ../src/convert/text.h ../src/convert/misc.h ./test.o: test.h -./mainargsparser.o: mainargsparser.h test.h -./mainargsparser.o: ../src/mainspaceparser/mainspaceparser.h -./mainargsparser.o: ../src/space/space.h ../src/textstream/types.h -./mainargsparser.o: ../src/convert/inttostr.h ../src/utf8/utf8.h -./mainargsparser.o: ../src/textstream/textstream.h ../src/date/date.h -./mainargsparser.o: ../src/membuffer/membuffer.h ../src/textstream/types.h -./mainargsparser.o: ../src/utf8/utf8_templates.h ../src/utf8/utf8_private.h +./mainoptionsparser.o: mainoptionsparser.h test.h +./mainoptionsparser.o: ../src/mainoptions/mainoptionsparser.h +./mainoptionsparser.o: ../src/space/space.h ../src/textstream/types.h +./mainoptionsparser.o: ../src/convert/inttostr.h ../src/utf8/utf8.h +./mainoptionsparser.o: ../src/textstream/textstream.h ../src/date/date.h +./mainoptionsparser.o: ../src/membuffer/membuffer.h ../src/textstream/types.h +./mainoptionsparser.o: ../src/utf8/utf8_templates.h +./mainoptionsparser.o: ../src/utf8/utf8_private.h ../src/convert/convert.h +./mainoptionsparser.o: ../src/convert/inttostr.h +./mainoptionsparser.o: ../src/convert/patternreplacer.h +./mainoptionsparser.o: ../src/convert/strtoint.h ../src/convert/text.h +./mainoptionsparser.o: ../src/convert/misc.h From e0565813de68f303668590f0afb8fd5e207a324a Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 18 May 2021 23:58:46 +0200 Subject: [PATCH 53/67] removed *.a from .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e66d9ce..960f3fc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,6 @@ .project .settings/ *.o -*.a +src/pikotools.a tests/tests m From ae1d25d5f3f8c811800b4ad01f40d78beef26848 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 19 May 2021 03:23:18 +0200 Subject: [PATCH 54/67] removed old not used variable from Space --- src/space/spaceparser.cpp | 1 - src/space/spaceparser.h | 7 ------- 2 files changed, 8 deletions(-) diff --git a/src/space/spaceparser.cpp b/src/space/spaceparser.cpp index 3c8f9bd..7784649 100644 --- a/src/space/spaceparser.cpp +++ b/src/space/spaceparser.cpp @@ -298,7 +298,6 @@ void SpaceParser::ParseRootSpace() { line = 1; status = ok; - skipped = 0; if( !root_space ) { diff --git a/src/space/spaceparser.h b/src/space/spaceparser.h index a602554..d93fbf1 100644 --- a/src/space/spaceparser.h +++ b/src/space/spaceparser.h @@ -88,13 +88,6 @@ public: - /* - how many objects were skipped - used in parsing tables when create_table_as_space is false - */ - size_t skipped; - - /* main methods used to parse a JSON file file_name is the path to a file From 0ea5497094574d7e81f2223bd3d9abd25971b1d2 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 19 May 2021 03:26:46 +0200 Subject: [PATCH 55/67] added CSVParser - a csv parser --- Makefile | 2 + src/csv/csvparser.cpp | 416 ++++++++++++++++++++++++++++++++++++++++++ src/csv/csvparser.h | 162 ++++++++++++++++ tests/csvparser.cpp | 329 +++++++++++++++++++++++++++++++++ tests/csvparser.h | 56 ++++++ tests/main.cpp | 2 + 6 files changed, 967 insertions(+) create mode 100644 src/csv/csvparser.cpp create mode 100644 src/csv/csvparser.h create mode 100644 tests/csvparser.cpp create mode 100644 tests/csvparser.h diff --git a/Makefile b/Makefile index ff5b96b..c7aab54 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,8 @@ tests: FORCE tests-gcc10: FORCE env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests + #env CXX=clang++ CXXFLAGS="-fsanitize=address -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src + #env CXX=clang++ CXXFLAGS="-fsanitize=address -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests clean: FORCE diff --git a/src/csv/csvparser.cpp b/src/csv/csvparser.cpp new file mode 100644 index 0000000..a4800ca --- /dev/null +++ b/src/csv/csvparser.cpp @@ -0,0 +1,416 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "csvparser.h" +#include "utf8/utf8.h" + + + +namespace PT +{ + + + + +CSVParser::Status CSVParser::parse_file(const char * file_name, Space & out_space) +{ + reading_from_file = true; + space = &out_space; + + file.clear(); + file.open(file_name, std::ios_base::binary | std::ios_base::in); + + if( file ) + { + parse(); + file.close(); + } + else + { + status = cant_open_file; + } + + return status; +} + + + +CSVParser::Status CSVParser::parse_file(const std::string & file_name, Space & out_space) +{ + return parse_file(file_name.c_str(), out_space); +} + + + + +CSVParser::Status CSVParser::parse_file(const wchar_t * file_name, Space & out_space) +{ + std::string file_name_utf8; + + PT::WideToUTF8(file_name, file_name_utf8); + return parse_file(file_name_utf8.c_str(), out_space); +} + + + +CSVParser::Status CSVParser::parse_file(const std::wstring & file_name, Space & out_space) +{ + return parse_file(file_name.c_str(), out_space); +} + + + + + +CSVParser::Status CSVParser::parse(const char * str, Space & out_space) +{ + reading_from_file = false; + reading_from_wchar_string = false; + pchar_ascii = str; + pchar_unicode = 0; + space = &out_space; + + parse(); + + return status; +} + + + +CSVParser::Status CSVParser::parse(const std::string & str, Space & out_space) +{ + return parse(str.c_str(), out_space); +} + + +CSVParser::Status CSVParser::parse(const wchar_t * str, Space & out_space) +{ + reading_from_file = false; + reading_from_wchar_string = true; + pchar_unicode = str; + pchar_ascii = 0; + space = &out_space; + + parse(); + + return status; +} + + +CSVParser::Status CSVParser::parse(const std::wstring & str, Space & out_space) +{ + return parse(str.c_str(), out_space); +} + + + +void CSVParser::parse() +{ + line = 1; + status = ok; + + space->set_empty_table(); + read_char(); // put first character to lastc + + if( lastc == -1 ) + { + // an empty file/string, in such a case we return such a space struct (if would be serialized to json): [[]] + Space * row_space = new Space(); + row_space->set_empty_table(); + space->add(row_space); + } + + while( lastc != -1 ) + { + /* + * even if there is an error when parsing we continue to read the file/string + * + */ + + Space * row_space = new Space(); + row_space->set_empty_table(); + + parse_row(row_space); + space->add(row_space); + } +} + + +void CSVParser::parse_row(Space * row_space) +{ + bool continue_reading; + + do + { + continue_reading = read_value_to(row_space); + } + while(continue_reading); +} + + +bool CSVParser::read_value_to(Space * row_space) +{ + Space & space_value = row_space->add_empty_space(); + space_value.set_empty_wstring(); + + if( lastc == '"' ) + { + return read_quoted_value_to(space_value.value.value_wstring); + } + else + { + return read_non_quoted_value_to(space_value.value.value_wstring); + } +} + + +bool CSVParser::read_quoted_value_to(std::wstring & value) +{ + bool is_comma = false; + bool is_value_character = true; + + while( lastc != -1 && is_value_character ) + { + read_char(); + + if( lastc == '"' ) + { + read_char(); + + if( lastc == '"' ) + { + value += lastc; + } + else + { + is_value_character = false; + } + } + else + if( lastc != -1 ) + { + value += lastc; + } + } + + if( lastc == ',' ) + { + is_comma = true; + read_char(); // skip the comma character + } + else + if( lastc == 13 ) + { + read_char(); // skip CR character + + if( lastc == 10 ) + read_char(); + } + else + if( lastc == 10 ) + { + read_char(); // skip new line character + } + + return is_comma; +} + + +bool CSVParser::read_non_quoted_value_to(std::wstring & value) +{ + while( lastc != -1 && lastc != ',' && lastc != 10 ) + { + value += lastc; + read_char(); + } + + bool is_comma = (lastc == ','); + + if( is_comma ) + { + read_char(); // skip the comma character + } + else + { + bool is_new_line = (lastc == 10); + + // check CRLF sequence + if( is_new_line && !value.empty() && value.back() == 13 ) + { + value.erase(value.size() - 1, 1); + } + + if( is_new_line ) + { + read_char(); // skip the new line character + } + } + + return is_comma; +} + + + + +int CSVParser::read_utf8_char() +{ +int c; +bool correct; + + lastc = -1; + + do + { + PT::UTF8ToInt(file, c, correct); + + if( !file ) + return lastc; + } + while( !correct ); + + lastc = c; + + if( lastc == '\n' ) + ++line; + +return lastc; +} + + + +int CSVParser::read_ascii_char() +{ + lastc = file.get(); + + if( lastc == '\n' ) + ++line; + +return lastc; +} + + + + +int CSVParser::read_char_from_wchar_string() +{ + if( *pchar_unicode == 0 ) + lastc = -1; + else + lastc = *(pchar_unicode++); + + if( lastc == '\n' ) + ++line; + +return lastc; +} + + +int CSVParser::read_char_from_utf8_string() +{ +int c; +bool correct; + + lastc = -1; + + do + { + size_t len = PT::UTF8ToInt(pchar_ascii, c, correct); + pchar_ascii += len; + } + while( *pchar_ascii && !correct ); + + if( correct ) + lastc = c; + + if( lastc == '\n' ) + ++line; + +return lastc; +} + + +int CSVParser::read_char_from_ascii_string() +{ + if( *pchar_ascii == 0 ) + lastc = -1; + else + lastc = *(pchar_ascii++); + + if( lastc == '\n' ) + ++line; + +return lastc; +} + + +int CSVParser::read_char_no_escape() +{ + if( reading_from_file ) + { + if( input_as_utf8 ) + return read_utf8_char(); + else + return read_ascii_char(); + } + else + { + if( reading_from_wchar_string ) + { + return read_char_from_wchar_string(); + } + else + { + if( input_as_utf8 ) + return read_char_from_utf8_string(); + else + return read_char_from_ascii_string(); + } + } +} + + + + +int CSVParser::read_char() +{ + return read_char_no_escape(); +} + + +} + + diff --git a/src/csv/csvparser.h b/src/csv/csvparser.h new file mode 100644 index 0000000..bb01132 --- /dev/null +++ b/src/csv/csvparser.h @@ -0,0 +1,162 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_csv_csvparser +#define headerfile_picotools_csv_csvparser + +#include "space/space.h" +#include +#include + + +namespace PT +{ + +/* + * + * https://datatracker.ietf.org/doc/html/rfc4180 + * + */ +class CSVParser +{ +public: + + enum Status + { + ok, + cant_open_file, + }; + + + Status parse_file(const char * file_name, Space & out_space); + Status parse_file(const std::string & file_name, Space & out_space); + Status parse_file(const wchar_t * file_name, Space & out_space); + Status parse_file(const std::wstring & file_name, Space & out_space); + + Status parse(const char * str, Space & out_space); + Status parse(const std::string & str, Space & out_space); + Status parse(const wchar_t * str, Space & out_space); + Status parse(const std::wstring & str, Space & out_space); + + + +protected: + + + /* + the last status of parsing, set by Parse() methods + */ + Status status; + + + Space * space; + + /* + true if parse_file() method was called + false if parse() was called + */ + bool reading_from_file; + + /* + true if parse(wchar_t *) or parse(std::wstring&) was called + */ + bool reading_from_wchar_string; + + /* + pointers to the current character + if parse() is being used + */ + const char * pchar_ascii; + const wchar_t * pchar_unicode; + + + /* + last read char + or -1 if the end + */ + int lastc; + + + + /* + a number of a line in which there is a syntax_error + */ + int line; + + /* + current file + + may it would be better to make a pointer? + if we parse only a string then there is no sense to have such an object + */ + std::ifstream file; + + /* + input file is in UTF-8 + default: true + */ + bool input_as_utf8; + + + + + void parse(); + void parse_row(Space * row_space); + + bool read_value_to(Space * row_space); + bool read_quoted_value_to(std::wstring & value); + bool read_non_quoted_value_to(std::wstring & value); + + + + /* + * copied from SpaceParser + * may it would be better to have a class with those methods and inherit from it? + */ + int read_utf8_char(); + int read_ascii_char(); + int read_char_from_wchar_string(); + int read_char_from_utf8_string(); + int read_char_from_ascii_string(); + int read_char_no_escape(); + + int read_char(); +}; + +} + +#endif diff --git a/tests/csvparser.cpp b/tests/csvparser.cpp new file mode 100644 index 0000000..6fce734 --- /dev/null +++ b/tests/csvparser.cpp @@ -0,0 +1,329 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "csvparser.h" +#include "csv/csvparser.h" +#include "test.h" + + + +namespace pt +{ + +// remove me in the future (when PT will be changed to pt) +using namespace PT; + + +namespace pt_csvparser_tests +{ + + +void test_csvparser(const char * input_str, const char * expected_json) +{ + CSVParser csv_parser; + Space space; + std::string json; + + CSVParser::Status status = csv_parser.parse(input_str, space); + + space.serialize_to_json_to(json); + + std::cout << "csv parsed as: " << json << std::endl; + test(json.c_str(), expected_json); +} + + + +void test_csvparser1() +{ + const char * input_str = ""; + const char * expected_json = R"json([[]])json"; + + test_csvparser(input_str, expected_json); +} + + +void test_csvparser2() +{ + const char * input_str = ","; + const char * expected_json = R"json([["",""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser3() +{ + const char * input_str = "field1"; + const char * expected_json = R"json([["field1"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser4() +{ + const char * input_str = R"csvstring(field1,field2,field3)csvstring"; + const char * expected_json = R"json([["field1","field2","field3"]])json"; + + test_csvparser(input_str, expected_json); +} + + +void test_csvparser5() +{ + const char * input_str = "\n"; + const char * expected_json = R"json([[""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser6() +{ + const char * input_str = "\r\n"; + const char * expected_json = R"json([[""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser7() +{ + const char * input_str = "field1\r\n"; + const char * expected_json = R"json([["field1"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser8() +{ + const char * input_str = ",\r\n"; + const char * expected_json = R"json([["",""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser9() +{ + const char * input_str = "field1\r\nfield2"; + const char * expected_json = R"json([["field1"],["field2"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser10() +{ + const char * input_str = "field1,field2\r\nfield3,field4"; + const char * expected_json = R"json([["field1","field2"],["field3","field4"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser11() +{ + const char * input_str = "field1,field2\r\nfield3,field4\r\n"; + const char * expected_json = R"json([["field1","field2"],["field3","field4"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser12() +{ + const char * input_str = "field1,field2\nfield3,field4\n"; + const char * expected_json = R"json([["field1","field2"],["field3","field4"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser13() +{ + const char * input_str = R"csv("")csv"; + const char * expected_json = R"json([[""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser14() +{ + const char * input_str = "\"\"\n"; + const char * expected_json = R"json([[""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser15() +{ + const char * input_str = "\"\"\r\n"; + const char * expected_json = R"json([[""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser16() +{ + const char * input_str = "\"\",\r\n"; + const char * expected_json = R"json([["",""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser17() +{ + const char * input_str = "\"\",\n"; + const char * expected_json = R"json([["",""]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser18() +{ + const char * input_str = "\"field1\""; + const char * expected_json = R"json([["field1"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser19() +{ + const char * input_str = "\"field1, with comma\""; + const char * expected_json = R"json([["field1, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser20() +{ + const char * input_str = "\"field1, with comma\"\r\n"; + const char * expected_json = R"json([["field1, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser21() +{ + const char * input_str = "\"field1, with comma\"\n"; + const char * expected_json = R"json([["field1, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + + +void test_csvparser22() +{ + const char * input_str = "\"field1, with comma\",\"field2\""; + const char * expected_json = R"json([["field1, with comma","field2"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser23() +{ + const char * input_str = "\"field1, with comma\",\"field2\"\r\n\"field3\",\"field4, with comma\""; + const char * expected_json = R"json([["field1, with comma","field2"],["field3","field4, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser24() +{ + const char * input_str = "\"field1, with comma\",\"field2\"\r\n\"field3\",\"field4, with comma\"\r\n"; + const char * expected_json = R"json([["field1, with comma","field2"],["field3","field4, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser25() +{ + const char * input_str = "\"field1, with comma\",\"field2 with \"\" double quote\"\r\n\"field3\",\"field4, with comma\""; + const char * expected_json = R"json([["field1, with comma","field2 with \" double quote"],["field3","field4, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser26() +{ + const char * input_str = "\"field1, with comma\",\"field2 with \"\" double quote\"\n\"field3\",\"field4, with comma\"\n"; + const char * expected_json = R"json([["field1, with comma","field2 with \" double quote"],["field3","field4, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + +void test_csvparser27() +{ + const char * input_str = "\"field1, with comma\",\"field2 with \"\" double quote\"syntax error\n\"field3\",\"field4, with comma\"\n"; + const char * expected_json = R"json([["field1, with comma","field2 with \" double quote"],["syntax error"],["field3","field4, with comma"]])json"; + + test_csvparser(input_str, expected_json); +} + +void make_tests() +{ + reset_test_counter("CSVParser"); + test_csvparser1(); + test_csvparser2(); + test_csvparser3(); + test_csvparser4(); + test_csvparser5(); + test_csvparser6(); + test_csvparser7(); + test_csvparser8(); + test_csvparser9(); + test_csvparser10(); + test_csvparser11(); + test_csvparser12(); + test_csvparser13(); + test_csvparser14(); + test_csvparser15(); + test_csvparser16(); + test_csvparser17(); + test_csvparser18(); + test_csvparser19(); + test_csvparser20(); + test_csvparser21(); + test_csvparser22(); + test_csvparser23(); + test_csvparser24(); + test_csvparser25(); + test_csvparser26(); + test_csvparser27(); +} + + + + +} + +} + + diff --git a/tests/csvparser.h b/tests/csvparser.h new file mode 100644 index 0000000..69c2821 --- /dev/null +++ b/tests/csvparser.h @@ -0,0 +1,56 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_tests_csvparser +#define headerfile_picotools_tests_csvparser + + +namespace pt +{ + +namespace pt_csvparser_tests +{ + + +void make_tests(); + + +} + +} + +#endif diff --git a/tests/main.cpp b/tests/main.cpp index d539e48..7b53280 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -37,6 +37,7 @@ #include "convert.h" #include "mainoptionsparser.h" +#include "csvparser.h" #include @@ -53,6 +54,7 @@ int main(int argc, const char ** argv) { pt::pt_convert_tests::make_tests(); pt::pt_mainoptions_tests::make_tests(); + pt::pt_csvparser_tests::make_tests(); if( pt::was_error ) { From 430822bad8054761d50240fc99d9110257774656 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 19 May 2021 03:26:57 +0200 Subject: [PATCH 56/67] make depend --- src/Makefile.dep | 4 ++++ tests/Makefile.dep | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Makefile.dep b/src/Makefile.dep index e37f93c..a2410fd 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -31,6 +31,10 @@ ./utf8/utf8_private.o: utf8/utf8_private.h textstream/textstream.h ./utf8/utf8_private.o: space/space.h textstream/types.h convert/inttostr.h ./utf8/utf8_private.o: date/date.h membuffer/membuffer.h textstream/types.h +./csv/csvparser.o: ./csv/csvparser.h space/space.h textstream/types.h +./csv/csvparser.o: convert/inttostr.h utf8/utf8.h textstream/textstream.h +./csv/csvparser.o: date/date.h membuffer/membuffer.h textstream/types.h +./csv/csvparser.o: utf8/utf8_templates.h utf8/utf8_private.h ./mainoptions/mainoptionsparser.o: ./mainoptions/mainoptionsparser.h ./mainoptions/mainoptionsparser.o: space/space.h textstream/types.h ./mainoptions/mainoptionsparser.o: convert/inttostr.h utf8/utf8.h diff --git a/tests/Makefile.dep b/tests/Makefile.dep index 827f046..7af1bb8 100644 --- a/tests/Makefile.dep +++ b/tests/Makefile.dep @@ -1,6 +1,6 @@ # DO NOT DELETE -./main.o: convert.h mainoptionsparser.h +./main.o: convert.h mainoptionsparser.h csvparser.h ./convert.o: convert.h test.h ../src/convert/convert.h ./convert.o: ../src/convert/inttostr.h ../src/convert/patternreplacer.h ./convert.o: ../src/textstream/textstream.h ../src/space/space.h @@ -21,3 +21,5 @@ ./mainoptionsparser.o: ../src/convert/patternreplacer.h ./mainoptionsparser.o: ../src/convert/strtoint.h ../src/convert/text.h ./mainoptionsparser.o: ../src/convert/misc.h +./csvparser.o: csvparser.h ../src/csv/csvparser.h ../src/space/space.h +./csvparser.o: ../src/textstream/types.h ../src/convert/inttostr.h test.h From 604b47db3265107c8d827bc264ad407d547ab618 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 19 May 2021 22:24:53 +0200 Subject: [PATCH 57/67] added move semantics to Space class added methods: Space(Space && space); Space & operator=(Space && space); void set(const Space & space); void set(Space && space); Space & add(const Space & space); Space & add(Space && space); Space & add(const wchar_t * field, const Space & space); Space & add(const wchar_t * field, Space && space); Space & add(const std::wstring & field, const Space & space); Space & add(const std::wstring & field, Space && space); --- src/space/space.cpp | 166 ++++++++++++++++++++++++++++++++++++++++++-- src/space/space.h | 21 +++++- 2 files changed, 182 insertions(+), 5 deletions(-) diff --git a/src/space/space.cpp b/src/space/space.cpp index 531d7e5..d40d6b5 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -35,11 +35,9 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -//#include #include -#include +#include #include "space.h" -//#include "textstream/textstream.h" #include "utf8/utf8.h" #include "convert/convert.h" @@ -59,6 +57,13 @@ Space::Space(const Space & space) copy_from(space); } +Space::Space(Space && space) +{ + initialize(); + move_from(std::move(space)); +} + + Space & Space::operator=(const Space & space) { copy_from(space); @@ -66,6 +71,13 @@ Space & Space::operator=(const Space & space) } +Space & Space::operator=(Space && space) +{ + move_from(std::move(space)); + return *this; +} + + Space::~Space() { remove_value(); @@ -337,6 +349,10 @@ void Space::set(const std::wstring & str) value.value_wstring = str; } +void Space::set(const Space & space) +{ + copy_from(space); +} void Space::set(const Space * space) { @@ -350,6 +366,12 @@ void Space::set(const Space * space) } } +void Space::set(Space && space) +{ + move_from(std::move(space)); +} + + Space & Space::add(bool val) { @@ -426,11 +448,25 @@ Space & Space::add(const std::wstring & val) return add_generic(val); } +Space & Space::add(const Space & space) +{ + return add_generic(space); +} + Space & Space::add(const Space * space) { return add_generic(space); } +Space & Space::add(Space && space) +{ + initialize_value_table_if_needed(); + Space * new_space = new Space(std::move(space)); + value.value_table.push_back(new_space); + return *value.value_table.back(); +} + + Space & Space::add_empty_space() { return add_generic(static_cast(nullptr)); @@ -514,11 +550,26 @@ Space & Space::add(const wchar_t * field, const std::wstring & val) return add_generic(field, val); } +Space & Space::add(const wchar_t * field, const Space & space) +{ + return add_generic(field, space); +} + Space & Space::add(const wchar_t * field, const Space * space) { return add_generic(field, space); } +Space & Space::add(const wchar_t * field, Space && space) +{ + initialize_value_object_if_needed(); + + auto insert_res = value.value_object.insert(std::make_pair(field, nullptr)); + insert_res.first->second = new Space(std::move(space)); + + return *(insert_res.first->second); +} + Space & Space::add_empty_space(const wchar_t * field) { return add_generic(field, static_cast(nullptr)); @@ -602,11 +653,21 @@ Space & Space::add(const std::wstring & field, const std::wstring & val) return add_generic(field, val); } +Space & Space::add(const std::wstring & field, const Space & space) +{ + return add_generic(field, space); +} + Space & Space::add(const std::wstring & field, const Space * space) { return add_generic(field, space); } +Space & Space::add(const std::wstring & field, Space && space) +{ + return add(field.c_str(), std::move(space)); +} + Space & Space::add_empty_space(const std::wstring & field) { return add_generic(field, static_cast(nullptr)); @@ -2034,6 +2095,45 @@ void Space::copy_value_table(const Value & value_from) } +void Space::move_value_from(Space && space) +{ + switch(space.type) + { + case type_string: + initialize_value_string_if_needed(std::move(space.value.value_string)); + break; + + case type_wstring: + initialize_value_wstring_if_needed(std::move(space.value.value_wstring)); + break; + + case type_object: + initialize_value_object_if_needed(std::move(space.value.value_object)); + break; + + case type_table: + initialize_value_table_if_needed(std::move(space.value.value_table)); + break; + + default: + copy_value_from(space); + break; + } +} + + +void Space::move_from(Space && space) +{ + move_value_from(std::move(space)); + space.type = Type::type_null; + + std::swap(child_spaces, space.child_spaces); + std::swap(name, space.name); +} + + + + void Space::initialize() { type = type_null; @@ -2106,6 +2206,22 @@ void Space::initialize_value_string_if_needed() } +void Space::initialize_value_string_if_needed(std::string && str) +{ + if( type != type_string ) + { + remove_value(); + new (&value) std::string(std::move(str)); + type = type_string; + } + else + { + value.value_string = std::move(str); + } +} + + + void Space::initialize_value_wstring_if_needed() { if( type != type_wstring ) @@ -2117,6 +2233,20 @@ void Space::initialize_value_wstring_if_needed() } +void Space::initialize_value_wstring_if_needed(std::wstring && str) +{ + if( type != type_wstring ) + { + remove_value(); + new (&value) std::wstring(std::move(str)); + type = type_wstring; + } + else + { + value.value_wstring = std::move(str); + } +} + void Space::initialize_value_object_if_needed() { if( type != type_object ) @@ -2127,6 +2257,20 @@ void Space::initialize_value_object_if_needed() } } +void Space::initialize_value_object_if_needed(ObjectType && obj) +{ + if( type != type_object ) + { + remove_value(); + new (&value) ObjectType(std::move(obj)); + type = type_object; + } + else + { + value.value_object = std::move(obj); + } +} + void Space::initialize_value_table_if_needed() { @@ -2139,6 +2283,21 @@ void Space::initialize_value_table_if_needed() } +void Space::initialize_value_table_if_needed(TableType && tab) +{ + if( type != type_table ) + { + remove_value(); + new (&value) TableType(std::move(tab)); + type = type_table; + } + else + { + value.value_table = std::move(tab); + } +} + + void Space::initialize_child_spaces_if_needed() { if( child_spaces == nullptr ) @@ -2264,7 +2423,6 @@ void Space::remove_space_name() - } // namespace diff --git a/src/space/space.h b/src/space/space.h index b9de2c2..5ebc4e9 100644 --- a/src/space/space.h +++ b/src/space/space.h @@ -186,8 +186,9 @@ public: Space(); Space(const Space & space); + Space(Space && space); Space & operator=(const Space & space); - // add move cctor + Space & operator=(Space && space); ~Space(); Space(bool val); @@ -232,7 +233,9 @@ public: void set(const wchar_t * str); void set(const std::string & str); void set(const std::wstring & str); + void set(const Space & space); void set(const Space * space); + void set(Space && space); // add a value to the table, change to table if needed, return the reference to the new inserted item @@ -251,7 +254,9 @@ public: Space & add(const wchar_t * val); Space & add(const std::string & val); Space & add(const std::wstring & val); + Space & add(const Space & space); Space & add(const Space * space); + Space & add(Space && space); Space & add_empty_space(); // IMPROVEME rename me to something better @@ -272,7 +277,9 @@ public: Space & add(const wchar_t * field, const wchar_t * val); Space & add(const wchar_t * field, const std::string & val); Space & add(const wchar_t * field, const std::wstring & val); + Space & add(const wchar_t * field, const Space & space); Space & add(const wchar_t * field, const Space * space); + Space & add(const wchar_t * field, Space && space); Space & add_empty_space(const wchar_t * field); // IMPROVEME rename me to something better Space & add(const std::wstring & field, bool val); @@ -290,7 +297,9 @@ public: Space & add(const std::wstring & field, const wchar_t * val); Space & add(const std::wstring & field, const std::string & val); Space & add(const std::wstring & field, const std::wstring & val); + Space & add(const std::wstring & field, const Space & space); Space & add(const std::wstring & field, const Space * space); + Space & add(const std::wstring & field, Space && space); Space & add_empty_space(const std::wstring & field); // IMPROVEME rename me to something better @@ -1285,6 +1294,9 @@ protected: void copy_value_object(const Value & value_from); void copy_value_table(const Value & value_from); + void move_value_from(Space && space); + void move_from(Space && space); + void initialize(); void initialize_value_null_if_needed(); void initialize_value_bool_if_needed(); @@ -1292,9 +1304,13 @@ protected: void initialize_value_float_if_needed(); void initialize_value_double_if_needed(); void initialize_value_string_if_needed(); + void initialize_value_string_if_needed(std::string && str); void initialize_value_wstring_if_needed(); + void initialize_value_wstring_if_needed(std::wstring && str); void initialize_value_object_if_needed(); + void initialize_value_object_if_needed(ObjectType && obj); void initialize_value_table_if_needed(); + void initialize_value_table_if_needed(TableType && tab); void initialize_child_spaces_if_needed(); void initialize_space_name_if_needed(); @@ -1309,6 +1325,9 @@ protected: }; + + + } // namespace From f8d24de3865a2b41a34e69cf30b3e56e6b80cfda Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 19 May 2021 22:31:18 +0200 Subject: [PATCH 58/67] fixed memory leak in CSVParser::parse() - a Space struct was allocated but never freed --- Makefile | 26 ++++++++++++++++++++++---- src/csv/csvparser.cpp | 12 ++++++------ src/csv/csvparser.h | 4 ++-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index c7aab54..3439f7c 100644 --- a/Makefile +++ b/Makefile @@ -18,10 +18,28 @@ tests: FORCE tests-gcc10: FORCE - env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src - env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests - #env CXX=clang++ CXXFLAGS="-fsanitize=address -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src - #env CXX=clang++ CXXFLAGS="-fsanitize=address -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests + env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -fmax-errors=1 -I../src -I/usr/local/include" $(MAKE) -C src + env CXX=g++10 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc10/ -Wall -pedantic -O0 -g3 -std=c++20 -fmax-errors=1 -I../src -I/usr/local/include" $(MAKE) -C tests + + +tests-clang: FORCE + env CXX=clang++ CXXFLAGS="-Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src + env CXX=clang++ CXXFLAGS="-Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests + + +tests-clang-sa: FORCE + env CXX=clang++ CXXFLAGS="-fsanitize=address -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src + env CXX=clang++ CXXFLAGS="-fsanitize=address -Wall -pedantic -O0 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests + + +tests-clang-sm: FORCE + env CXX=clang++ CXXFLAGS="-fsanitize=memory -Wall -pedantic -O3 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src + env CXX=clang++ CXXFLAGS="-fsanitize=memory -Wall -pedantic -O3 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests + + +tests-clang-su: FORCE + env CXX=clang++ CXXFLAGS="-fsanitize=undefined -Wall -pedantic -O3 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C src + env CXX=clang++ CXXFLAGS="-fsanitize=undefined -Wall -pedantic -O3 -g3 -std=c++20 -I../src -I/usr/local/include" $(MAKE) -C tests clean: FORCE diff --git a/src/csv/csvparser.cpp b/src/csv/csvparser.cpp index a4800ca..437804b 100644 --- a/src/csv/csvparser.cpp +++ b/src/csv/csvparser.cpp @@ -161,16 +161,16 @@ void CSVParser::parse() * */ - Space * row_space = new Space(); - row_space->set_empty_table(); + Space row_space; + row_space.set_empty_table(); parse_row(row_space); - space->add(row_space); + space->add(std::move(row_space)); } } -void CSVParser::parse_row(Space * row_space) +void CSVParser::parse_row(Space & row_space) { bool continue_reading; @@ -182,9 +182,9 @@ void CSVParser::parse_row(Space * row_space) } -bool CSVParser::read_value_to(Space * row_space) +bool CSVParser::read_value_to(Space & row_space) { - Space & space_value = row_space->add_empty_space(); + Space & space_value = row_space.add_empty_space(); space_value.set_empty_wstring(); if( lastc == '"' ) diff --git a/src/csv/csvparser.h b/src/csv/csvparser.h index bb01132..7402896 100644 --- a/src/csv/csvparser.h +++ b/src/csv/csvparser.h @@ -135,9 +135,9 @@ protected: void parse(); - void parse_row(Space * row_space); + void parse_row(Space & row_space); - bool read_value_to(Space * row_space); + bool read_value_to(Space & row_space); bool read_quoted_value_to(std::wstring & value); bool read_non_quoted_value_to(std::wstring & value); From 6f50626ddad22fb9bdcb1f3cab215b69f336260e Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 19 May 2021 22:34:10 +0200 Subject: [PATCH 59/67] fixed another memory leak in CSVParser::parse() (similar like before) --- src/csv/csvparser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csv/csvparser.cpp b/src/csv/csvparser.cpp index 437804b..81fcf7e 100644 --- a/src/csv/csvparser.cpp +++ b/src/csv/csvparser.cpp @@ -149,9 +149,9 @@ void CSVParser::parse() if( lastc == -1 ) { // an empty file/string, in such a case we return such a space struct (if would be serialized to json): [[]] - Space * row_space = new Space(); - row_space->set_empty_table(); - space->add(row_space); + Space row_space; + row_space.set_empty_table(); + space->add(std::move(row_space)); } while( lastc != -1 ) From b574289054293607e4c66cedffe328232329ce71 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 20 May 2021 16:11:12 +0200 Subject: [PATCH 60/67] namespace PT renamed to pt --- src/convert/inttostr.cpp | 2 +- src/convert/inttostr.h | 2 +- src/convert/misc.cpp | 2 +- src/convert/misc.h | 2 +- src/convert/patternreplacer.h | 2 +- src/convert/strtoint.h | 2 +- src/convert/text.cpp | 2 +- src/convert/text.h | 2 +- src/convert/text_private.h | 4 +- src/csv/csvparser.cpp | 8 +- src/csv/csvparser.h | 2 +- src/date/date.cpp | 2 +- src/date/date.h | 2 +- src/log/filelog.cpp | 10 +- src/log/filelog.h | 4 +- src/log/log.cpp | 16 +- src/log/log.h | 16 +- src/mainoptions/mainoptionsparser.cpp | 6 +- src/mainoptions/mainoptionsparser.h | 2 +- src/membuffer/membuffer.h | 2 +- src/space/space.cpp | 22 +- src/space/space.h | 6 +- src/space/spaceparser.cpp | 10 +- src/space/spaceparser.h | 2 +- src/textstream/textstream.h | 10 +- src/textstream/types.h | 2 +- src/utf8/utf8.cpp | 2 +- src/utf8/utf8.h | 2 +- src/utf8/utf8_private.cpp | 4 +- src/utf8/utf8_private.h | 6 +- src/utf8/utf8_templates.h | 4 +- tests/convert.cpp | 1093 ++++++++++++------------- tests/convert.h | 4 - tests/csvparser.cpp | 5 +- tests/mainoptionsparser.cpp | 7 +- 35 files changed, 628 insertions(+), 641 deletions(-) diff --git a/src/convert/inttostr.cpp b/src/convert/inttostr.cpp index 948ce15..b9a8d6d 100644 --- a/src/convert/inttostr.cpp +++ b/src/convert/inttostr.cpp @@ -38,7 +38,7 @@ #include "inttostr.h" -namespace PT +namespace pt { std::string to_str(unsigned long long value, int base) diff --git a/src/convert/inttostr.h b/src/convert/inttostr.h index 27e2496..f134dc8 100644 --- a/src/convert/inttostr.h +++ b/src/convert/inttostr.h @@ -42,7 +42,7 @@ -namespace PT +namespace pt { diff --git a/src/convert/misc.cpp b/src/convert/misc.cpp index a6cf0d7..978cce7 100644 --- a/src/convert/misc.cpp +++ b/src/convert/misc.cpp @@ -38,7 +38,7 @@ #include "misc.h" -namespace PT +namespace pt { diff --git a/src/convert/misc.h b/src/convert/misc.h index 4f9ba87..7dbb128 100644 --- a/src/convert/misc.h +++ b/src/convert/misc.h @@ -42,7 +42,7 @@ #include "text.h" -namespace PT +namespace pt { void SetOverflow(bool * was_overflow, bool val); diff --git a/src/convert/patternreplacer.h b/src/convert/patternreplacer.h index 0d89a8f..65569f0 100644 --- a/src/convert/patternreplacer.h +++ b/src/convert/patternreplacer.h @@ -44,7 +44,7 @@ -namespace PT +namespace pt { template diff --git a/src/convert/strtoint.h b/src/convert/strtoint.h index 3324d3a..9d06f4b 100644 --- a/src/convert/strtoint.h +++ b/src/convert/strtoint.h @@ -43,7 +43,7 @@ #include "misc.h" -namespace PT +namespace pt { diff --git a/src/convert/text.cpp b/src/convert/text.cpp index c8d8fa0..8551ba0 100644 --- a/src/convert/text.cpp +++ b/src/convert/text.cpp @@ -40,7 +40,7 @@ #include "text_private.h" -namespace PT +namespace pt { // white_chars table should be sorted (a binary search algorithm is used to find a character) diff --git a/src/convert/text.h b/src/convert/text.h index d698047..d5dcdf2 100644 --- a/src/convert/text.h +++ b/src/convert/text.h @@ -41,7 +41,7 @@ #include -namespace PT +namespace pt { bool is_white(wchar_t c, bool check_additional_chars = true, bool treat_new_line_as_white = true); diff --git a/src/convert/text_private.h b/src/convert/text_private.h index 5957367..2b93ac4 100644 --- a/src/convert/text_private.h +++ b/src/convert/text_private.h @@ -42,7 +42,7 @@ #include "text.h" -namespace PT +namespace pt { namespace pt_private @@ -302,7 +302,7 @@ bool is_substr_nc_generic(const StringType1 * short_str, const StringType2 * lon } // namespace pt_private -} // namespace PT +} // namespace pt #endif diff --git a/src/csv/csvparser.cpp b/src/csv/csvparser.cpp index 81fcf7e..cd2f345 100644 --- a/src/csv/csvparser.cpp +++ b/src/csv/csvparser.cpp @@ -40,7 +40,7 @@ -namespace PT +namespace pt { @@ -81,7 +81,7 @@ CSVParser::Status CSVParser::parse_file(const wchar_t * file_name, Space & out_s { std::string file_name_utf8; - PT::WideToUTF8(file_name, file_name_utf8); + WideToUTF8(file_name, file_name_utf8); return parse_file(file_name_utf8.c_str(), out_space); } @@ -295,7 +295,7 @@ bool correct; do { - PT::UTF8ToInt(file, c, correct); + UTF8ToInt(file, c, correct); if( !file ) return lastc; @@ -348,7 +348,7 @@ bool correct; do { - size_t len = PT::UTF8ToInt(pchar_ascii, c, correct); + size_t len = UTF8ToInt(pchar_ascii, c, correct); pchar_ascii += len; } while( *pchar_ascii && !correct ); diff --git a/src/csv/csvparser.h b/src/csv/csvparser.h index 7402896..8370867 100644 --- a/src/csv/csvparser.h +++ b/src/csv/csvparser.h @@ -43,7 +43,7 @@ #include -namespace PT +namespace pt { /* diff --git a/src/date/date.cpp b/src/date/date.cpp index 1e79c39..6ba05d4 100644 --- a/src/date/date.cpp +++ b/src/date/date.cpp @@ -41,7 +41,7 @@ #include -namespace PT +namespace pt { diff --git a/src/date/date.h b/src/date/date.h index f17b7ab..59938c3 100644 --- a/src/date/date.h +++ b/src/date/date.h @@ -44,7 +44,7 @@ -namespace PT +namespace pt { diff --git a/src/log/filelog.cpp b/src/log/filelog.cpp index 82c1cb7..ff9b82c 100644 --- a/src/log/filelog.cpp +++ b/src/log/filelog.cpp @@ -39,7 +39,7 @@ -namespace PT +namespace pt { @@ -74,7 +74,7 @@ void FileLog::init(const std::wstring & log_file, bool log_stdout, int log_level this->log_stdout = log_stdout; this->log_level = log_level; this->save_each_line = save_each_line; - PT::WideToUTF8(log_file, this->log_file); + WideToUTF8(log_file, this->log_file); } @@ -100,7 +100,7 @@ void FileLog::open_file() } -void FileLog::save_log(PT::WTextStream * buffer) +void FileLog::save_log(WTextStream * buffer) { if( buffer->empty() ) return; @@ -111,7 +111,7 @@ void FileLog::save_log(PT::WTextStream * buffer) { if( log_stdout ) { - PT::WideStreamToUTF8(*buffer, std::cout); + WideStreamToUTF8(*buffer, std::cout); } if( !log_file.empty() ) @@ -126,7 +126,7 @@ void FileLog::save_log(PT::WTextStream * buffer) if( file ) { - PT::WideStreamToUTF8(*buffer, file); + WideStreamToUTF8(*buffer, file); file.flush(); } } diff --git a/src/log/filelog.h b/src/log/filelog.h index abf6555..07f8701 100644 --- a/src/log/filelog.h +++ b/src/log/filelog.h @@ -42,7 +42,7 @@ #include "textstream/textstream.h" -namespace PT +namespace pt { @@ -55,7 +55,7 @@ public: virtual ~FileLog(); virtual void init(const std::wstring & log_file, bool log_stdout, int log_level, bool save_each_line); - virtual void save_log(PT::WTextStream * buffer); + virtual void save_log(WTextStream * buffer); virtual int get_log_level(); virtual bool should_save_each_line(); diff --git a/src/log/log.cpp b/src/log/log.cpp index 757c9cb..34010ee 100644 --- a/src/log/log.cpp +++ b/src/log/log.cpp @@ -45,7 +45,7 @@ #include "morm.h" #endif -namespace PT +namespace pt { @@ -73,13 +73,13 @@ Log::~Log() } -void Log::SetLogBuffer(PT::WTextStream * buffer) +void Log::SetLogBuffer(WTextStream * buffer) { this->buffer = buffer; } -PT::WTextStream * Log::GetLogBuffer() +WTextStream * Log::GetLogBuffer() { return buffer; } @@ -136,7 +136,7 @@ Log & Log::operator<<(const char * s) { if( buffer && file_log && s && current_level <= file_log->get_log_level() ) { - PT::UTF8ToWide(s, *buffer, false); + UTF8ToWide(s, *buffer, false); } return *this; @@ -148,7 +148,7 @@ Log & Log::operator<<(const std::string & s) { if( buffer && file_log && current_level <= file_log->get_log_level() ) { - PT::UTF8ToWide(s, *buffer, false); + UTF8ToWide(s, *buffer, false); } return *this; @@ -160,7 +160,7 @@ Log & Log::operator<<(const std::string * s) { if( buffer && file_log && current_level <= file_log->get_log_level() ) { - PT::UTF8ToWide(*s, *buffer, false); + UTF8ToWide(*s, *buffer, false); } return *this; @@ -290,7 +290,7 @@ Log & Log::operator<<(double s) -Log & Log::operator<<(const PT::Space & s) +Log & Log::operator<<(const Space & s) { if( buffer && file_log && current_level <= file_log->get_log_level() ) { @@ -302,7 +302,7 @@ Log & Log::operator<<(const PT::Space & s) -Log & Log::operator<<(const PT::Date & date) +Log & Log::operator<<(const Date & date) { if( buffer && file_log && current_level <= file_log->get_log_level() ) { diff --git a/src/log/log.h b/src/log/log.h index 891fb6d..d5073ae 100644 --- a/src/log/log.h +++ b/src/log/log.h @@ -51,7 +51,7 @@ namespace morm } -namespace PT +namespace pt { @@ -93,8 +93,8 @@ public: Log(); virtual ~Log(); - virtual void SetLogBuffer(PT::WTextStream * buffer); - virtual PT::WTextStream * GetLogBuffer(); + virtual void SetLogBuffer(WTextStream * buffer); + virtual WTextStream * GetLogBuffer(); void SetFileLog(FileLog * file_log); FileLog * GetFileLog(); @@ -128,8 +128,8 @@ public: //virtual Log & operator<<(float s); // added virtual Log & operator<<(double s); - virtual Log & operator<<(const PT::Space & space); - virtual Log & operator<<(const PT::Date & date); + virtual Log & operator<<(const Space & space); + virtual Log & operator<<(const Date & date); #ifdef PT_HAS_MORM virtual Log & operator<<(morm::Model & model); @@ -145,7 +145,7 @@ public: template - Log & operator<<(const PT::TextStreamBase & buf); + Log & operator<<(const TextStreamBase & buf); @@ -157,7 +157,7 @@ public: protected: // buffer for the log - PT::WTextStream * buffer; + WTextStream * buffer; // file logger FileLog * file_log; @@ -205,7 +205,7 @@ Log & Log::log_string_generic(const StringType & value, size_t max_size) template -Log & Log::operator<<(const PT::TextStreamBase & buf) +Log & Log::operator<<(const TextStreamBase & buf) { if( buffer && file_log && current_level <= file_log->get_log_level() ) { diff --git a/src/mainoptions/mainoptionsparser.cpp b/src/mainoptions/mainoptionsparser.cpp index 05044bd..685674b 100644 --- a/src/mainoptions/mainoptionsparser.cpp +++ b/src/mainoptions/mainoptionsparser.cpp @@ -42,7 +42,7 @@ -namespace PT +namespace pt { @@ -165,7 +165,7 @@ void MainOptionsParser::convert_str(const char * src, std::wstring & dst) { if( should_use_utf8 ) { - PT::UTF8ToWide(src, dst); + UTF8ToWide(src, dst); } else { @@ -181,7 +181,7 @@ void MainOptionsParser::convert_str(const char * src, size_t len, std::wstring & { if( should_use_utf8 ) { - PT::UTF8ToWide(src, len, dst); + UTF8ToWide(src, len, dst); } else { diff --git a/src/mainoptions/mainoptionsparser.h b/src/mainoptions/mainoptionsparser.h index 97d0147..0930dc3 100644 --- a/src/mainoptions/mainoptionsparser.h +++ b/src/mainoptions/mainoptionsparser.h @@ -43,7 +43,7 @@ #include -namespace PT +namespace pt { diff --git a/src/membuffer/membuffer.h b/src/membuffer/membuffer.h index dea0493..8c14010 100644 --- a/src/membuffer/membuffer.h +++ b/src/membuffer/membuffer.h @@ -41,7 +41,7 @@ #include -namespace PT +namespace pt { /* diff --git a/src/space/space.cpp b/src/space/space.cpp index d40d6b5..f2b7b79 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -42,7 +42,7 @@ #include "convert/convert.h" -namespace PT +namespace pt { Space::Space() @@ -922,7 +922,7 @@ std::string Space::to_str() const if( type == type_wstring ) { - PT::TextStream stream; + TextStream stream; serialize_string_buffer(value.value_wstring.c_str(), stream, Escape::no_escape); stream.to_string(str); return str; @@ -942,7 +942,7 @@ std::wstring Space::to_wstr() const if( type == type_string ) { - PT::UTF8ToWide(value.value_string, str); + UTF8ToWide(value.value_string, str); return str; } @@ -1277,7 +1277,7 @@ std::wstring Space::serialize_to_space_wstr(bool pretty_print) const void Space::serialize_to_space_to(std::string & str, bool pretty_print) const { - PT::TextStream stream; + TextStream stream; serialize_to_space_stream(stream, pretty_print); stream.to_string(str); @@ -1286,7 +1286,7 @@ void Space::serialize_to_space_to(std::string & str, bool pretty_print) const void Space::serialize_to_space_to(std::wstring & str, bool pretty_print) const { - PT::WTextStream stream; + WTextStream stream; serialize_to_space_stream(stream, pretty_print); stream.to_string(str); @@ -1312,7 +1312,7 @@ std::wstring Space::serialize_to_json_wstr() const void Space::serialize_to_json_to(std::string & str) const { - PT::TextStream stream; + TextStream stream; serialize_to_json_stream(stream); stream.to_string(str); @@ -1321,7 +1321,7 @@ void Space::serialize_to_json_to(std::string & str) const void Space::serialize_to_json_to(std::wstring & str) const { - PT::WTextStream stream; + WTextStream stream; serialize_to_json_stream(stream); stream.to_string(str); @@ -1429,7 +1429,7 @@ bool Space::has_value(const char * val) const { for(size_t i=0 ; i < value.value_table.size() ; ++i) { - PT::Space * table_item = value.value_table[i]; + Space * table_item = value.value_table[i]; if( table_item->type == type_string ) { @@ -1459,7 +1459,7 @@ bool Space::has_value(const wchar_t * val) const { for(size_t i=0 ; i < value.value_table.size() ; ++i) { - PT::Space * table_item = value.value_table[i]; + Space * table_item = value.value_table[i]; if( table_item->type == type_wstring ) { @@ -1934,7 +1934,7 @@ void Space::remove_child_space(const wchar_t * name) { for(size_t i=0 ; isize() ; ) { - PT::Space * child = (*child_spaces)[i]; + Space * child = (*child_spaces)[i]; if( child->name && (*child->name) == name ) { @@ -1960,7 +1960,7 @@ void Space::remove_child_space(size_t index) { if( child_spaces && index < child_spaces->size() ) { - PT::Space * child = (*child_spaces)[index]; + Space * child = (*child_spaces)[index]; delete child; child = nullptr; diff --git a/src/space/space.h b/src/space/space.h index 5ebc4e9..0278803 100644 --- a/src/space/space.h +++ b/src/space/space.h @@ -50,7 +50,7 @@ -namespace PT +namespace pt { @@ -915,7 +915,7 @@ protected: wchar_t buffer[50]; size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); - PT::Toa(value.value_long, buffer, buffer_len); + Toa(value.value_long, buffer, buffer_len); serialize_string_buffer(buffer, str, Escape::escape_space); } @@ -1095,7 +1095,7 @@ protected: wchar_t buffer[50]; size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); - PT::Toa(value.value_long, buffer, buffer_len); + Toa(value.value_long, buffer, buffer_len); serialize_string_buffer(buffer, str, Escape::escape_json); } diff --git a/src/space/spaceparser.cpp b/src/space/spaceparser.cpp index 7784649..b36ef41 100644 --- a/src/space/spaceparser.cpp +++ b/src/space/spaceparser.cpp @@ -42,7 +42,7 @@ #include "convert/strtoint.h" -namespace PT +namespace pt { @@ -145,7 +145,7 @@ SpaceParser::Status SpaceParser::ParseJSONFile(const wchar_t * file_name) { std::string file_name_utf8; - PT::WideToUTF8(file_name, file_name_utf8); + WideToUTF8(file_name, file_name_utf8); return ParseJSONFile(file_name_utf8.c_str()); } @@ -195,7 +195,7 @@ SpaceParser::Status SpaceParser::ParseSpaceFile(const wchar_t * file_name) { std::string file_name_utf8; - PT::WideToUTF8(file_name, file_name_utf8); + WideToUTF8(file_name, file_name_utf8); return ParseSpaceFile(file_name_utf8.c_str()); } @@ -972,7 +972,7 @@ bool correct; do { - PT::UTF8ToInt(file, c, correct); + UTF8ToInt(file, c, correct); if( !file ) return lastc; @@ -1025,7 +1025,7 @@ bool correct; do { - size_t len = PT::UTF8ToInt(pchar_ascii, c, correct); + size_t len = UTF8ToInt(pchar_ascii, c, correct); pchar_ascii += len; } while( *pchar_ascii && !correct ); diff --git a/src/space/spaceparser.h b/src/space/spaceparser.h index d93fbf1..20c24f1 100644 --- a/src/space/spaceparser.h +++ b/src/space/spaceparser.h @@ -43,7 +43,7 @@ -namespace PT +namespace pt { diff --git a/src/textstream/textstream.h b/src/textstream/textstream.h index 9b49589..1ad96cc 100644 --- a/src/textstream/textstream.h +++ b/src/textstream/textstream.h @@ -49,7 +49,7 @@ // for snprintf #include -namespace PT +namespace pt { @@ -109,8 +109,8 @@ public: TextStreamBase & operator<<(unsigned long long); TextStreamBase & operator<<(double); TextStreamBase & operator<<(const void *); // printing a pointer - TextStreamBase & operator<<(const PT::Space & space); - TextStreamBase & operator<<(const PT::Date & date); + TextStreamBase & operator<<(const Space & space); + TextStreamBase & operator<<(const Date & date); // min width for integer output // if the output value has less digits then first zeroes are added @@ -469,7 +469,7 @@ wchar_t buf[100]; template TextStreamBase & -TextStreamBase::operator<<(const PT::Space & space) +TextStreamBase::operator<<(const Space & space) { space.serialize_to_space_stream(*this, true); @@ -480,7 +480,7 @@ return *this; template TextStreamBase & -TextStreamBase::operator<<(const PT::Date & date) +TextStreamBase::operator<<(const Date & date) { date.Serialize(*this); diff --git a/src/textstream/types.h b/src/textstream/types.h index d2fe229..dbb84a0 100644 --- a/src/textstream/types.h +++ b/src/textstream/types.h @@ -40,7 +40,7 @@ -namespace PT +namespace pt { diff --git a/src/utf8/utf8.cpp b/src/utf8/utf8.cpp index 6090e59..5ed9e19 100644 --- a/src/utf8/utf8.cpp +++ b/src/utf8/utf8.cpp @@ -40,7 +40,7 @@ -namespace PT +namespace pt { diff --git a/src/utf8/utf8.h b/src/utf8/utf8.h index 979dd9e..fecd2eb 100644 --- a/src/utf8/utf8.h +++ b/src/utf8/utf8.h @@ -42,7 +42,7 @@ #include "textstream/textstream.h" -namespace PT +namespace pt { /*! diff --git a/src/utf8/utf8_private.cpp b/src/utf8/utf8_private.cpp index 71248d0..1394ebb 100644 --- a/src/utf8/utf8_private.cpp +++ b/src/utf8/utf8_private.cpp @@ -38,7 +38,7 @@ #include "utf8_private.h" -namespace PT +namespace pt { namespace private_namespace @@ -277,7 +277,7 @@ return chars; } // namespace private_namespace -} // namespace PT +} // namespace pt diff --git a/src/utf8/utf8_private.h b/src/utf8/utf8_private.h index 909d834..9b0b7f3 100644 --- a/src/utf8/utf8_private.h +++ b/src/utf8/utf8_private.h @@ -41,7 +41,7 @@ #include "textstream/textstream.h" -namespace PT +namespace pt { bool UTF8_CheckRange(int c); @@ -138,7 +138,7 @@ bool correct, was_error = false; } else { - len = PT::UTF8ToInt(utf8, utf8_len, z, correct); // the len will be different from zero + len = pt::UTF8ToInt(utf8, utf8_len, z, correct); // the len will be different from zero } if( !correct ) @@ -215,6 +215,6 @@ void WideToUTF8Generic(TextStreamBase & } // namespace private_namespace -} // namespace PT +} // namespace pt #endif diff --git a/src/utf8/utf8_templates.h b/src/utf8/utf8_templates.h index 7acde96..20271a1 100644 --- a/src/utf8/utf8_templates.h +++ b/src/utf8/utf8_templates.h @@ -43,7 +43,7 @@ #include "utf8_private.h" -namespace PT +namespace pt { @@ -263,7 +263,7 @@ void WideStreamToUTF8(StreamTypeIn & buffer, StreamTypeOut & utf8, int mode) -} // namespace PT +} // namespace pt #endif diff --git a/tests/convert.cpp b/tests/convert.cpp index 7106d95..fbd4b3b 100644 --- a/tests/convert.cpp +++ b/tests/convert.cpp @@ -44,48 +44,45 @@ namespace pt { -// remove me in the future (when PT will be changed to pt) -using namespace PT; - - namespace pt_convert_tests { + void test_text1() { reset_test_counter("is_white"); - test(PT::is_white(0), false); - test(PT::is_white(1), false); - test(PT::is_white(9), true); - test(PT::is_white(10), true); - test(PT::is_white(30), false); - test(PT::is_white(32), true); - test(PT::is_white(40), false); - test(PT::is_white('a'), false); - test(PT::is_white(0xabcd), false); + test(pt::is_white(0), false); + test(pt::is_white(1), false); + test(pt::is_white(9), true); + test(pt::is_white(10), true); + test(pt::is_white(30), false); + test(pt::is_white(32), true); + test(pt::is_white(40), false); + test(pt::is_white('a'), false); + test(pt::is_white(0xabcd), false); - test(PT::is_white(5, false, false), false); - test(PT::is_white(9, false, false), true); - test(PT::is_white(10, false, false), false); - test(PT::is_white(31, false, false), false); - test(PT::is_white(32, false, false), true); - test(PT::is_white('z', false, false), false); - test(PT::is_white(0xbbcc, false, false), false); - test(PT::is_white(0xffff, false, false), false); - test(PT::is_white(0x10ffff, false, false), false); + test(pt::is_white(5, false, false), false); + test(pt::is_white(9, false, false), true); + test(pt::is_white(10, false, false), false); + test(pt::is_white(31, false, false), false); + test(pt::is_white(32, false, false), true); + test(pt::is_white('z', false, false), false); + test(pt::is_white(0xbbcc, false, false), false); + test(pt::is_white(0xffff, false, false), false); + test(pt::is_white(0x10ffff, false, false), false); - test(PT::is_white(0x000B, false, false), false); - test(PT::is_white(0x00A0, false, false), false); - test(PT::is_white(0x2001, false, false), false); - test(PT::is_white(0x2009, false, false), false); - test(PT::is_white(0xFEFF, false, false), false); + test(pt::is_white(0x000B, false, false), false); + test(pt::is_white(0x00A0, false, false), false); + test(pt::is_white(0x2001, false, false), false); + test(pt::is_white(0x2009, false, false), false); + test(pt::is_white(0xFEFF, false, false), false); - test(PT::is_white(0x000B, true, false), true); - test(PT::is_white(0x00A0, true, false), true); - test(PT::is_white(0x2001, true, false), true); - test(PT::is_white(0x2009, true, false), true); - test(PT::is_white(0xFEFF, true, false), true); + test(pt::is_white(0x000B, true, false), true); + test(pt::is_white(0x00A0, true, false), true); + test(pt::is_white(0x2001, true, false), true); + test(pt::is_white(0x2009, true, false), true); + test(pt::is_white(0xFEFF, true, false), true); } @@ -95,56 +92,56 @@ void test_text2() int digit; - test(PT::is_digit(0, 10, &digit), false); - test(PT::is_digit(1, 10, &digit), false); - test(PT::is_digit(10, 10, &digit), false); - test(PT::is_digit(32, 10, &digit), false); - test(PT::is_digit('z', 10, &digit), false); - test(PT::is_digit('x', 10, &digit), false); + test(pt::is_digit(0, 10, &digit), false); + test(pt::is_digit(1, 10, &digit), false); + test(pt::is_digit(10, 10, &digit), false); + test(pt::is_digit(32, 10, &digit), false); + test(pt::is_digit('z', 10, &digit), false); + test(pt::is_digit('x', 10, &digit), false); - test(PT::is_digit('0', 2, &digit), true); + test(pt::is_digit('0', 2, &digit), true); test(digit, 0); - test(PT::is_digit('1', 2, &digit), true); + test(pt::is_digit('1', 2, &digit), true); test(digit, 1); - test(PT::is_digit('2', 2, &digit), false); + test(pt::is_digit('2', 2, &digit), false); - test(PT::is_digit('0', 8, &digit), true); + test(pt::is_digit('0', 8, &digit), true); test(digit, 0); - test(PT::is_digit('7', 8, &digit), true); + test(pt::is_digit('7', 8, &digit), true); test(digit, 7); - test(PT::is_digit('8', 8, &digit), false); + test(pt::is_digit('8', 8, &digit), false); - test(PT::is_digit('0', 10, &digit), true); + test(pt::is_digit('0', 10, &digit), true); test(digit, 0); - test(PT::is_digit('1', 10, &digit), true); + test(pt::is_digit('1', 10, &digit), true); test(digit, 1); - test(PT::is_digit('8', 10, &digit), true); + test(pt::is_digit('8', 10, &digit), true); test(digit, 8); - test(PT::is_digit('9', 10, &digit), true); + test(pt::is_digit('9', 10, &digit), true); test(digit, 9); - test(PT::is_digit('a', 10, &digit), false); + test(pt::is_digit('a', 10, &digit), false); - test(PT::is_digit('a', 16, &digit), true); + test(pt::is_digit('a', 16, &digit), true); test(digit, 0x0a); - test(PT::is_digit('c', 16, &digit), true); + test(pt::is_digit('c', 16, &digit), true); test(digit, 0x0c); - test(PT::is_digit('f', 16, &digit), true); + test(pt::is_digit('f', 16, &digit), true); test(digit, 0x0f); - test(PT::is_digit('g', 16, &digit), false); + test(pt::is_digit('g', 16, &digit), false); } @@ -152,34 +149,34 @@ void test_text3() { reset_test_counter("skip_white"); - test(PT::skip_white(""), ""); - test(PT::skip_white(" "), ""); - test(PT::skip_white("\n \n"), ""); - test(PT::skip_white("hello world"), "hello world"); - test(PT::skip_white(" hello world"), "hello world"); - test(PT::skip_white(" hello world"), "hello world"); - test(PT::skip_white(" hello world"), "hello world"); - test(PT::skip_white(" hello world"), "hello world"); + test(pt::skip_white(""), ""); + test(pt::skip_white(" "), ""); + test(pt::skip_white("\n \n"), ""); + test(pt::skip_white("hello world"), "hello world"); + test(pt::skip_white(" hello world"), "hello world"); + test(pt::skip_white(" hello world"), "hello world"); + test(pt::skip_white(" hello world"), "hello world"); + test(pt::skip_white(" hello world"), "hello world"); - test(PT::skip_white("\n\nhello world"), "hello world"); - test(PT::skip_white("\n\nhello world", true, true), "hello world"); - test(PT::skip_white("\n\nhello world", true, false), "\n\nhello world"); - test(PT::skip_white("\n\n \n\n \t\t\n\nhello world", true, true), "hello world"); + test(pt::skip_white("\n\nhello world"), "hello world"); + test(pt::skip_white("\n\nhello world", true, true), "hello world"); + test(pt::skip_white("\n\nhello world", true, false), "\n\nhello world"); + test(pt::skip_white("\n\n \n\n \t\t\n\nhello world", true, true), "hello world"); - test(PT::skip_white(L" hello world"), L"hello world"); - test(PT::skip_white(L" hello world"), L"hello world"); - test(PT::skip_white(L" hello world"), L"hello world"); - test(PT::skip_white(L" hello world"), L"hello world"); + test(pt::skip_white(L" hello world"), L"hello world"); + test(pt::skip_white(L" hello world"), L"hello world"); + test(pt::skip_white(L" hello world"), L"hello world"); + test(pt::skip_white(L" hello world"), L"hello world"); - test(PT::skip_white(L"\n\nhello world", true, true), L"hello world"); - test(PT::skip_white(L"\n\nhello world", true, false), L"\n\nhello world"); - test(PT::skip_white(L"\n\n \n\n \t\t\n\nhello world", true, true), L"hello world"); + test(pt::skip_white(L"\n\nhello world", true, true), L"hello world"); + test(pt::skip_white(L"\n\nhello world", true, false), L"\n\nhello world"); + test(pt::skip_white(L"\n\n \n\n \t\t\n\nhello world", true, true), L"hello world"); - test(PT::skip_white(L"\x000B hello world", true, true), L"hello world"); - test(PT::skip_white(L"\x000B hello world", false, true), L"\x000B hello world"); + test(pt::skip_white(L"\x000B hello world", true, true), L"hello world"); + test(pt::skip_white(L"\x000B hello world", false, true), L"\x000B hello world"); - test(PT::skip_white(L"\x2029 hello world", true, true), L"hello world"); - test(PT::skip_white(L"\x2029 hello world", false, true), L"\x2029 hello world"); + test(pt::skip_white(L"\x2029 hello world", true, true), L"hello world"); + test(pt::skip_white(L"\x2029 hello world", false, true), L"\x2029 hello world"); } @@ -188,35 +185,35 @@ void test_text4() { reset_test_counter("skip_white_from_back"); - test(PT::skip_white_from_back(""), ""); - test(PT::skip_white_from_back(" "), " "); - test(PT::skip_white_from_back("\n \n"), "\n \n"); + test(pt::skip_white_from_back(""), ""); + test(pt::skip_white_from_back(" "), " "); + test(pt::skip_white_from_back("\n \n"), "\n \n"); - test(PT::skip_white_from_back("hello world"), ""); - test(PT::skip_white_from_back("hello world "), " "); - test(PT::skip_white_from_back("hello world "), " "); - test(PT::skip_white_from_back("hello world "), " "); + test(pt::skip_white_from_back("hello world"), ""); + test(pt::skip_white_from_back("hello world "), " "); + test(pt::skip_white_from_back("hello world "), " "); + test(pt::skip_white_from_back("hello world "), " "); - test(PT::skip_white_from_back("hello world\n\n"), "\n\n"); - test(PT::skip_white_from_back("hello world\n\n", true, true), "\n\n"); - test(PT::skip_white_from_back("hello world\n\n", true, false), ""); - test(PT::skip_white_from_back("hello world\n\n \n\n \t\t\n\n", true, true), "\n\n \n\n \t\t\n\n"); + test(pt::skip_white_from_back("hello world\n\n"), "\n\n"); + test(pt::skip_white_from_back("hello world\n\n", true, true), "\n\n"); + test(pt::skip_white_from_back("hello world\n\n", true, false), ""); + test(pt::skip_white_from_back("hello world\n\n \n\n \t\t\n\n", true, true), "\n\n \n\n \t\t\n\n"); - test(PT::skip_white_from_back(L"hello world "), L" "); - test(PT::skip_white_from_back(L"hello world "), L" "); - test(PT::skip_white_from_back(L"hello world\n\n\n\t\t\t "), L"\n\n\n\t\t\t "); - test(PT::skip_white_from_back(L"hello world "), L" "); + test(pt::skip_white_from_back(L"hello world "), L" "); + test(pt::skip_white_from_back(L"hello world "), L" "); + test(pt::skip_white_from_back(L"hello world\n\n\n\t\t\t "), L"\n\n\n\t\t\t "); + test(pt::skip_white_from_back(L"hello world "), L" "); - test(PT::skip_white_from_back(L"hello world\n\n", true, true), L"\n\n"); - test(PT::skip_white_from_back(L"hello world\n\n", true, false), L""); - test(PT::skip_white_from_back(L"hello world\n\n \n\n \t\t\n\n", true, true), L"\n\n \n\n \t\t\n\n"); + test(pt::skip_white_from_back(L"hello world\n\n", true, true), L"\n\n"); + test(pt::skip_white_from_back(L"hello world\n\n", true, false), L""); + test(pt::skip_white_from_back(L"hello world\n\n \n\n \t\t\n\n", true, true), L"\n\n \n\n \t\t\n\n"); - test(PT::skip_white_from_back(L"hello world \x000B", true, true), L" \x000B"); - test(PT::skip_white_from_back(L"hello world \x000B", false, true), L""); + test(pt::skip_white_from_back(L"hello world \x000B", true, true), L" \x000B"); + test(pt::skip_white_from_back(L"hello world \x000B", false, true), L""); - test(PT::skip_white_from_back(L"hello world \x2029", true, true), L" \x2029"); - test(PT::skip_white_from_back(L"hello world \x2029", false, true), L""); + test(pt::skip_white_from_back(L"hello world \x2029", true, true), L" \x2029"); + test(pt::skip_white_from_back(L"hello world \x2029", false, true), L""); } @@ -224,44 +221,44 @@ void test_text5() { reset_test_counter("to_lower"); - test(PT::to_lower((char)0), (char)0); - test(PT::to_lower((char)32), (char)32); - test(PT::to_lower((char)127), (char)127); - test(PT::to_lower((char)128), (char)128); - test(PT::to_lower((char)200), (char)200); - test(PT::to_lower((char)255), (char)255); + test(pt::to_lower((char)0), (char)0); + test(pt::to_lower((char)32), (char)32); + test(pt::to_lower((char)127), (char)127); + test(pt::to_lower((char)128), (char)128); + test(pt::to_lower((char)200), (char)200); + test(pt::to_lower((char)255), (char)255); - test(PT::to_lower('a'), 'a'); - test(PT::to_lower('c'), 'c'); - test(PT::to_lower('t'), 't'); - test(PT::to_lower('z'), 'z'); - test(PT::to_lower('0'), '0'); - test(PT::to_lower('A'), 'a'); - test(PT::to_lower('C'), 'c'); - test(PT::to_lower('X'), 'x'); - test(PT::to_lower('Z'), 'z'); - test(PT::to_lower('@'), '@'); - test(PT::to_lower('['), '['); - test(PT::to_lower('`'), '`'); - test(PT::to_lower('{'), '{'); + test(pt::to_lower('a'), 'a'); + test(pt::to_lower('c'), 'c'); + test(pt::to_lower('t'), 't'); + test(pt::to_lower('z'), 'z'); + test(pt::to_lower('0'), '0'); + test(pt::to_lower('A'), 'a'); + test(pt::to_lower('C'), 'c'); + test(pt::to_lower('X'), 'x'); + test(pt::to_lower('Z'), 'z'); + test(pt::to_lower('@'), '@'); + test(pt::to_lower('['), '['); + test(pt::to_lower('`'), '`'); + test(pt::to_lower('{'), '{'); - test(PT::to_lower((wchar_t)0), (wchar_t)0); - test(PT::to_lower((wchar_t)32), (wchar_t)32); - test(PT::to_lower((wchar_t)127), (wchar_t)127); - test(PT::to_lower((wchar_t)128), (wchar_t)128); - test(PT::to_lower((wchar_t)200), (wchar_t)200); - test(PT::to_lower((wchar_t)255), (wchar_t)255); + test(pt::to_lower((wchar_t)0), (wchar_t)0); + test(pt::to_lower((wchar_t)32), (wchar_t)32); + test(pt::to_lower((wchar_t)127), (wchar_t)127); + test(pt::to_lower((wchar_t)128), (wchar_t)128); + test(pt::to_lower((wchar_t)200), (wchar_t)200); + test(pt::to_lower((wchar_t)255), (wchar_t)255); - test(PT::to_lower(L'a'), L'a'); - test(PT::to_lower(L't'), L't'); - test(PT::to_lower(L'z'), L'z'); - test(PT::to_lower(L'0'), L'0'); - test(PT::to_lower(L'A'), L'a'); - test(PT::to_lower(L'C'), L'c'); - test(PT::to_lower(L'X'), L'x'); - test(PT::to_lower(L'Z'), L'z'); - test(PT::to_lower(L'@'), L'@'); - test(PT::to_lower(L'['), L'['); + test(pt::to_lower(L'a'), L'a'); + test(pt::to_lower(L't'), L't'); + test(pt::to_lower(L'z'), L'z'); + test(pt::to_lower(L'0'), L'0'); + test(pt::to_lower(L'A'), L'a'); + test(pt::to_lower(L'C'), L'c'); + test(pt::to_lower(L'X'), L'x'); + test(pt::to_lower(L'Z'), L'z'); + test(pt::to_lower(L'@'), L'@'); + test(pt::to_lower(L'['), L'['); } @@ -269,44 +266,44 @@ void test_text6() { reset_test_counter("to_upper"); - test(PT::to_upper((char)0), (char)0); - test(PT::to_upper((char)32), (char)32); - test(PT::to_upper((char)127), (char)127); - test(PT::to_upper((char)128), (char)128); - test(PT::to_upper((char)200), (char)200); - test(PT::to_upper((char)255), (char)255); + test(pt::to_upper((char)0), (char)0); + test(pt::to_upper((char)32), (char)32); + test(pt::to_upper((char)127), (char)127); + test(pt::to_upper((char)128), (char)128); + test(pt::to_upper((char)200), (char)200); + test(pt::to_upper((char)255), (char)255); - test(PT::to_upper('a'), 'A'); - test(PT::to_upper('c'), 'C'); - test(PT::to_upper('t'), 'T'); - test(PT::to_upper('z'), 'Z'); - test(PT::to_upper('0'), '0'); - test(PT::to_upper('A'), 'A'); - test(PT::to_upper('C'), 'C'); - test(PT::to_upper('X'), 'X'); - test(PT::to_upper('Z'), 'Z'); - test(PT::to_upper('@'), '@'); - test(PT::to_upper('['), '['); - test(PT::to_upper('`'), '`'); - test(PT::to_upper('{'), '{'); + test(pt::to_upper('a'), 'A'); + test(pt::to_upper('c'), 'C'); + test(pt::to_upper('t'), 'T'); + test(pt::to_upper('z'), 'Z'); + test(pt::to_upper('0'), '0'); + test(pt::to_upper('A'), 'A'); + test(pt::to_upper('C'), 'C'); + test(pt::to_upper('X'), 'X'); + test(pt::to_upper('Z'), 'Z'); + test(pt::to_upper('@'), '@'); + test(pt::to_upper('['), '['); + test(pt::to_upper('`'), '`'); + test(pt::to_upper('{'), '{'); - test(PT::to_upper((wchar_t)0), (wchar_t)0); - test(PT::to_upper((wchar_t)32), (wchar_t)32); - test(PT::to_upper((wchar_t)127), (wchar_t)127); - test(PT::to_upper((wchar_t)128), (wchar_t)128); - test(PT::to_upper((wchar_t)200), (wchar_t)200); - test(PT::to_upper((wchar_t)255), (wchar_t)255); + test(pt::to_upper((wchar_t)0), (wchar_t)0); + test(pt::to_upper((wchar_t)32), (wchar_t)32); + test(pt::to_upper((wchar_t)127), (wchar_t)127); + test(pt::to_upper((wchar_t)128), (wchar_t)128); + test(pt::to_upper((wchar_t)200), (wchar_t)200); + test(pt::to_upper((wchar_t)255), (wchar_t)255); - test(PT::to_upper(L'a'), L'A'); - test(PT::to_upper(L't'), L'T'); - test(PT::to_upper(L'z'), L'Z'); - test(PT::to_upper(L'0'), L'0'); - test(PT::to_upper(L'A'), L'A'); - test(PT::to_upper(L'C'), L'C'); - test(PT::to_upper(L'X'), L'X'); - test(PT::to_upper(L'Z'), L'Z'); - test(PT::to_upper(L'@'), L'@'); - test(PT::to_upper(L'['), L'['); + test(pt::to_upper(L'a'), L'A'); + test(pt::to_upper(L't'), L'T'); + test(pt::to_upper(L'z'), L'Z'); + test(pt::to_upper(L'0'), L'0'); + test(pt::to_upper(L'A'), L'A'); + test(pt::to_upper(L'C'), L'C'); + test(pt::to_upper(L'X'), L'X'); + test(pt::to_upper(L'Z'), L'Z'); + test(pt::to_upper(L'@'), L'@'); + test(pt::to_upper(L'['), L'['); } @@ -476,27 +473,27 @@ void test_text11() str1 = "abcdefghijklm nopqrstuvwxyz"; str2 = str1; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += "A"; str2 += "a"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += "B"; str2 += "b"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += "@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; str2 += "@[`{cdefghijklmnopqrstuvwxyz"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += "0123456789"; str2 += "0123456789"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += "[];'\\!@#$%^&*()_+"; str2 += "[];'\\!@#$%^&*()_+"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); } @@ -507,27 +504,27 @@ void test_text12() str1 = L"abcdefghijklm nopqrstuvwxyz"; str2 = str1; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += L"A"; str2 += L"a"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += L"B"; str2 += L"b"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += L"@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; str2 += L"@[`{cdefghijklmnopqrstuvwxyz"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += L"0123456789"; str2 += L"0123456789"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); str1 += L"[];'\\!@#$%^&*()_+"; str2 += L"[];'\\!@#$%^&*()_+"; - test(PT::to_lower(str1), str2); + test(pt::to_lower(str1), str2); } @@ -538,27 +535,27 @@ void test_text13() str1 = "ABCDEFGHIJKLM NOPQRSTUVWXYZ"; str2 = str1; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += "a"; str2 += "A"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += "b"; str2 += "B"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += "@[`{cdefghijklmnopqrstuvwxyz"; str2 += "@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += "0123456789"; str2 += "0123456789"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += "[];'\\!@#$%^&*()_+"; str2 += "[];'\\!@#$%^&*()_+"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); } @@ -569,27 +566,27 @@ void test_text14() str1 = L"ABCDEFGHIJKLM NOPQRSTUVWXYZ"; str2 = str1; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += L"a"; str2 += L"A"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += L"b"; str2 += L"B"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += L"@[`{cdefghijklmnopqrstuvwxyz"; str2 += L"@[`{CDEFGHIJKLMNOPQRSTUVWXYZ"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += L"0123456789"; str2 += L"0123456789"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); str1 += L"[];'\\!@#$%^&*()_+"; str2 += L"[];'\\!@#$%^&*()_+"; - test(PT::to_upper(str1), str2); + test(pt::to_upper(str1), str2); } @@ -597,66 +594,66 @@ void test_text15() { reset_test_counter("compare const char *"); - test(PT::compare("", "") == 0, true); - test(PT::compare("a", "a") == 0, true); - test(PT::compare("abc", "abc") == 0, true); - test(PT::compare("ABC", "ABC") == 0, true); - test(PT::compare("hello world", "hello world") == 0, true); - test(PT::compare("hello world", "HELLO WORLD") > 0, true); - test(PT::compare("HELLO WORLD", "hello world") < 0, true); - test(PT::compare("HEllo WOrld", "heLLO woRLD") < 0, true); - test(PT::compare("heLLO woRLD", "HEllo WOrld") > 0, true); + test(pt::compare("", "") == 0, true); + test(pt::compare("a", "a") == 0, true); + test(pt::compare("abc", "abc") == 0, true); + test(pt::compare("ABC", "ABC") == 0, true); + test(pt::compare("hello world", "hello world") == 0, true); + test(pt::compare("hello world", "HELLO WORLD") > 0, true); + test(pt::compare("HELLO WORLD", "hello world") < 0, true); + test(pt::compare("HEllo WOrld", "heLLO woRLD") < 0, true); + test(pt::compare("heLLO woRLD", "HEllo WOrld") > 0, true); - test(PT::compare("a", "b") < 0, true); - test(PT::compare("b", "c") < 0, true); - test(PT::compare("x", "z") < 0, true); - test(PT::compare("hello world", "xhelloworld") < 0, true); + test(pt::compare("a", "b") < 0, true); + test(pt::compare("b", "c") < 0, true); + test(pt::compare("x", "z") < 0, true); + test(pt::compare("hello world", "xhelloworld") < 0, true); - test(PT::compare("c", "b") > 0, true); - test(PT::compare("d", "c") > 0, true); - test(PT::compare("z", "x") > 0, true); - test(PT::compare("xhello world", "helloworld") > 0, true); + test(pt::compare("c", "b") > 0, true); + test(pt::compare("d", "c") > 0, true); + test(pt::compare("z", "x") > 0, true); + test(pt::compare("xhello world", "helloworld") > 0, true); - test(PT::compare("abc8", "abc9") < 0, true); - test(PT::compare("abc9", "abc8") > 0, true); - test(PT::compare("abc8abc", "abc9abc") < 0, true); - test(PT::compare("abc9abc", "abc8abc") > 0, true); - test(PT::compare("abc9abc", "abc8") > 0, true); - test(PT::compare("abc8abc", "abc9") < 0, true); - test(PT::compare("abc8", "abc9abc") < 0, true); - test(PT::compare("abc9", "abc8abc") > 0, true); + test(pt::compare("abc8", "abc9") < 0, true); + test(pt::compare("abc9", "abc8") > 0, true); + test(pt::compare("abc8abc", "abc9abc") < 0, true); + test(pt::compare("abc9abc", "abc8abc") > 0, true); + test(pt::compare("abc9abc", "abc8") > 0, true); + test(pt::compare("abc8abc", "abc9") < 0, true); + test(pt::compare("abc8", "abc9abc") < 0, true); + test(pt::compare("abc9", "abc8abc") > 0, true); char foo[] = {"abc"}; char bar[] = {"abc"}; - test(PT::compare(foo, bar) == 0, true); + test(pt::compare(foo, bar) == 0, true); foo[0] = (char)(unsigned char)127; bar[0] = (char)(unsigned char)128; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (char)(unsigned char)128; bar[0] = (char)(unsigned char)127; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); foo[0] = (char)(unsigned char)1; bar[0] = (char)(unsigned char)255; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (char)(unsigned char)255; bar[0] = (char)(unsigned char)1; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); foo[0] = (char)(unsigned char)0; bar[0] = (char)(unsigned char)0; - test(PT::compare(foo, bar) == 0, true); + test(pt::compare(foo, bar) == 0, true); foo[0] = (char)(unsigned char)0; bar[0] = (char)(unsigned char)1; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (char)(unsigned char)1; bar[0] = (char)(unsigned char)0; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); } @@ -665,90 +662,90 @@ void test_text16() { reset_test_counter("compare const wchar_t *"); - test(PT::compare(L"", L"") == 0, true); - test(PT::compare(L"a", L"a") == 0, true); - test(PT::compare(L"abc", L"abc") == 0, true); - test(PT::compare(L"ABC", L"ABC") == 0, true); - test(PT::compare(L"hello world", L"hello world") == 0, true); - test(PT::compare(L"hello world", L"HELLO WORLD") > 0, true); - test(PT::compare(L"HELLO WORLD", L"hello world") < 0, true); - test(PT::compare(L"HEllo WOrld", L"heLLO woRLD") < 0, true); - test(PT::compare(L"heLLO woRLD", L"HEllo WOrld") > 0, true); + test(pt::compare(L"", L"") == 0, true); + test(pt::compare(L"a", L"a") == 0, true); + test(pt::compare(L"abc", L"abc") == 0, true); + test(pt::compare(L"ABC", L"ABC") == 0, true); + test(pt::compare(L"hello world", L"hello world") == 0, true); + test(pt::compare(L"hello world", L"HELLO WORLD") > 0, true); + test(pt::compare(L"HELLO WORLD", L"hello world") < 0, true); + test(pt::compare(L"HEllo WOrld", L"heLLO woRLD") < 0, true); + test(pt::compare(L"heLLO woRLD", L"HEllo WOrld") > 0, true); - test(PT::compare(L"a", L"b") < 0, true); - test(PT::compare(L"b", L"c") < 0, true); - test(PT::compare(L"x", L"z") < 0, true); - test(PT::compare(L"hello world", L"xhelloworld") < 0, true); + test(pt::compare(L"a", L"b") < 0, true); + test(pt::compare(L"b", L"c") < 0, true); + test(pt::compare(L"x", L"z") < 0, true); + test(pt::compare(L"hello world", L"xhelloworld") < 0, true); - test(PT::compare(L"c", L"b") > 0, true); - test(PT::compare(L"d", L"c") > 0, true); - test(PT::compare(L"z", L"x") > 0, true); - test(PT::compare(L"xhello world", L"helloworld") > 0, true); + test(pt::compare(L"c", L"b") > 0, true); + test(pt::compare(L"d", L"c") > 0, true); + test(pt::compare(L"z", L"x") > 0, true); + test(pt::compare(L"xhello world", L"helloworld") > 0, true); - test(PT::compare(L"abc8", L"abc9") < 0, true); - test(PT::compare(L"abc9", L"abc8") > 0, true); - test(PT::compare(L"abc8abc", L"abc9abc") < 0, true); - test(PT::compare(L"abc9abc", L"abc8abc") > 0, true); - test(PT::compare(L"abc9abc", L"abc8") > 0, true); - test(PT::compare(L"abc8abc", L"abc9") < 0, true); - test(PT::compare(L"abc8", L"abc9abc") < 0, true); - test(PT::compare(L"abc9", L"abc8abc") > 0, true); + test(pt::compare(L"abc8", L"abc9") < 0, true); + test(pt::compare(L"abc9", L"abc8") > 0, true); + test(pt::compare(L"abc8abc", L"abc9abc") < 0, true); + test(pt::compare(L"abc9abc", L"abc8abc") > 0, true); + test(pt::compare(L"abc9abc", L"abc8") > 0, true); + test(pt::compare(L"abc8abc", L"abc9") < 0, true); + test(pt::compare(L"abc8", L"abc9abc") < 0, true); + test(pt::compare(L"abc9", L"abc8abc") > 0, true); wchar_t foo[] = {L"abc"}; wchar_t bar[] = {L"abc"}; - test(PT::compare(foo, bar) == 0, true); + test(pt::compare(foo, bar) == 0, true); foo[0] = (wchar_t)127; bar[0] = (wchar_t)128; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (wchar_t)128; bar[0] = (wchar_t)127; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); foo[0] = (wchar_t)1; bar[0] = (wchar_t)255; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (wchar_t)255; bar[0] = (wchar_t)1; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); foo[0] = (wchar_t)0; bar[0] = (wchar_t)0; - test(PT::compare(foo, bar) == 0, true); + test(pt::compare(foo, bar) == 0, true); foo[0] = (wchar_t)0; bar[0] = (wchar_t)1; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (wchar_t)1; bar[0] = (wchar_t)0; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); foo[0] = (wchar_t)1; bar[0] = (wchar_t)0xffff; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (wchar_t)127; bar[0] = (wchar_t)0xffff; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (wchar_t)128; bar[0] = (wchar_t)0xffff; - test(PT::compare(foo, bar) < 0, true); + test(pt::compare(foo, bar) < 0, true); foo[0] = (wchar_t)0xffff; bar[0] = (wchar_t)1; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); foo[0] = (wchar_t)0xffff; bar[0] = (wchar_t)127; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); foo[0] = (wchar_t)0xffff; bar[0] = (wchar_t)128; - test(PT::compare(foo, bar) > 0, true); + test(pt::compare(foo, bar) > 0, true); } void test_text17() @@ -756,35 +753,35 @@ void test_text17() reset_test_counter("compare std::string"); std::string str1, str2; - test(PT::compare(str1, str2) == 0, true); + test(pt::compare(str1, str2) == 0, true); str1 = "abc"; str2 = "abc"; - test(PT::compare(str1, str2) == 0, true); + test(pt::compare(str1, str2) == 0, true); str1 = "aBc"; str2 = "abc"; - test(PT::compare(str1, str2) < 0, true); + test(pt::compare(str1, str2) < 0, true); str1 = "abc"; str2 = "aBc"; - test(PT::compare(str1, str2) > 0, true); + test(pt::compare(str1, str2) > 0, true); str1 = "xyz"; str2 = "abc"; - test(PT::compare(str1, str2) > 0, true); + test(pt::compare(str1, str2) > 0, true); str1 = "abc"; str2 = "xyz"; - test(PT::compare(str1, str2) < 0, true); + test(pt::compare(str1, str2) < 0, true); str1 = "abc1"; str2 = "abc2"; - test(PT::compare(str1, str2) < 0, true); + test(pt::compare(str1, str2) < 0, true); str1 = "abc9"; str2 = "abc8"; - test(PT::compare(str1, str2) > 0, true); + test(pt::compare(str1, str2) > 0, true); } void test_text18() @@ -792,35 +789,35 @@ void test_text18() reset_test_counter("compare std::wstring"); std::wstring str1, str2; - test(PT::compare(str1, str2) == 0, true); + test(pt::compare(str1, str2) == 0, true); str1 = L"abc"; str2 = L"abc"; - test(PT::compare(str1, str2) == 0, true); + test(pt::compare(str1, str2) == 0, true); str1 = L"aBc"; str2 = L"abc"; - test(PT::compare(str1, str2) < 0, true); + test(pt::compare(str1, str2) < 0, true); str1 = L"abc"; str2 = L"aBc"; - test(PT::compare(str1, str2) > 0, true); + test(pt::compare(str1, str2) > 0, true); str1 = L"xyz"; str2 = L"abc"; - test(PT::compare(str1, str2) > 0, true); + test(pt::compare(str1, str2) > 0, true); str1 = L"abc"; str2 = L"xyz"; - test(PT::compare(str1, str2) < 0, true); + test(pt::compare(str1, str2) < 0, true); str1 = L"abc1"; str2 = L"abc2"; - test(PT::compare(str1, str2) < 0, true); + test(pt::compare(str1, str2) < 0, true); str1 = L"abc9"; str2 = L"abc8"; - test(PT::compare(str1, str2) > 0, true); + test(pt::compare(str1, str2) > 0, true); } void test_text19() @@ -831,31 +828,31 @@ void test_text19() char bar[] = {"abcdef"}; size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero - test(PT::compare(foo, foo + len, bar) == 0, true); - test(PT::compare(foo, foo + len - 1, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) == 0, true); + test(pt::compare(foo, foo + len - 1, bar) < 0, true); foo[len - 1] = (char)(unsigned char)127; bar[len - 1] = (char)(unsigned char)128; - test(PT::compare(foo, foo + len, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) < 0, true); foo[len - 1] = (char)(unsigned char)128; bar[len - 1] = (char)(unsigned char)127; - test(PT::compare(foo, foo + len, bar) > 0, true); + test(pt::compare(foo, foo + len, bar) > 0, true); foo[len - 1] = (char)(unsigned char)1; bar[len - 1] = (char)(unsigned char)255; - test(PT::compare(foo, foo + len, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) < 0, true); foo[len - 1] = (char)(unsigned char)255; bar[len - 1] = (char)(unsigned char)1; - test(PT::compare(foo, foo + len, bar) > 0, true); + test(pt::compare(foo, foo + len, bar) > 0, true); foo[len - 1] = 'f'; bar[len - 1] = 'f'; bar[3] = 'X'; - test(PT::compare(foo, foo + len, bar) > 0, true); + test(pt::compare(foo, foo + len, bar) > 0, true); foo[3] = 'A'; - test(PT::compare(foo, foo + len, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) < 0, true); } void test_text20() @@ -866,39 +863,39 @@ void test_text20() wchar_t bar[] = {L"abcdef"}; size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero - test(PT::compare(foo, foo + len, bar) == 0, true); - test(PT::compare(foo, foo + len - 1, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) == 0, true); + test(pt::compare(foo, foo + len - 1, bar) < 0, true); foo[len - 1] = (wchar_t)127; bar[len - 1] = (wchar_t)128; - test(PT::compare(foo, foo + len, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) < 0, true); foo[len - 1] = (wchar_t)128; bar[len - 1] = (wchar_t)127; - test(PT::compare(foo, foo + len, bar) > 0, true); + test(pt::compare(foo, foo + len, bar) > 0, true); foo[len - 1] = (wchar_t)1; bar[len - 1] = (wchar_t)255; - test(PT::compare(foo, foo + len, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) < 0, true); foo[len - 1] = (wchar_t)255; bar[len - 1] = (wchar_t)1; - test(PT::compare(foo, foo + len, bar) > 0, true); + test(pt::compare(foo, foo + len, bar) > 0, true); foo[len - 1] = (wchar_t)1; bar[len - 1] = (wchar_t)0xffff; - test(PT::compare(foo, foo + len, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) < 0, true); foo[len - 1] = (wchar_t)0xffff; bar[len - 1] = (wchar_t)1; - test(PT::compare(foo, foo + len, bar) > 0, true); + test(pt::compare(foo, foo + len, bar) > 0, true); foo[len - 1] = L'f'; bar[len - 1] = L'f'; bar[3] = L'X'; - test(PT::compare(foo, foo + len, bar) > 0, true); + test(pt::compare(foo, foo + len, bar) > 0, true); foo[3] = L'A'; - test(PT::compare(foo, foo + len, bar) < 0, true); + test(pt::compare(foo, foo + len, bar) < 0, true); } @@ -907,66 +904,66 @@ void test_text21() { reset_test_counter("compare_nc const char *"); - test(PT::compare_nc("", "") == 0, true); - test(PT::compare_nc("a", "a") == 0, true); - test(PT::compare_nc("abc", "abc") == 0, true); - test(PT::compare_nc("ABC", "ABC") == 0, true); - test(PT::compare_nc("hello world", "hello world") == 0, true); - test(PT::compare_nc("hello world", "HELLO WORLD") == 0, true); - test(PT::compare_nc("HELLO WORLD", "hello world") == 0, true); - test(PT::compare_nc("HEllo WOrld", "heLLO woRLD") == 0, true); - test(PT::compare_nc("heLLO woRLD", "HEllo WOrld")== 0, true); + test(pt::compare_nc("", "") == 0, true); + test(pt::compare_nc("a", "a") == 0, true); + test(pt::compare_nc("abc", "abc") == 0, true); + test(pt::compare_nc("ABC", "ABC") == 0, true); + test(pt::compare_nc("hello world", "hello world") == 0, true); + test(pt::compare_nc("hello world", "HELLO WORLD") == 0, true); + test(pt::compare_nc("HELLO WORLD", "hello world") == 0, true); + test(pt::compare_nc("HEllo WOrld", "heLLO woRLD") == 0, true); + test(pt::compare_nc("heLLO woRLD", "HEllo WOrld")== 0, true); - test(PT::compare_nc("a", "b") < 0, true); - test(PT::compare_nc("b", "c") < 0, true); - test(PT::compare_nc("x", "z") < 0, true); - test(PT::compare_nc("hello world", "xhelloworld") < 0, true); + test(pt::compare_nc("a", "b") < 0, true); + test(pt::compare_nc("b", "c") < 0, true); + test(pt::compare_nc("x", "z") < 0, true); + test(pt::compare_nc("hello world", "xhelloworld") < 0, true); - test(PT::compare_nc("c", "b") > 0, true); - test(PT::compare_nc("d", "c") > 0, true); - test(PT::compare_nc("z", "x") > 0, true); - test(PT::compare_nc("xhello world", "helloworld") > 0, true); + test(pt::compare_nc("c", "b") > 0, true); + test(pt::compare_nc("d", "c") > 0, true); + test(pt::compare_nc("z", "x") > 0, true); + test(pt::compare_nc("xhello world", "helloworld") > 0, true); - test(PT::compare_nc("abc8", "abc9") < 0, true); - test(PT::compare_nc("abc9", "abc8") > 0, true); - test(PT::compare_nc("abc8abc", "abc9abc") < 0, true); - test(PT::compare_nc("abc9abc", "abc8abc") > 0, true); - test(PT::compare_nc("abc9abc", "abc8") > 0, true); - test(PT::compare_nc("abc8abc", "abc9") < 0, true); - test(PT::compare_nc("abc8", "abc9abc") < 0, true); - test(PT::compare_nc("abc9", "abc8abc") > 0, true); + test(pt::compare_nc("abc8", "abc9") < 0, true); + test(pt::compare_nc("abc9", "abc8") > 0, true); + test(pt::compare_nc("abc8abc", "abc9abc") < 0, true); + test(pt::compare_nc("abc9abc", "abc8abc") > 0, true); + test(pt::compare_nc("abc9abc", "abc8") > 0, true); + test(pt::compare_nc("abc8abc", "abc9") < 0, true); + test(pt::compare_nc("abc8", "abc9abc") < 0, true); + test(pt::compare_nc("abc9", "abc8abc") > 0, true); char foo[] = {"abc"}; char bar[] = {"abc"}; - test(PT::compare_nc(foo, bar) == 0, true); + test(pt::compare_nc(foo, bar) == 0, true); foo[0] = (char)(unsigned char)127; bar[0] = (char)(unsigned char)128; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (char)(unsigned char)128; bar[0] = (char)(unsigned char)127; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); foo[0] = (char)(unsigned char)1; bar[0] = (char)(unsigned char)255; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (char)(unsigned char)255; bar[0] = (char)(unsigned char)1; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); foo[0] = (char)(unsigned char)0; bar[0] = (char)(unsigned char)0; - test(PT::compare_nc(foo, bar) == 0, true); + test(pt::compare_nc(foo, bar) == 0, true); foo[0] = (char)(unsigned char)0; bar[0] = (char)(unsigned char)1; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (char)(unsigned char)1; bar[0] = (char)(unsigned char)0; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); } @@ -975,90 +972,90 @@ void test_text22() { reset_test_counter("compare_nc const wchar_t *"); - test(PT::compare_nc(L"", L"") == 0, true); - test(PT::compare_nc(L"a", L"a") == 0, true); - test(PT::compare_nc(L"abc", L"abc") == 0, true); - test(PT::compare_nc(L"ABC", L"ABC") == 0, true); - test(PT::compare_nc(L"hello world", L"hello world") == 0, true); - test(PT::compare_nc(L"hello world", L"HELLO WORLD") == 0, true); - test(PT::compare_nc(L"HELLO WORLD", L"hello world") == 0, true); - test(PT::compare_nc(L"HEllo WOrld", L"heLLO woRLD") == 0, true); - test(PT::compare_nc(L"heLLO woRLD", L"HEllo WOrld") == 0, true); + test(pt::compare_nc(L"", L"") == 0, true); + test(pt::compare_nc(L"a", L"a") == 0, true); + test(pt::compare_nc(L"abc", L"abc") == 0, true); + test(pt::compare_nc(L"ABC", L"ABC") == 0, true); + test(pt::compare_nc(L"hello world", L"hello world") == 0, true); + test(pt::compare_nc(L"hello world", L"HELLO WORLD") == 0, true); + test(pt::compare_nc(L"HELLO WORLD", L"hello world") == 0, true); + test(pt::compare_nc(L"HEllo WOrld", L"heLLO woRLD") == 0, true); + test(pt::compare_nc(L"heLLO woRLD", L"HEllo WOrld") == 0, true); - test(PT::compare_nc(L"a", L"b") < 0, true); - test(PT::compare_nc(L"b", L"c") < 0, true); - test(PT::compare_nc(L"x", L"z") < 0, true); - test(PT::compare_nc(L"hello world", L"xhelloworld") < 0, true); + test(pt::compare_nc(L"a", L"b") < 0, true); + test(pt::compare_nc(L"b", L"c") < 0, true); + test(pt::compare_nc(L"x", L"z") < 0, true); + test(pt::compare_nc(L"hello world", L"xhelloworld") < 0, true); - test(PT::compare_nc(L"c", L"b") > 0, true); - test(PT::compare_nc(L"d", L"c") > 0, true); - test(PT::compare_nc(L"z", L"x") > 0, true); - test(PT::compare_nc(L"xhello world", L"helloworld") > 0, true); + test(pt::compare_nc(L"c", L"b") > 0, true); + test(pt::compare_nc(L"d", L"c") > 0, true); + test(pt::compare_nc(L"z", L"x") > 0, true); + test(pt::compare_nc(L"xhello world", L"helloworld") > 0, true); - test(PT::compare_nc(L"abc8", L"abc9") < 0, true); - test(PT::compare_nc(L"abc9", L"abc8") > 0, true); - test(PT::compare_nc(L"abc8abc", L"abc9abc") < 0, true); - test(PT::compare_nc(L"abc9abc", L"abc8abc") > 0, true); - test(PT::compare_nc(L"abc9abc", L"abc8") > 0, true); - test(PT::compare_nc(L"abc8abc", L"abc9") < 0, true); - test(PT::compare_nc(L"abc8", L"abc9abc") < 0, true); - test(PT::compare_nc(L"abc9", L"abc8abc") > 0, true); + test(pt::compare_nc(L"abc8", L"abc9") < 0, true); + test(pt::compare_nc(L"abc9", L"abc8") > 0, true); + test(pt::compare_nc(L"abc8abc", L"abc9abc") < 0, true); + test(pt::compare_nc(L"abc9abc", L"abc8abc") > 0, true); + test(pt::compare_nc(L"abc9abc", L"abc8") > 0, true); + test(pt::compare_nc(L"abc8abc", L"abc9") < 0, true); + test(pt::compare_nc(L"abc8", L"abc9abc") < 0, true); + test(pt::compare_nc(L"abc9", L"abc8abc") > 0, true); wchar_t foo[] = {L"abc"}; wchar_t bar[] = {L"abc"}; - test(PT::compare_nc(foo, bar) == 0, true); + test(pt::compare_nc(foo, bar) == 0, true); foo[0] = (wchar_t)127; bar[0] = (wchar_t)128; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (wchar_t)128; bar[0] = (wchar_t)127; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); foo[0] = (wchar_t)1; bar[0] = (wchar_t)255; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (wchar_t)255; bar[0] = (wchar_t)1; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); foo[0] = (wchar_t)0; bar[0] = (wchar_t)0; - test(PT::compare_nc(foo, bar) == 0, true); + test(pt::compare_nc(foo, bar) == 0, true); foo[0] = (wchar_t)0; bar[0] = (wchar_t)1; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (wchar_t)1; bar[0] = (wchar_t)0; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); foo[0] = (wchar_t)1; bar[0] = (wchar_t)0xffff; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (wchar_t)127; bar[0] = (wchar_t)0xffff; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (wchar_t)128; bar[0] = (wchar_t)0xffff; - test(PT::compare_nc(foo, bar) < 0, true); + test(pt::compare_nc(foo, bar) < 0, true); foo[0] = (wchar_t)0xffff; bar[0] = (wchar_t)1; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); foo[0] = (wchar_t)0xffff; bar[0] = (wchar_t)127; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); foo[0] = (wchar_t)0xffff; bar[0] = (wchar_t)128; - test(PT::compare_nc(foo, bar) > 0, true); + test(pt::compare_nc(foo, bar) > 0, true); } void test_text23() @@ -1066,35 +1063,35 @@ void test_text23() reset_test_counter("compare_nc std::string"); std::string str1, str2; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = "abc"; str2 = "abc"; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = "aBc"; str2 = "abc"; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = "abc"; str2 = "aBc"; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = "xyz"; str2 = "abc"; - test(PT::compare_nc(str1, str2) > 0, true); + test(pt::compare_nc(str1, str2) > 0, true); str1 = "abc"; str2 = "xyz"; - test(PT::compare_nc(str1, str2) < 0, true); + test(pt::compare_nc(str1, str2) < 0, true); str1 = "abc1"; str2 = "abc2"; - test(PT::compare_nc(str1, str2) < 0, true); + test(pt::compare_nc(str1, str2) < 0, true); str1 = "abc9"; str2 = "abc8"; - test(PT::compare_nc(str1, str2) > 0, true); + test(pt::compare_nc(str1, str2) > 0, true); } void test_text24() @@ -1102,35 +1099,35 @@ void test_text24() reset_test_counter("compare_nc std::wstring"); std::wstring str1, str2; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = L"abc"; str2 = L"abc"; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = L"aBc"; str2 = L"abc"; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = L"abc"; str2 = L"aBc"; - test(PT::compare_nc(str1, str2) == 0, true); + test(pt::compare_nc(str1, str2) == 0, true); str1 = L"xyz"; str2 = L"abc"; - test(PT::compare_nc(str1, str2) > 0, true); + test(pt::compare_nc(str1, str2) > 0, true); str1 = L"abc"; str2 = L"xyz"; - test(PT::compare_nc(str1, str2) < 0, true); + test(pt::compare_nc(str1, str2) < 0, true); str1 = L"abc1"; str2 = L"abc2"; - test(PT::compare_nc(str1, str2) < 0, true); + test(pt::compare_nc(str1, str2) < 0, true); str1 = L"abc9"; str2 = L"abc8"; - test(PT::compare_nc(str1, str2) > 0, true); + test(pt::compare_nc(str1, str2) > 0, true); } void test_text25() @@ -1141,31 +1138,31 @@ void test_text25() char bar[] = {"abcdef"}; size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero - test(PT::compare_nc(foo, foo + len, bar) == 0, true); - test(PT::compare_nc(foo, foo + len - 1, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) == 0, true); + test(pt::compare_nc(foo, foo + len - 1, bar) < 0, true); foo[len - 1] = (char)(unsigned char)127; bar[len - 1] = (char)(unsigned char)128; - test(PT::compare_nc(foo, foo + len, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) < 0, true); foo[len - 1] = (char)(unsigned char)128; bar[len - 1] = (char)(unsigned char)127; - test(PT::compare_nc(foo, foo + len, bar) > 0, true); + test(pt::compare_nc(foo, foo + len, bar) > 0, true); foo[len - 1] = (char)(unsigned char)1; bar[len - 1] = (char)(unsigned char)255; - test(PT::compare_nc(foo, foo + len, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) < 0, true); foo[len - 1] = (char)(unsigned char)255; bar[len - 1] = (char)(unsigned char)1; - test(PT::compare_nc(foo, foo + len, bar) > 0, true); + test(pt::compare_nc(foo, foo + len, bar) > 0, true); foo[len - 1] = 'f'; bar[len - 1] = 'f'; bar[3] = 'X'; - test(PT::compare_nc(foo, foo + len, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) < 0, true); foo[3] = 'Z'; - test(PT::compare_nc(foo, foo + len, bar) > 0, true); + test(pt::compare_nc(foo, foo + len, bar) > 0, true); } void test_text26() @@ -1176,39 +1173,39 @@ void test_text26() wchar_t bar[] = {L"abcdef"}; size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero - test(PT::compare_nc(foo, foo + len, bar) == 0, true); - test(PT::compare_nc(foo, foo + len - 1, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) == 0, true); + test(pt::compare_nc(foo, foo + len - 1, bar) < 0, true); foo[len - 1] = (wchar_t)127; bar[len - 1] = (wchar_t)128; - test(PT::compare_nc(foo, foo + len, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) < 0, true); foo[len - 1] = (wchar_t)128; bar[len - 1] = (wchar_t)127; - test(PT::compare_nc(foo, foo + len, bar) > 0, true); + test(pt::compare_nc(foo, foo + len, bar) > 0, true); foo[len - 1] = (wchar_t)1; bar[len - 1] = (wchar_t)255; - test(PT::compare_nc(foo, foo + len, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) < 0, true); foo[len - 1] = (wchar_t)255; bar[len - 1] = (wchar_t)1; - test(PT::compare_nc(foo, foo + len, bar) > 0, true); + test(pt::compare_nc(foo, foo + len, bar) > 0, true); foo[len - 1] = (wchar_t)1; bar[len - 1] = (wchar_t)0xffff; - test(PT::compare_nc(foo, foo + len, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) < 0, true); foo[len - 1] = (wchar_t)0xffff; bar[len - 1] = (wchar_t)1; - test(PT::compare_nc(foo, foo + len, bar) > 0, true); + test(pt::compare_nc(foo, foo + len, bar) > 0, true); foo[len - 1] = L'f'; bar[len - 1] = L'f'; bar[3] = L'X'; - test(PT::compare_nc(foo, foo + len, bar) < 0, true); + test(pt::compare_nc(foo, foo + len, bar) < 0, true); foo[3] = L'Z'; - test(PT::compare_nc(foo, foo + len, bar) > 0, true); + test(pt::compare_nc(foo, foo + len, bar) > 0, true); } @@ -1338,35 +1335,35 @@ void test_text31() char bar[] = {"ABCDEF"}; size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero - test(PT::is_equal(foo, foo + len, bar), true); - test(PT::is_equal(foo, foo + len - 1, bar), false); + test(pt::is_equal(foo, foo + len, bar), true); + test(pt::is_equal(foo, foo + len - 1, bar), false); foo[len - 1] = (char)(unsigned char)127; bar[len - 1] = (char)(unsigned char)128; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = (char)(unsigned char)128; bar[len - 1] = (char)(unsigned char)127; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = (char)(unsigned char)1; bar[len - 1] = (char)(unsigned char)255; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = (char)(unsigned char)255; bar[len - 1] = (char)(unsigned char)1; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = 'f'; bar[len - 1] = 'f'; bar[3] = 'X'; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[3] = 'A'; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[3] = '1'; bar[3] = '1'; - test(PT::is_equal(foo, foo + len, bar), true); + test(pt::is_equal(foo, foo + len, bar), true); } @@ -1378,35 +1375,35 @@ void test_text32() wchar_t bar[] = {L"ABCDEF"}; size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero - test(PT::is_equal(foo, foo + len, bar), true); - test(PT::is_equal(foo, foo + len - 1, bar), false); + test(pt::is_equal(foo, foo + len, bar), true); + test(pt::is_equal(foo, foo + len - 1, bar), false); foo[len - 1] = (wchar_t)127; bar[len - 1] = (wchar_t)128; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = (wchar_t)128; bar[len - 1] = (wchar_t)127; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = (wchar_t)1; bar[len - 1] = (wchar_t)255; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = (wchar_t)255; bar[len - 1] = (wchar_t)1; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[len - 1] = L'f'; bar[len - 1] = L'f'; bar[3] = L'X'; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[3] = L'A'; - test(PT::is_equal(foo, foo + len, bar), false); + test(pt::is_equal(foo, foo + len, bar), false); foo[3] = L'1'; bar[3] = L'1'; - test(PT::is_equal(foo, foo + len, bar), true); + test(pt::is_equal(foo, foo + len, bar), true); } @@ -1537,43 +1534,43 @@ void test_text37() char bar[] = {"ABCDEF"}; size_t len = sizeof(foo) / sizeof(char) - 1; // minus terminating zero - test(PT::is_equal_nc(foo, foo + len, bar), true); - test(PT::is_equal_nc(foo, foo + len - 1, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len - 1, bar), false); foo[len - 1] = (char)(unsigned char)127; bar[len - 1] = (char)(unsigned char)128; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = (char)(unsigned char)128; bar[len - 1] = (char)(unsigned char)127; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = (char)(unsigned char)1; bar[len - 1] = (char)(unsigned char)255; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = (char)(unsigned char)255; bar[len - 1] = (char)(unsigned char)1; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = 'f'; bar[len - 1] = 'f'; bar[3] = 'X'; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[3] = 'A'; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[3] = '1'; bar[3] = '1'; - test(PT::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len, bar), true); foo[3] = 'h'; bar[3] = 'H'; - test(PT::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len, bar), true); foo[3] = 'H'; bar[3] = 'h'; - test(PT::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len, bar), true); } @@ -1585,43 +1582,43 @@ void test_text38() wchar_t bar[] = {L"ABCDEF"}; size_t len = sizeof(foo) / sizeof(wchar_t) - 1; // minus terminating zero - test(PT::is_equal_nc(foo, foo + len, bar), true); - test(PT::is_equal_nc(foo, foo + len - 1, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len - 1, bar), false); foo[len - 1] = (wchar_t)127; bar[len - 1] = (wchar_t)128; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = (wchar_t)128; bar[len - 1] = (wchar_t)127; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = (wchar_t)1; bar[len - 1] = (wchar_t)255; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = (wchar_t)255; bar[len - 1] = (wchar_t)1; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[len - 1] = L'f'; bar[len - 1] = L'f'; bar[3] = L'X'; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[3] = L'A'; - test(PT::is_equal_nc(foo, foo + len, bar), false); + test(pt::is_equal_nc(foo, foo + len, bar), false); foo[3] = L'1'; bar[3] = L'1'; - test(PT::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len, bar), true); foo[3] = L'h'; bar[3] = L'H'; - test(PT::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len, bar), true); foo[3] = L'H'; bar[3] = L'h'; - test(PT::is_equal_nc(foo, foo + len, bar), true); + test(pt::is_equal_nc(foo, foo + len, bar), true); } @@ -1629,20 +1626,20 @@ void test_text39() { reset_test_counter("is_substr const char *"); - test(PT::is_substr("", ""), true); - test(PT::is_substr("", "a"), true); - test(PT::is_substr("a", ""), false); - test(PT::is_substr("a", "a"), true); - test(PT::is_substr("a", "ab"), true); - test(PT::is_substr("abc", "abb"), false); - test(PT::is_substr("abc", "abcd"), true); - test(PT::is_substr("XYZ", "XYZabc"), true); - test(PT::is_substr("XYZ", "xYz"), false); - test(PT::is_substr("hello world", "hello world"), true); - test(PT::is_substr("hello world", "abc hello world"), false); - test(PT::is_substr("hello world", "hello worldabc"), true); - test(PT::is_substr("Hello World", "hello world"), false); - test(PT::is_substr("hello world", "Hello World"), false); + test(pt::is_substr("", ""), true); + test(pt::is_substr("", "a"), true); + test(pt::is_substr("a", ""), false); + test(pt::is_substr("a", "a"), true); + test(pt::is_substr("a", "ab"), true); + test(pt::is_substr("abc", "abb"), false); + test(pt::is_substr("abc", "abcd"), true); + test(pt::is_substr("XYZ", "XYZabc"), true); + test(pt::is_substr("XYZ", "xYz"), false); + test(pt::is_substr("hello world", "hello world"), true); + test(pt::is_substr("hello world", "abc hello world"), false); + test(pt::is_substr("hello world", "hello worldabc"), true); + test(pt::is_substr("Hello World", "hello world"), false); + test(pt::is_substr("hello world", "Hello World"), false); } @@ -1650,20 +1647,20 @@ void test_text40() { reset_test_counter("is_substr const wchar_t *"); - test(PT::is_substr(L"", L""), true); - test(PT::is_substr(L"", L"a"), true); - test(PT::is_substr(L"a", L""), false); - test(PT::is_substr(L"a", L"a"), true); - test(PT::is_substr(L"a", L"ab"), true); - test(PT::is_substr(L"abc", L"abb"), false); - test(PT::is_substr(L"abc", L"abcd"), true); - test(PT::is_substr(L"XYZ", L"XYZabc"), true); - test(PT::is_substr(L"XYZ", L"xYz"), false); - test(PT::is_substr(L"hello world", L"hello world"), true); - test(PT::is_substr(L"hello world", L"abc hello world"), false); - test(PT::is_substr(L"hello world", L"hello worldabc"), true); - test(PT::is_substr(L"Hello World", L"hello world"), false); - test(PT::is_substr(L"hello world", L"Hello World"), false); + test(pt::is_substr(L"", L""), true); + test(pt::is_substr(L"", L"a"), true); + test(pt::is_substr(L"a", L""), false); + test(pt::is_substr(L"a", L"a"), true); + test(pt::is_substr(L"a", L"ab"), true); + test(pt::is_substr(L"abc", L"abb"), false); + test(pt::is_substr(L"abc", L"abcd"), true); + test(pt::is_substr(L"XYZ", L"XYZabc"), true); + test(pt::is_substr(L"XYZ", L"xYz"), false); + test(pt::is_substr(L"hello world", L"hello world"), true); + test(pt::is_substr(L"hello world", L"abc hello world"), false); + test(pt::is_substr(L"hello world", L"hello worldabc"), true); + test(pt::is_substr(L"Hello World", L"hello world"), false); + test(pt::is_substr(L"hello world", L"Hello World"), false); } @@ -1673,51 +1670,51 @@ void test_text41() reset_test_counter("is_substr std::string"); std::string str1, str2; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = ""; str2 = "a"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = "a"; str2 = "a"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = "a"; str2 = ""; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = "abcd"; str2 = "abcd"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = "abcdefg"; str2 = "abcd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = "abcd"; str2 = "abcdefg"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = "aBCd"; str2 = "abcd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = "abcd"; str2 = "aBCd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = "aBCdefg"; str2 = "abcd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = "aBCd"; str2 = "abcdefg"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = "abcd"; str2 = "aBCdefg"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); } @@ -1726,51 +1723,51 @@ void test_text42() reset_test_counter("is_substr std::wstring"); std::wstring str1, str2; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = L""; str2 = L"a"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = L"a"; str2 = L"a"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = L"a"; str2 = L""; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = L"abcd"; str2 = L"abcd"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = L"abcdefg"; str2 = L"abcd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = L"abcd"; str2 = L"abcdefg"; - test(PT::is_substr(str1, str2), true); + test(pt::is_substr(str1, str2), true); str1 = L"aBCd"; str2 = L"abcd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = L"abcd"; str2 = L"aBCd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = L"aBCdefg"; str2 = L"abcd"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = L"aBCd"; str2 = L"abcdefg"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); str1 = L"abcd"; str2 = L"aBCdefg"; - test(PT::is_substr(str1, str2), false); + test(pt::is_substr(str1, str2), false); } @@ -1779,20 +1776,20 @@ void test_text43() { reset_test_counter("is_substr_nc const char *"); - test(PT::is_substr_nc("", ""), true); - test(PT::is_substr_nc("", "a"), true); - test(PT::is_substr_nc("a", ""), false); - test(PT::is_substr_nc("a", "a"), true); - test(PT::is_substr_nc("a", "ab"), true); - test(PT::is_substr_nc("abc", "abb"), false); - test(PT::is_substr_nc("abc", "abcd"), true); - test(PT::is_substr_nc("XYZ", "XYZabc"), true); - test(PT::is_substr_nc("XYZ", "xYz"), true); - test(PT::is_substr_nc("hello world", "hello world"), true); - test(PT::is_substr_nc("hello world", "abc hello world"), false); - test(PT::is_substr_nc("hello world", "hello worldabc"), true); - test(PT::is_substr_nc("Hello World", "hello world"), true); - test(PT::is_substr_nc("hello world", "Hello World"), true); + test(pt::is_substr_nc("", ""), true); + test(pt::is_substr_nc("", "a"), true); + test(pt::is_substr_nc("a", ""), false); + test(pt::is_substr_nc("a", "a"), true); + test(pt::is_substr_nc("a", "ab"), true); + test(pt::is_substr_nc("abc", "abb"), false); + test(pt::is_substr_nc("abc", "abcd"), true); + test(pt::is_substr_nc("XYZ", "XYZabc"), true); + test(pt::is_substr_nc("XYZ", "xYz"), true); + test(pt::is_substr_nc("hello world", "hello world"), true); + test(pt::is_substr_nc("hello world", "abc hello world"), false); + test(pt::is_substr_nc("hello world", "hello worldabc"), true); + test(pt::is_substr_nc("Hello World", "hello world"), true); + test(pt::is_substr_nc("hello world", "Hello World"), true); } @@ -1800,20 +1797,20 @@ void test_text44() { reset_test_counter("is_substr_nc const wchar_t *"); - test(PT::is_substr_nc(L"", L""), true); - test(PT::is_substr_nc(L"", L"a"), true); - test(PT::is_substr_nc(L"a", L""), false); - test(PT::is_substr_nc(L"a", L"a"), true); - test(PT::is_substr_nc(L"a", L"ab"), true); - test(PT::is_substr_nc(L"abc", L"abb"), false); - test(PT::is_substr_nc(L"abc", L"abcd"), true); - test(PT::is_substr_nc(L"XYZ", L"XYZabc"), true); - test(PT::is_substr_nc(L"XYZ", L"xYz"), true); - test(PT::is_substr_nc(L"hello world", L"hello world"), true); - test(PT::is_substr_nc(L"hello world", L"abc hello world"), false); - test(PT::is_substr_nc(L"hello world", L"hello worldabc"), true); - test(PT::is_substr_nc(L"Hello World", L"hello world"), true); - test(PT::is_substr_nc(L"hello world", L"Hello World"), true); + test(pt::is_substr_nc(L"", L""), true); + test(pt::is_substr_nc(L"", L"a"), true); + test(pt::is_substr_nc(L"a", L""), false); + test(pt::is_substr_nc(L"a", L"a"), true); + test(pt::is_substr_nc(L"a", L"ab"), true); + test(pt::is_substr_nc(L"abc", L"abb"), false); + test(pt::is_substr_nc(L"abc", L"abcd"), true); + test(pt::is_substr_nc(L"XYZ", L"XYZabc"), true); + test(pt::is_substr_nc(L"XYZ", L"xYz"), true); + test(pt::is_substr_nc(L"hello world", L"hello world"), true); + test(pt::is_substr_nc(L"hello world", L"abc hello world"), false); + test(pt::is_substr_nc(L"hello world", L"hello worldabc"), true); + test(pt::is_substr_nc(L"Hello World", L"hello world"), true); + test(pt::is_substr_nc(L"hello world", L"Hello World"), true); } @@ -1823,51 +1820,51 @@ void test_text45() reset_test_counter("is_substr_nc std::string"); std::string str1, str2; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = ""; str2 = "a"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = "a"; str2 = "a"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = "a"; str2 = ""; - test(PT::is_substr_nc(str1, str2), false); + test(pt::is_substr_nc(str1, str2), false); str1 = "abcd"; str2 = "abcd"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = "abcdefg"; str2 = "abcd"; - test(PT::is_substr_nc(str1, str2), false); + test(pt::is_substr_nc(str1, str2), false); str1 = "abcd"; str2 = "abcdefg"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = "aBCd"; str2 = "abcd"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = "abcd"; str2 = "aBCd"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = "aBCdefg"; str2 = "abcd"; - test(PT::is_substr_nc(str1, str2), false); + test(pt::is_substr_nc(str1, str2), false); str1 = "aBCd"; str2 = "abcdefg"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = "abcd"; str2 = "aBCdefg"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); } @@ -1877,51 +1874,51 @@ void test_text46() reset_test_counter("is_substr_nc std::wstring"); std::wstring str1, str2; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L""; str2 = L"a"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L"a"; str2 = L"a"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L"a"; str2 = L""; - test(PT::is_substr_nc(str1, str2), false); + test(pt::is_substr_nc(str1, str2), false); str1 = L"abcd"; str2 = L"abcd"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L"abcdefg"; str2 = L"abcd"; - test(PT::is_substr_nc(str1, str2), false); + test(pt::is_substr_nc(str1, str2), false); str1 = L"abcd"; str2 = L"abcdefg"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L"aBCd"; str2 = L"abcd"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L"abcd"; str2 = L"aBCd"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L"aBCdefg"; str2 = L"abcd"; - test(PT::is_substr_nc(str1, str2), false); + test(pt::is_substr_nc(str1, str2), false); str1 = L"aBCd"; str2 = L"abcdefg"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); str1 = L"abcd"; str2 = L"aBCdefg"; - test(PT::is_substr_nc(str1, str2), true); + test(pt::is_substr_nc(str1, str2), true); } diff --git a/tests/convert.h b/tests/convert.h index 431697e..e3c0421 100644 --- a/tests/convert.h +++ b/tests/convert.h @@ -46,14 +46,10 @@ namespace pt_convert_tests - - void make_tests(); - - } } diff --git a/tests/csvparser.cpp b/tests/csvparser.cpp index 6fce734..eecbc3e 100644 --- a/tests/csvparser.cpp +++ b/tests/csvparser.cpp @@ -44,14 +44,11 @@ namespace pt { -// remove me in the future (when PT will be changed to pt) -using namespace PT; - - namespace pt_csvparser_tests { + void test_csvparser(const char * input_str, const char * expected_json) { CSVParser csv_parser; diff --git a/tests/mainoptionsparser.cpp b/tests/mainoptionsparser.cpp index 646b9a7..569b7aa 100644 --- a/tests/mainoptionsparser.cpp +++ b/tests/mainoptionsparser.cpp @@ -45,13 +45,10 @@ namespace pt { -// remove me in the future (when PT will be changed to pt) -using namespace PT; - - namespace pt_mainoptions_tests { + struct MainOptionsParserOutputTest { MainOptionsParser::Status status; @@ -83,7 +80,7 @@ bool has_space_in_str(const char * arg) { while( *arg ) { - if( PT::is_white((wchar_t)*arg) ) + if( is_white((wchar_t)*arg) ) return true; arg += 1; From 59d4c9a9c824caed3d96aff121cf75f95d879abc Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 21 May 2021 00:24:56 +0200 Subject: [PATCH 61/67] changed utf8 functions: PascalCase to snake_case --- src/csv/csvparser.cpp | 6 +- src/log/filelog.cpp | 6 +- src/log/log.cpp | 6 +- src/mainoptions/mainoptionsparser.cpp | 4 +- src/space/space.cpp | 2 +- src/space/space.h | 2 +- src/space/spaceparser.cpp | 8 +-- src/utf8/utf8.cpp | 98 +++++++++++++-------------- src/utf8/utf8.h | 64 +++++++++-------- src/utf8/utf8_private.cpp | 36 +++++----- src/utf8/utf8_private.h | 46 ++++++------- src/utf8/utf8_templates.h | 44 ++++++------ tests/mainoptionsparser.cpp | 2 +- 13 files changed, 161 insertions(+), 163 deletions(-) diff --git a/src/csv/csvparser.cpp b/src/csv/csvparser.cpp index cd2f345..4ab1480 100644 --- a/src/csv/csvparser.cpp +++ b/src/csv/csvparser.cpp @@ -81,7 +81,7 @@ CSVParser::Status CSVParser::parse_file(const wchar_t * file_name, Space & out_s { std::string file_name_utf8; - WideToUTF8(file_name, file_name_utf8); + wide_to_utf8(file_name, file_name_utf8); return parse_file(file_name_utf8.c_str(), out_space); } @@ -295,7 +295,7 @@ bool correct; do { - UTF8ToInt(file, c, correct); + utf8_to_int(file, c, correct); if( !file ) return lastc; @@ -348,7 +348,7 @@ bool correct; do { - size_t len = UTF8ToInt(pchar_ascii, c, correct); + size_t len = utf8_to_int(pchar_ascii, c, correct); pchar_ascii += len; } while( *pchar_ascii && !correct ); diff --git a/src/log/filelog.cpp b/src/log/filelog.cpp index ff9b82c..afb76f3 100644 --- a/src/log/filelog.cpp +++ b/src/log/filelog.cpp @@ -74,7 +74,7 @@ void FileLog::init(const std::wstring & log_file, bool log_stdout, int log_level this->log_stdout = log_stdout; this->log_level = log_level; this->save_each_line = save_each_line; - WideToUTF8(log_file, this->log_file); + wide_to_utf8(log_file, this->log_file); } @@ -111,7 +111,7 @@ void FileLog::save_log(WTextStream * buffer) { if( log_stdout ) { - WideStreamToUTF8(*buffer, std::cout); + wide_stream_to_utf8(*buffer, std::cout); } if( !log_file.empty() ) @@ -126,7 +126,7 @@ void FileLog::save_log(WTextStream * buffer) if( file ) { - WideStreamToUTF8(*buffer, file); + wide_stream_to_utf8(*buffer, file); file.flush(); } } diff --git a/src/log/log.cpp b/src/log/log.cpp index 34010ee..fb7ec91 100644 --- a/src/log/log.cpp +++ b/src/log/log.cpp @@ -136,7 +136,7 @@ Log & Log::operator<<(const char * s) { if( buffer && file_log && s && current_level <= file_log->get_log_level() ) { - UTF8ToWide(s, *buffer, false); + utf8_to_wide(s, *buffer, false); } return *this; @@ -148,7 +148,7 @@ Log & Log::operator<<(const std::string & s) { if( buffer && file_log && current_level <= file_log->get_log_level() ) { - UTF8ToWide(s, *buffer, false); + utf8_to_wide(s, *buffer, false); } return *this; @@ -160,7 +160,7 @@ Log & Log::operator<<(const std::string * s) { if( buffer && file_log && current_level <= file_log->get_log_level() ) { - UTF8ToWide(*s, *buffer, false); + utf8_to_wide(*s, *buffer, false); } return *this; diff --git a/src/mainoptions/mainoptionsparser.cpp b/src/mainoptions/mainoptionsparser.cpp index 685674b..ae839b5 100644 --- a/src/mainoptions/mainoptionsparser.cpp +++ b/src/mainoptions/mainoptionsparser.cpp @@ -165,7 +165,7 @@ void MainOptionsParser::convert_str(const char * src, std::wstring & dst) { if( should_use_utf8 ) { - UTF8ToWide(src, dst); + utf8_to_wide(src, dst); } else { @@ -181,7 +181,7 @@ void MainOptionsParser::convert_str(const char * src, size_t len, std::wstring & { if( should_use_utf8 ) { - UTF8ToWide(src, len, dst); + utf8_to_wide(src, len, dst); } else { diff --git a/src/space/space.cpp b/src/space/space.cpp index f2b7b79..f4157ad 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -942,7 +942,7 @@ std::wstring Space::to_wstr() const if( type == type_string ) { - UTF8ToWide(value.value_string, str); + utf8_to_wide(value.value_string, str); return str; } diff --git a/src/space/space.h b/src/space/space.h index 0278803..96dea3b 100644 --- a/src/space/space.h +++ b/src/space/space.h @@ -881,7 +881,7 @@ protected: StreamType temp_stream; // input is wide but output is utf8 - WideToUTF8(input_str, temp_stream, false); + wide_to_utf8(input_str, temp_stream, false); copy_input_stream_to_output(temp_stream, out_str, escape); } } diff --git a/src/space/spaceparser.cpp b/src/space/spaceparser.cpp index b36ef41..4839d6a 100644 --- a/src/space/spaceparser.cpp +++ b/src/space/spaceparser.cpp @@ -145,7 +145,7 @@ SpaceParser::Status SpaceParser::ParseJSONFile(const wchar_t * file_name) { std::string file_name_utf8; - WideToUTF8(file_name, file_name_utf8); + wide_to_utf8(file_name, file_name_utf8); return ParseJSONFile(file_name_utf8.c_str()); } @@ -195,7 +195,7 @@ SpaceParser::Status SpaceParser::ParseSpaceFile(const wchar_t * file_name) { std::string file_name_utf8; - WideToUTF8(file_name, file_name_utf8); + wide_to_utf8(file_name, file_name_utf8); return ParseSpaceFile(file_name_utf8.c_str()); } @@ -972,7 +972,7 @@ bool correct; do { - UTF8ToInt(file, c, correct); + utf8_to_int(file, c, correct); if( !file ) return lastc; @@ -1025,7 +1025,7 @@ bool correct; do { - size_t len = UTF8ToInt(pchar_ascii, c, correct); + size_t len = utf8_to_int(pchar_ascii, c, correct); pchar_ascii += len; } while( *pchar_ascii && !correct ); diff --git a/src/utf8/utf8.cpp b/src/utf8/utf8.cpp index 5ed9e19..325de87 100644 --- a/src/utf8/utf8.cpp +++ b/src/utf8/utf8.cpp @@ -50,7 +50,7 @@ namespace pt /*! returns true if 'c' is a correct unicode character */ -bool UTF8_CheckRange(int c) +bool utf8_check_range(int c) { return c>=0 && c<=0x10FFFF && !(c>=0xD800 && c<=0xDFFF); } @@ -62,7 +62,7 @@ bool UTF8_CheckRange(int c) this method is used when reading from an utf8 string how_many_bytes - means how many bytes from the utf8 string were read */ -bool UTF8_CheckRange(int c, int how_many_bytes) +bool utf8_check_range(int c, int how_many_bytes) { if( c >= 0x0000 && c <= 0x007f && how_many_bytes == 1 ) { @@ -111,7 +111,7 @@ return false; (returns zero only if utf8_len is zero) even if there are errors the functions returns a different from zero value */ -size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct) +size_t utf8_to_int(const char * utf8, size_t utf8_len, int & res, bool & correct) { size_t i, len; @@ -121,7 +121,7 @@ size_t i, len; if( utf8_len == 0 ) return 0; - if( !private_namespace::UTF8ToInt_FirstOctet(utf8[0], len, res) ) + if( !private_namespace::utf8_to_int_first_octet(utf8[0], len, res) ) return 1; if( utf8_len < len ) @@ -129,11 +129,11 @@ size_t i, len; for(i=1 ; i0xffff ) { @@ -291,13 +291,13 @@ static void IntToWide(int c, std::wstring & res) the function returns false if there were some errors when converting */ -bool UTF8ToWide(const char * utf8, size_t utf8_len, std::wstring & res, bool clear, int mode) +bool utf8_to_wide(const char * utf8, size_t utf8_len, std::wstring & res, bool clear, int mode) { if( clear ) res.clear(); - bool status = private_namespace::UTF8ToWideGeneric(utf8, utf8_len, mode, [&res](int c) { - IntToWide(c, res); + bool status = private_namespace::utf8_to_wide_generic(utf8, utf8_len, mode, [&res](int c) { + int_to_wide(c, res); }); return status; @@ -321,14 +321,14 @@ bool UTF8ToWide(const char * utf8, size_t utf8_len, std::wstring & res, bool cle the function returns false if there were some errors when converting */ -bool UTF8ToWide(const char * utf8, std::wstring & res, bool clear, int mode) +bool utf8_to_wide(const char * utf8, std::wstring & res, bool clear, int mode) { size_t utf8_len = 0; while( utf8[utf8_len] != 0 ) utf8_len += 1; -return UTF8ToWide(utf8, utf8_len, res, clear, mode); +return utf8_to_wide(utf8, utf8_len, res, clear, mode); } @@ -347,9 +347,9 @@ return UTF8ToWide(utf8, utf8_len, res, clear, mode); the function returns false if there were some errors when converting */ -bool UTF8ToWide(const std::string & utf8, std::wstring & res, bool clear, int mode) +bool utf8_to_wide(const std::string & utf8, std::wstring & res, bool clear, int mode) { - return UTF8ToWide(utf8.c_str(), utf8.size(), res, clear, mode); + return utf8_to_wide(utf8.c_str(), utf8.size(), res, clear, mode); } @@ -368,7 +368,7 @@ bool UTF8ToWide(const std::string & utf8, std::wstring & res, bool clear, int mo the function returns false if there were some errors when converting */ -bool UTF8ToWide(std::istream & utf8, std::wstring & res, bool clear, int mode) +bool utf8_to_wide(std::istream & utf8, std::wstring & res, bool clear, int mode) { int z; bool correct, was_error = false; @@ -376,7 +376,7 @@ bool correct, was_error = false; if( clear ) res.clear(); - while( UTF8ToInt(utf8, z, correct) > 0 ) + while( utf8_to_int(utf8, z, correct) > 0 ) { if( !correct ) { @@ -387,7 +387,7 @@ bool correct, was_error = false; } else { - IntToWide(z, res); + int_to_wide(z, res); } } @@ -410,13 +410,13 @@ return !was_error; the function returns how many characters have been written to the utf8, zero means the utf8 buffer is too small or 'z' is an incorrect unicode character */ -size_t IntToUTF8(int z, char * utf8, size_t utf8_max_len) +size_t int_to_utf8(int z, char * utf8, size_t utf8_max_len) { char buf[10]; int i = 0; int mask = 0x3f; // 6 first bits set - if( utf8_max_len==0 || !UTF8_CheckRange(z) ) + if( utf8_max_len==0 || !utf8_check_range(z) ) return 0; if( z <= 0x7f ) @@ -464,14 +464,14 @@ return a; the function returns how many characters have been written to the utf8 string, zero means that 'z' is an incorrect unicode character */ -size_t IntToUTF8(int z, std::string & utf8, bool clear) +size_t int_to_utf8(int z, std::string & utf8, bool clear) { char buf[10]; if( clear ) utf8.clear(); - size_t len = IntToUTF8(z, buf, sizeof(buf)/sizeof(char)); + size_t len = int_to_utf8(z, buf, sizeof(buf)/sizeof(char)); size_t i; for(i=0 ; i 0 ) { - chars = private_namespace::WideOneToUTF8(wide_string, string_len, utf8, was_error, mode); + chars = private_namespace::wide_one_to_utf8(wide_string, string_len, utf8, was_error, mode); wide_string += chars; string_len -= chars; } @@ -531,7 +531,7 @@ return !was_error; this function returns false if there were some errors when converting */ -bool WideToUTF8(const wchar_t * wide_string, std::string & utf8, bool clear, int mode) +bool wide_to_utf8(const wchar_t * wide_string, std::string & utf8, bool clear, int mode) { bool was_error = false; @@ -539,7 +539,7 @@ bool was_error = false; utf8.clear(); while( *wide_string ) - wide_string += private_namespace::WideOneToUTF8(wide_string, utf8, was_error, mode); + wide_string += private_namespace::wide_one_to_utf8(wide_string, utf8, was_error, mode); return !was_error; } @@ -560,9 +560,9 @@ return !was_error; this function returns false if there were some errors when converting */ -bool WideToUTF8(const std::wstring & wide_string, std::string & utf8, bool clear, int mode) +bool wide_to_utf8(const std::wstring & wide_string, std::string & utf8, bool clear, int mode) { - return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, clear, mode); + return wide_to_utf8(wide_string.c_str(), wide_string.size(), utf8, clear, mode); } @@ -590,7 +590,7 @@ bool WideToUTF8(const std::wstring & wide_string, std::string & utf8, bool clear if there is an error when converting (there is an incorrect character in the wide string) the function will continue converting but if the buffer is too small the function breaks immediately */ -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, size_t & utf8_written, int mode) +bool wide_to_utf8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, size_t & utf8_written, int mode) { bool was_error = false; bool was_buffer_to_small; @@ -600,7 +600,7 @@ size_t chars, utf8_saved; while( string_len > 0 ) { - chars = private_namespace::WideOneToUTF8(wide_string, string_len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); + chars = private_namespace::wide_one_to_utf8(wide_string, string_len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); if( was_buffer_to_small ) { @@ -644,9 +644,9 @@ return !was_error; if there is an error when converting (there is an incorrect character in the wide string) the function will continue converting but if the buffer is too small the function breaks immediately */ -bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode) +bool wide_to_utf8(const std::wstring & wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode) { - return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, utf8_len, utf8_written, mode); + return wide_to_utf8(wide_string.c_str(), wide_string.size(), utf8, utf8_len, utf8_written, mode); } @@ -672,7 +672,7 @@ bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, will continue converting but if the buffer is too small the function breaks immediately (in both cases the utf8 buffer is null terminated) */ -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, int mode) +bool wide_to_utf8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, int mode) { size_t utf8_saved; bool res; @@ -680,7 +680,7 @@ bool res; if( utf8_len == 0 ) return false; - res = WideToUTF8(wide_string, string_len, utf8, utf8_len - 1, utf8_saved, mode); + res = wide_to_utf8(wide_string, string_len, utf8, utf8_len - 1, utf8_saved, mode); utf8[utf8_saved] = 0; return res; @@ -708,9 +708,9 @@ return res; will continue converting but if the buffer is too small the function breaks immediately (in both cases the utf8 buffer is null terminated) */ -bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, int mode) +bool wide_to_utf8(const std::wstring & wide_string, char * utf8, size_t utf8_len, int mode) { - return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, utf8_len, mode); + return wide_to_utf8(wide_string.c_str(), wide_string.size(), utf8, utf8_len, mode); } @@ -735,7 +735,7 @@ bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, if there is an error when converting (there is an incorrect character in the wide string) the function will continue converting but if the buffer is too small the function breaks immediately */ -bool WideToUTF8(const wchar_t * wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode) +bool wide_to_utf8(const wchar_t * wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode) { bool was_error = false; bool was_buffer_to_small; @@ -747,7 +747,7 @@ size_t len; while( *wide_string ) { len = (*(wide_string+1) == 0) ? 1 : 2; - chars = private_namespace::WideOneToUTF8(wide_string, len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); + chars = private_namespace::wide_one_to_utf8(wide_string, len, utf8, utf8_len, utf8_saved, was_buffer_to_small, was_error, mode); if( was_buffer_to_small ) { @@ -790,7 +790,7 @@ return !was_error; will continue converting but if the buffer is too small the function breaks immediately (in both cases the utf8 buffer is null terminated) */ -bool WideToUTF8(const wchar_t * wide_string, char * utf8, size_t utf8_len, int mode) +bool wide_to_utf8(const wchar_t * wide_string, char * utf8, size_t utf8_len, int mode) { size_t utf8_saved; bool res; @@ -798,7 +798,7 @@ bool res; if( utf8_len == 0 ) return false; - res = WideToUTF8(wide_string, utf8, utf8_len - 1, utf8_saved, mode); + res = wide_to_utf8(wide_string, utf8, utf8_len - 1, utf8_saved, mode); utf8[utf8_saved] = 0; return res; diff --git a/src/utf8/utf8.h b/src/utf8/utf8.h index fecd2eb..65dbda9 100644 --- a/src/utf8/utf8.h +++ b/src/utf8/utf8.h @@ -61,7 +61,7 @@ namespace pt /*! returns true if 'c' is a correct unicode character */ -bool UTF8_CheckRange(int c); +bool utf8_check_range(int c); /*! @@ -70,7 +70,7 @@ bool UTF8_CheckRange(int c); this method is used when reading from an utf8 string how_many_chars - means how many characters from utf8 string were read */ -bool UTF8_CheckRange(int c, int how_many_bytes); +bool utf8_check_range(int c, int how_many_bytes); /* @@ -86,31 +86,31 @@ bool UTF8_CheckRange(int c, int how_many_bytes); /*! converting one character from UTF-8 to an int */ -size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct); -size_t UTF8ToInt(const char * utf8, int & res, bool & correct); -size_t UTF8ToInt(const std::string & utf8, int & res, bool & correct); -size_t UTF8ToInt(std::istream & utf8, int & res, bool & correct); +size_t utf8_to_int(const char * utf8, size_t utf8_len, int & res, bool & correct); +size_t utf8_to_int(const char * utf8, int & res, bool & correct); +size_t utf8_to_int(const std::string & utf8, int & res, bool & correct); +size_t utf8_to_int(std::istream & utf8, int & res, bool & correct); /*! converting UTF-8 string to a wide string */ -bool UTF8ToWide(const char * utf8, size_t utf8_len, std::wstring & res, bool clear = true, int mode = 1); -bool UTF8ToWide(const char * utf8, std::wstring & res, bool clear = true, int mode = 1); -bool UTF8ToWide(const std::string & utf8, std::wstring & res, bool clear = true, int mode = 1); -bool UTF8ToWide(std::istream & utf8, std::wstring & res, bool clear = true, int mode = 1); +bool utf8_to_wide(const char * utf8, size_t utf8_len, std::wstring & res, bool clear = true, int mode = 1); +bool utf8_to_wide(const char * utf8, std::wstring & res, bool clear = true, int mode = 1); +bool utf8_to_wide(const std::string & utf8, std::wstring & res, bool clear = true, int mode = 1); +bool utf8_to_wide(std::istream & utf8, std::wstring & res, bool clear = true, int mode = 1); template -bool UTF8ToWide(const char * utf8, size_t utf8_len, StreamType & res, bool clear = true, int mode = 1); // need to be tested +bool utf8_to_wide(const char * utf8, size_t utf8_len, StreamType & res, bool clear = true, int mode = 1); // need to be tested template -bool UTF8ToWide(const char * utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested +bool utf8_to_wide(const char * utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested template -bool UTF8ToWide(const std::string & utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested +bool utf8_to_wide(const std::string & utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested template -bool UTF8ToWide(std::istream & utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested +bool utf8_to_wide(std::istream & utf8, StreamType & res, bool clear = true, int mode = 1); // need to be tested @@ -128,47 +128,45 @@ bool UTF8ToWide(std::istream & utf8, StreamType & res, bool clear = true, int mo /*! converting one int character to UTF-8 */ -size_t IntToUTF8(int z, char * utf8, size_t utf8_max_len); -size_t IntToUTF8(int z, std::string & utf8, bool clear = true); +size_t int_to_utf8(int z, char * utf8, size_t utf8_max_len); +size_t int_to_utf8(int z, std::string & utf8, bool clear = true); template -size_t IntToUTF8(int z, StreamType & utf8); +size_t int_to_utf8(int z, StreamType & utf8); /*! converting a wide string to UTF-8 string */ -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool clear = true, int mode = 1); -bool WideToUTF8(const wchar_t * wide_string, std::string & utf8, bool clear = true, int mode = 1); -bool WideToUTF8(const std::wstring & wide_string, std::string & utf8, bool clear = true, int mode = 1); +bool wide_to_utf8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool clear = true, int mode = 1); +bool wide_to_utf8(const wchar_t * wide_string, std::string & utf8, bool clear = true, int mode = 1); +bool wide_to_utf8(const std::wstring & wide_string, std::string & utf8, bool clear = true, int mode = 1); template -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, int mode = 1); +bool wide_to_utf8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, int mode = 1); template -bool WideToUTF8(const wchar_t * wide_string, StreamType & utf8, int mode = 1); +bool wide_to_utf8(const wchar_t * wide_string, StreamType & utf8, int mode = 1); template -bool WideToUTF8(const std::wstring & wide_string, StreamType & utf8, int mode = 1); +bool wide_to_utf8(const std::wstring & wide_string, StreamType & utf8, int mode = 1); -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); -bool WideToUTF8(const wchar_t * wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); -bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); -// implement template +bool wide_to_utf8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); +bool wide_to_utf8(const wchar_t * wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); +bool wide_to_utf8(const std::wstring & wide_string, char * utf8, size_t utf8_len, size_t & utf8_written, int mode = 1); -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, int mode = 1); -bool WideToUTF8(const wchar_t * wide_string, char * utf8, size_t utf8_len, int mode = 1); -bool WideToUTF8(const std::wstring & wide_string, char * utf8, size_t utf8_len, int mode = 1); -// implement template +bool wide_to_utf8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, int mode = 1); +bool wide_to_utf8(const wchar_t * wide_string, char * utf8, size_t utf8_len, int mode = 1); +bool wide_to_utf8(const std::wstring & wide_string, char * utf8, size_t utf8_len, int mode = 1); template -void WideStreamToUTF8(StreamType & buffer, std::string & utf8, bool clear = true, int mode = 1); // not tested +void wide_stream_to_utf8(StreamType & buffer, std::string & utf8, bool clear = true, int mode = 1); // not tested template -void WideStreamToUTF8(StreamTypeIn & buffer, StreamTypeOut & utf8, int mode = 1); // not tested +void wide_stream_to_utf8(StreamTypeIn & buffer, StreamTypeOut & utf8, int mode = 1); // not tested diff --git a/src/utf8/utf8_private.cpp b/src/utf8/utf8_private.cpp index 1394ebb..54aa3c1 100644 --- a/src/utf8/utf8_private.cpp +++ b/src/utf8/utf8_private.cpp @@ -47,7 +47,7 @@ namespace private_namespace /*! an auxiliary function for converting from UTF-8 string */ -bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res) +bool utf8_to_int_first_octet(unsigned char uz, size_t & len, int & res) { for(len=0 ; (uz & 0x80) != 0 ; ++len) uz <<= 1; @@ -71,7 +71,7 @@ return true; /*! an auxiliary function for converting from UTF-8 string */ -bool UTF8ToInt_AddNextOctet(unsigned char uz, int & res) +bool utf8_to_int_add_next_octet(unsigned char uz, int & res) { if( (uz & 0xc0) != 0x80 ) return false; @@ -93,7 +93,7 @@ return true; returns how many wide characters were used if string_len is greater than 0 then the return value is always greater than zero too */ -size_t WideToInt(const wchar_t * wide_string, size_t string_len, int & z, bool & correct) +size_t wide_to_int(const wchar_t * wide_string, size_t string_len, int & z, bool & correct) { if( string_len == 0 ) { @@ -130,7 +130,7 @@ size_t WideToInt(const wchar_t * wide_string, size_t string_len, int & z, bool & } else { - correct = UTF8_CheckRange(z); + correct = utf8_check_range(z); return 1; } } @@ -144,7 +144,7 @@ size_t WideToInt(const wchar_t * wide_string, size_t string_len, int & z, bool & returns how many wide characters were used if wide_string has at least one character then the return value is always greater than zero too */ -size_t WideToInt(const wchar_t * wide_string, int & z, bool & correct) +size_t wide_to_int(const wchar_t * wide_string, int & z, bool & correct) { size_t min_str_len = 1; @@ -158,7 +158,7 @@ size_t min_str_len = 1; if( *(wide_string+1) != 0 ) min_str_len = 2; -return WideToInt(wide_string, min_str_len, z, correct); +return wide_to_int(wide_string, min_str_len, z, correct); } @@ -177,7 +177,7 @@ return WideToInt(wide_string, min_str_len, z, correct); was_error - will be true if there is an error when converting (there was an incorrect wide character) (was_error will not be true if the utf8 buffer is too small) */ -size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, +size_t wide_one_to_utf8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, size_t & utf8_written, bool & was_utf8_buf_too_small, bool & was_error, int mode) { int z; @@ -186,11 +186,11 @@ size_t chars; utf8_written = 0; was_utf8_buf_too_small = false; - chars = WideToInt(wide_string, string_len, z, correct); + chars = wide_to_int(wide_string, string_len, z, correct); if( correct ) { - utf8_written = IntToUTF8(z, utf8, utf8_len); + utf8_written = int_to_utf8(z, utf8, utf8_len); if( utf8_written == 0 ) was_utf8_buf_too_small = true; @@ -199,7 +199,7 @@ size_t chars; { if( mode == 1 ) { - utf8_written = IntToUTF8(0xFFFD, utf8, utf8_len); // U+FFFD "replacement character" + utf8_written = int_to_utf8(0xFFFD, utf8, utf8_len); // U+FFFD "replacement character" if( utf8_written == 0 ) was_utf8_buf_too_small = true; @@ -219,21 +219,21 @@ return chars; returns how many wide characters were used if string_len is greater than 0 then the return value is always greater than zero too */ -size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode) +size_t wide_one_to_utf8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode) { int z; bool correct; size_t chars; - chars = WideToInt(wide_string, string_len, z, correct); + chars = wide_to_int(wide_string, string_len, z, correct); if( correct ) - correct = IntToUTF8(z, utf8, false) != 0; + correct = int_to_utf8(z, utf8, false) != 0; if( !correct ) { if( mode == 1 ) - IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character" + int_to_utf8(0xFFFD, utf8, false); // U+FFFD "replacement character" was_error = true; } @@ -249,21 +249,21 @@ return chars; returns how many wide characters were used if wide_string has at least one character then the return value is always greater than zero too */ -size_t WideOneToUTF8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode) +size_t wide_one_to_utf8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode) { int z; bool correct; size_t chars; - chars = WideToInt(wide_string, z, correct); + chars = wide_to_int(wide_string, z, correct); if( correct ) - correct = IntToUTF8(z, utf8, false) != 0; + correct = int_to_utf8(z, utf8, false) != 0; if( !correct ) { if( mode == 1 ) - IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character" + int_to_utf8(0xFFFD, utf8, false); // U+FFFD "replacement character" was_error = true; } diff --git a/src/utf8/utf8_private.h b/src/utf8/utf8_private.h index 9b0b7f3..5ea815f 100644 --- a/src/utf8/utf8_private.h +++ b/src/utf8/utf8_private.h @@ -44,26 +44,26 @@ namespace pt { -bool UTF8_CheckRange(int c); -size_t IntToUTF8(int z, char * utf8, size_t utf8_max_len); -size_t IntToUTF8(int z, std::string & utf8, bool clear); -size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct); +bool utf8_check_range(int c); +size_t int_to_utf8(int z, char * utf8, size_t utf8_max_len); +size_t int_to_utf8(int z, std::string & utf8, bool clear); +size_t utf8_to_int(const char * utf8, size_t utf8_len, int & res, bool & correct); namespace private_namespace { -bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res); -bool UTF8ToInt_AddNextOctet(unsigned char uz, int & res); +bool utf8_to_int_first_octet(unsigned char uz, size_t & len, int & res); +bool utf8_to_int_add_next_octet(unsigned char uz, int & res); -size_t WideToInt(const wchar_t * wide_string, size_t string_len, int & z, bool & correct); -size_t WideToInt(const wchar_t * wide_string, int & z, bool & correct); +size_t wide_to_int(const wchar_t * wide_string, size_t string_len, int & z, bool & correct); +size_t wide_to_int(const wchar_t * wide_string, int & z, bool & correct); -size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, +size_t wide_one_to_utf8(const wchar_t * wide_string, size_t string_len, char * utf8, size_t utf8_len, size_t & utf8_written, bool & was_utf8_buf_too_small, bool & was_error, int mode); -size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode); +size_t wide_one_to_utf8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode); -size_t WideOneToUTF8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode); +size_t wide_one_to_utf8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode); /*! @@ -73,21 +73,21 @@ size_t WideOneToUTF8(const wchar_t * wide_string, std::string & utf8, bool & was if string_len is greater than 0 then the return value is always greater than zero too */ template -static size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, bool & was_error, int mode) +static size_t wide_one_to_utf8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, bool & was_error, int mode) { int z; bool correct; size_t chars; - chars = WideToInt(wide_string, string_len, z, correct); + chars = wide_to_int(wide_string, string_len, z, correct); if( correct ) - correct = IntToUTF8(z, utf8) != 0; + correct = int_to_utf8(z, utf8) != 0; if( !correct ) { if( mode == 1 ) - IntToUTF8(0xFFFD, utf8); // U+FFFD "replacement character" + int_to_utf8(0xFFFD, utf8); // U+FFFD "replacement character" was_error = true; } @@ -100,7 +100,7 @@ return chars; an auxiliary function for converting from wide characters to UTF-8 */ template -static size_t WideOneToUTF8(const wchar_t * wide_string, StreamType & utf8, bool & was_error, int mode) +static size_t wide_one_to_utf8(const wchar_t * wide_string, StreamType & utf8, bool & was_error, int mode) { size_t min_str_len = 1; @@ -110,18 +110,18 @@ static size_t WideOneToUTF8(const wchar_t * wide_string, StreamType & utf8, bool if( *(wide_string+1) != 0 ) min_str_len = 2; -return WideOneToUTF8(wide_string, min_str_len, utf8, was_error, mode); +return wide_one_to_utf8(wide_string, min_str_len, utf8, was_error, mode); } // declared in utf8.h, defined in utf8.cpp -size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct); +size_t utf8_to_int(const char * utf8, size_t utf8_len, int & res, bool & correct); template -bool UTF8ToWideGeneric(const char * utf8, size_t utf8_len, int mode, function_type convert_function) +bool utf8_to_wide_generic(const char * utf8, size_t utf8_len, int mode, function_type convert_function) { int z; size_t len; @@ -138,7 +138,7 @@ bool correct, was_error = false; } else { - len = pt::UTF8ToInt(utf8, utf8_len, z, correct); // the len will be different from zero + len = pt::utf8_to_int(utf8, utf8_len, z, correct); // the len will be different from zero } if( !correct ) @@ -163,7 +163,7 @@ return !was_error; template -void IntToWide(int c, StreamType & res) +void int_to_wide(int c, StreamType & res) { if( sizeof(wchar_t)==2 && c>0xffff ) { @@ -183,7 +183,7 @@ void IntToWide(int c, StreamType & res) // FIX ME it is not using surrogate pairs from input stream // and mode parameter template -void WideToUTF8Generic(TextStreamBase & buffer, int mode, function_type write_function) +void wide_to_utf8_generic(TextStreamBase & buffer, int mode, function_type write_function) { char utf8_buffer[256]; std::size_t buffer_len = sizeof(utf8_buffer) / sizeof(char); @@ -200,7 +200,7 @@ void WideToUTF8Generic(TextStreamBase & index = 0; } - index += IntToUTF8(*i, utf8_buffer + index, buffer_len - index); + index += int_to_utf8(*i, utf8_buffer + index, buffer_len - index); ++i; } diff --git a/src/utf8/utf8_templates.h b/src/utf8/utf8_templates.h index 20271a1..d4a5744 100644 --- a/src/utf8/utf8_templates.h +++ b/src/utf8/utf8_templates.h @@ -53,13 +53,13 @@ namespace pt */ // need to be tested template -bool UTF8ToWide(const char * utf8, size_t utf8_len, StreamType & res, bool clear, int mode) +bool utf8_to_wide(const char * utf8, size_t utf8_len, StreamType & res, bool clear, int mode) { if( clear ) res.clear(); - bool status = private_namespace::UTF8ToWideGeneric(utf8, utf8_len, mode, [&res](int c) { - private_namespace::IntToWide(c, res); + bool status = private_namespace::utf8_to_wide_generic(utf8, utf8_len, mode, [&res](int c) { + private_namespace::int_to_wide(c, res); }); return status; @@ -69,29 +69,29 @@ bool UTF8ToWide(const char * utf8, size_t utf8_len, StreamType & res, bool clear template -bool UTF8ToWide(const char * utf8, StreamType & res, bool clear, int mode) +bool utf8_to_wide(const char * utf8, StreamType & res, bool clear, int mode) { size_t utf8_len = 0; while( utf8[utf8_len] != 0 ) utf8_len += 1; -return UTF8ToWide(utf8, utf8_len, res, clear, mode); +return utf8_to_wide(utf8, utf8_len, res, clear, mode); } template -bool UTF8ToWide(const std::string & utf8, StreamType & res, bool clear, int mode) +bool utf8_to_wide(const std::string & utf8, StreamType & res, bool clear, int mode) { - return UTF8ToWide(utf8.c_str(), utf8.size(), res, clear, mode); + return utf8_to_wide(utf8.c_str(), utf8.size(), res, clear, mode); } // need to be tested template -bool UTF8ToWide(std::istream & utf8, StreamType & res, bool clear, int mode) +bool utf8_to_wide(std::istream & utf8, StreamType & res, bool clear, int mode) { int z; bool correct, was_error = false; @@ -99,7 +99,7 @@ bool correct, was_error = false; if( clear ) res.clear(); - while( UTF8ToInt(utf8, z, correct) > 0 ) + while( utf8_to_int(utf8, z, correct) > 0 ) { if( !correct ) { @@ -110,7 +110,7 @@ bool correct, was_error = false; } else { - private_namespace::IntToWide(z, res); + private_namespace::int_to_wide(z, res); } } @@ -137,11 +137,11 @@ return !was_error; zero means that 'z' is an incorrect unicode character */ template -size_t IntToUTF8(int z, StreamType & utf8) +size_t int_to_utf8(int z, StreamType & utf8) { char buf[10]; - size_t len = IntToUTF8(z, buf, sizeof(buf)/sizeof(char)); + size_t len = int_to_utf8(z, buf, sizeof(buf)/sizeof(char)); if( len > 0 ) utf8.write(buf, len); @@ -169,14 +169,14 @@ size_t IntToUTF8(int z, StreamType & utf8) this function returns false if there were some errors when converting */ template -bool WideToUTF8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, int mode) +bool wide_to_utf8(const wchar_t * wide_string, size_t string_len, StreamType & utf8, int mode) { bool was_error = false; size_t chars; while( string_len > 0 ) { - chars = private_namespace::WideOneToUTF8(wide_string, string_len, utf8, was_error, mode); + chars = private_namespace::wide_one_to_utf8(wide_string, string_len, utf8, was_error, mode); wide_string += chars; string_len -= chars; } @@ -203,12 +203,12 @@ return !was_error; this function returns false if there were some errors when converting */ template -bool WideToUTF8(const wchar_t * wide_string, StreamType & utf8, int mode) +bool wide_to_utf8(const wchar_t * wide_string, StreamType & utf8, int mode) { bool was_error = false; while( *wide_string ) - wide_string += private_namespace::WideOneToUTF8(wide_string, utf8, was_error, mode); + wide_string += private_namespace::wide_one_to_utf8(wide_string, utf8, was_error, mode); return !was_error; } @@ -230,21 +230,21 @@ return !was_error; this function returns false if there were some errors when converting */ template -bool WideToUTF8(const std::wstring & wide_string, StreamType & utf8, int mode) +bool wide_to_utf8(const std::wstring & wide_string, StreamType & utf8, int mode) { - return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, mode); + return wide_to_utf8(wide_string.c_str(), wide_string.size(), utf8, mode); } template -void WideStreamToUTF8(StreamType & buffer, std::string & utf8, bool clear, int mode) +void wide_stream_to_utf8(StreamType & buffer, std::string & utf8, bool clear, int mode) { if( clear ) utf8.clear(); - private_namespace::WideToUTF8Generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ + private_namespace::wide_to_utf8_generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ utf8.append(utf8_buffer, buffer_len); }); } @@ -252,9 +252,9 @@ void WideStreamToUTF8(StreamType & buffer, std::string & utf8, bool clear, int m // not tested template -void WideStreamToUTF8(StreamTypeIn & buffer, StreamTypeOut & utf8, int mode) +void wide_stream_to_utf8(StreamTypeIn & buffer, StreamTypeOut & utf8, int mode) { - private_namespace::WideToUTF8Generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ + private_namespace::wide_to_utf8_generic(buffer, mode, [&utf8](const char * utf8_buffer, std::size_t buffer_len){ utf8.write(utf8_buffer, buffer_len); }); } diff --git a/tests/mainoptionsparser.cpp b/tests/mainoptionsparser.cpp index 569b7aa..720f3e8 100644 --- a/tests/mainoptionsparser.cpp +++ b/tests/mainoptionsparser.cpp @@ -134,7 +134,7 @@ void test_mainoptionsparser(size_t len, const char ** argv, const Space & argume std::wstring & err_wstr = parser.get_wrong_option(); std::string err_str; - WideToUTF8(err_wstr, err_str); + wide_to_utf8(err_wstr, err_str); std::string json; space.serialize_to_json_to(json); From abeca010cc5e2d120328c7e29b13b060a22b82f2 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 21 May 2021 00:26:19 +0200 Subject: [PATCH 62/67] fixed: SpaceParser was using space->set_empty_object() when parsing a space and it cleared all values if not an empty object was provided to the set_space() method --- src/space/spaceparser.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/space/spaceparser.cpp b/src/space/spaceparser.cpp index 4839d6a..45c8ba6 100644 --- a/src/space/spaceparser.cpp +++ b/src/space/spaceparser.cpp @@ -407,7 +407,9 @@ void SpaceParser::ParseSpace(Space * space) ReadChar(); // inserting a next character after the space_start char to lastc } - space->set_empty_object(); + if( !space->is_object() ) + space->set_empty_object(); + ParseKeyValuePairs(space); if( need_space_start_character ) @@ -496,9 +498,6 @@ void SpaceParser::ParseFloatingPointValue(Space * space) void SpaceParser::ParseTable(Space * space) { - space->set_empty_table(); - - ReadChar(); // inserting a next character after the table_start char to lastc space->set_empty_table(); ParseValuesList(space); From 82a21f6d8512ea38ddb99989b087b8cadbe0e7d4 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 21 May 2021 01:33:01 +0200 Subject: [PATCH 63/67] removed: SpaceParser::SetSpace(...) methods, now ParseJSON/Space(...) methods take a space as an argument --- src/space/spaceparser.cpp | 129 +++++++++++++------------------------- src/space/spaceparser.h | 42 ++++++------- 2 files changed, 63 insertions(+), 108 deletions(-) diff --git a/src/space/spaceparser.cpp b/src/space/spaceparser.cpp index 45c8ba6..e6ded1f 100644 --- a/src/space/spaceparser.cpp +++ b/src/space/spaceparser.cpp @@ -55,18 +55,6 @@ SpaceParser::SpaceParser() } -void SpaceParser::SetSpace(Space * pspace) -{ - root_space = pspace; -} - - -void SpaceParser::SetSpace(Space & pspace) -{ - root_space = &pspace; -} - - void SpaceParser::SetDefault() { // you can change this separators to what you want @@ -110,17 +98,18 @@ int SpaceParser::get_last_parsed_line() -SpaceParser::Status SpaceParser::ParseJSONFile(const char * file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const char * file_name, Space & out_space, bool clear_space) { reading_from_file = true; parsing_space = false; + root_space = &out_space; file.clear(); file.open(file_name, std::ios_base::binary | std::ios_base::in); if( file ) { - ParseRootSpace(); + ParseRootSpace(clear_space); file.close(); } else @@ -133,44 +122,45 @@ return status; -SpaceParser::Status SpaceParser::ParseJSONFile(const std::string & file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const std::string & file_name, Space & out_space, bool clear_space) { - return ParseJSONFile(file_name.c_str()); + return ParseJSONFile(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSONFile(const wchar_t * file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const wchar_t * file_name, Space & out_space, bool clear_space) { std::string file_name_utf8; wide_to_utf8(file_name, file_name_utf8); - return ParseJSONFile(file_name_utf8.c_str()); + return ParseJSONFile(file_name_utf8.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSONFile(const std::wstring & file_name) +SpaceParser::Status SpaceParser::ParseJSONFile(const std::wstring & file_name, Space & out_space, bool clear_space) { - return ParseJSONFile(file_name.c_str()); + return ParseJSONFile(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpaceFile(const char * file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const char * file_name, Space & out_space, bool clear_space) { reading_from_file = true; parsing_space = true; + root_space = &out_space; file.clear(); file.open(file_name, std::ios_base::binary | std::ios_base::in); if( file ) { - ParseRootSpace(); + ParseRootSpace(clear_space); file.close(); } else @@ -183,126 +173,129 @@ return status; -SpaceParser::Status SpaceParser::ParseSpaceFile(const std::string & file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const std::string & file_name, Space & out_space, bool clear_space) { - return ParseSpaceFile(file_name.c_str()); + return ParseSpaceFile(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpaceFile(const wchar_t * file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const wchar_t * file_name, Space & out_space, bool clear_space) { std::string file_name_utf8; wide_to_utf8(file_name, file_name_utf8); - return ParseSpaceFile(file_name_utf8.c_str()); + return ParseSpaceFile(file_name_utf8.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpaceFile(const std::wstring & file_name) +SpaceParser::Status SpaceParser::ParseSpaceFile(const std::wstring & file_name, Space & out_space, bool clear_space) { - return ParseSpaceFile(file_name.c_str()); + return ParseSpaceFile(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSON(const char * str) +SpaceParser::Status SpaceParser::ParseJSON(const char * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = false; pchar_ascii = str; pchar_unicode = 0; parsing_space = false; + root_space = &out_space; - ParseRootSpace(); + ParseRootSpace(clear_space); -return status; + return status; } -SpaceParser::Status SpaceParser::ParseJSON(const std::string & str) +SpaceParser::Status SpaceParser::ParseJSON(const std::string & str, Space & out_space, bool clear_space) { - return ParseJSON(str.c_str()); + return ParseJSON(str.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSON(const wchar_t * str) +SpaceParser::Status SpaceParser::ParseJSON(const wchar_t * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = true; pchar_unicode = str; pchar_ascii = 0; parsing_space = false; + root_space = &out_space; - ParseRootSpace(); + ParseRootSpace(clear_space); -return status; + return status; } -SpaceParser::Status SpaceParser::ParseJSON(const std::wstring & str) +SpaceParser::Status SpaceParser::ParseJSON(const std::wstring & str, Space & out_space, bool clear_space) { - return ParseJSON(str.c_str()); + return ParseJSON(str.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpace(const char * str) +SpaceParser::Status SpaceParser::ParseSpace(const char * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = false; pchar_ascii = str; pchar_unicode = 0; parsing_space = true; + root_space = &out_space; - ParseRootSpace(); + ParseRootSpace(clear_space); -return status; + return status; } -SpaceParser::Status SpaceParser::ParseSpace(const std::string & str) +SpaceParser::Status SpaceParser::ParseSpace(const std::string & str, Space & out_space, bool clear_space) { - return ParseSpace(str.c_str()); + return ParseSpace(str.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpace(const wchar_t * str) +SpaceParser::Status SpaceParser::ParseSpace(const wchar_t * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = true; pchar_unicode = str; pchar_ascii = 0; parsing_space = true; + root_space = &out_space; - ParseRootSpace(); + ParseRootSpace(clear_space); -return status; + return status; } -SpaceParser::Status SpaceParser::ParseSpace(const std::wstring & str) +SpaceParser::Status SpaceParser::ParseSpace(const std::wstring & str, Space & out_space, bool clear_space) { - return ParseSpace(str.c_str()); + return ParseSpace(str.c_str(), out_space, clear_space); } -void SpaceParser::ParseRootSpace() +void SpaceParser::ParseRootSpace(bool clear_root_space) { line = 1; status = ok; - if( !root_space ) + if( clear_root_space ) { - status = no_space; - return; + root_space->set_empty_object(); } ReadChar(); // put first character to lastc @@ -784,37 +777,6 @@ void SpaceParser::TrimLastWhite(std::wstring & s) } -/* -void SpaceParser::Trim(std::wstring & s) -{ -std::wstring::size_type i; - - if( s.empty() ) - return; - - // looking for white characters at the end - for(i=s.size()-1 ; i>0 && IsWhite(s[i]) ; --i); - - if( i==0 && IsWhite(s[i]) ) - { - // the whole string consists of white characters - s.clear(); - return; - } - - // deleting white characters at the end - if( i != s.size() - 1 ) - s.erase(i+1, std::wstring::npos); - - // looking for white characters at the beginning - for(i=0 ; i Date: Fri, 21 May 2021 04:28:31 +0200 Subject: [PATCH 64/67] removed from SpaceParser: SetDefault(), SkipEmpty(bool skip) and UseEscapeChar(bool escape) methods --- src/space/spaceparser.cpp | 32 ++------------------ src/space/spaceparser.h | 62 +++++---------------------------------- 2 files changed, 11 insertions(+), 83 deletions(-) diff --git a/src/space/spaceparser.cpp b/src/space/spaceparser.cpp index e6ded1f..2e1db62 100644 --- a/src/space/spaceparser.cpp +++ b/src/space/spaceparser.cpp @@ -50,42 +50,16 @@ namespace pt SpaceParser::SpaceParser() { - root_space = 0; - SetDefault(); -} - - -void SpaceParser::SetDefault() -{ - // you can change this separators to what you want - // you shoud not use only white characters here (as expected by IsWhite() method) - // and new line characters ('\n') - separator = ':'; + root_space = nullptr; space_start = '{'; space_end = '}'; - table_start = '['; - table_end = ']'; option_delimiter = ','; - skip_empty = false; - use_escape_char = true; input_as_utf8 = true; } -void SpaceParser::SkipEmpty(bool skip) -{ - skip_empty = skip; -} - - -void SpaceParser::UseEscapeChar(bool escape) -{ - use_escape_char = escape; -} - - -void SpaceParser::UTF8(bool utf) +void SpaceParser::use_utf8(bool utf) { input_as_utf8 = utf; } @@ -1090,7 +1064,7 @@ int SpaceParser::ReadChar() char_was_escaped = false; ReadCharNoEscape(); - if( use_escape_char && lastc == '\\' ) + if( lastc == '\\' ) { char_was_escaped = true; ReadCharNoEscape(); diff --git a/src/space/spaceparser.h b/src/space/spaceparser.h index 6a1d7df..7af36db 100644 --- a/src/space/spaceparser.h +++ b/src/space/spaceparser.h @@ -60,15 +60,6 @@ public: SpaceParser(); - - - /* - setting options of the parser to the default values - utf8 etc. - */ - void SetDefault(); - - /* status of parsing */ @@ -133,33 +124,16 @@ public: */ - /* - if true then empty values and lists, e.g: - option = - option2 = () - will be omitted (not inserted to 'table') - default: false - */ - void SkipEmpty(bool skip); - /* - '\' character is used to escape other characters in a quoted string - so "some \t t\"ext" will produce "some t t"ext" - default: true - */ - void UseEscapeChar(bool escape); - - - /* - if true then the input file or string (char* or std::string) is treated as UTF-8 - default true - - the internal storage for strings is std::wstring so if you call UTF8(false) then - the characters of input string will be simple static_cast<> from char to wchar_t - */ - // rename to use_utf8(bool) - void UTF8(bool utf); + * if true then the input file or string (char* or std::string) is treated as UTF-8 + * default true + * + * the internal storage for strings is std::wstring so if you call set_utf8(false) then + * the characters of input string will be simple static_cast<> from char to wchar_t + * + */ + void use_utf8(bool utf); /* @@ -271,16 +245,6 @@ private: std::ifstream file; - /* - if true then empty lists, e.g: - option = - option2 = () - will be omitted (not inserted to 'table') - default: false - */ - bool skip_empty; - - /* input file is in UTF-8 default: true @@ -289,17 +253,8 @@ private: /* - if true you can use an escape character '\' in quoted values - */ - bool use_escape_char; - - - - /* - * * if parsing_space is false then it means we are parsing JSON format * - * */ bool parsing_space; @@ -347,7 +302,6 @@ private: void SkipLine(); void SkipWhite(); void TrimLastWhite(std::wstring & s); - //void Trim(std::wstring & s); bool IsHexDigit(wchar_t c); int HexToInt(wchar_t c); void ReadUnicodeCodePoint(); From c11aa78335af59104a1f5baedb2d10a4ab6e71f8 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 21 May 2021 04:42:55 +0200 Subject: [PATCH 65/67] changed: names of methods in SpaceParser: PascalCase to snake_case --- src/space/spaceparser.cpp | 270 +++++++++++++++++++------------------- src/space/spaceparser.h | 104 +++++++-------- 2 files changed, 185 insertions(+), 189 deletions(-) diff --git a/src/space/spaceparser.cpp b/src/space/spaceparser.cpp index 2e1db62..a5704f8 100644 --- a/src/space/spaceparser.cpp +++ b/src/space/spaceparser.cpp @@ -72,7 +72,7 @@ int SpaceParser::get_last_parsed_line() -SpaceParser::Status SpaceParser::ParseJSONFile(const char * file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json_file(const char * file_name, Space & out_space, bool clear_space) { reading_from_file = true; parsing_space = false; @@ -83,7 +83,7 @@ SpaceParser::Status SpaceParser::ParseJSONFile(const char * file_name, Space & o if( file ) { - ParseRootSpace(clear_space); + parse_root_space(clear_space); file.close(); } else @@ -96,34 +96,34 @@ return status; -SpaceParser::Status SpaceParser::ParseJSONFile(const std::string & file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json_file(const std::string & file_name, Space & out_space, bool clear_space) { - return ParseJSONFile(file_name.c_str(), out_space, clear_space); + return parse_json_file(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSONFile(const wchar_t * file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json_file(const wchar_t * file_name, Space & out_space, bool clear_space) { std::string file_name_utf8; wide_to_utf8(file_name, file_name_utf8); - return ParseJSONFile(file_name_utf8.c_str(), out_space, clear_space); + return parse_json_file(file_name_utf8.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSONFile(const std::wstring & file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json_file(const std::wstring & file_name, Space & out_space, bool clear_space) { - return ParseJSONFile(file_name.c_str(), out_space, clear_space); + return parse_json_file(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpaceFile(const char * file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space_file(const char * file_name, Space & out_space, bool clear_space) { reading_from_file = true; parsing_space = true; @@ -134,7 +134,7 @@ SpaceParser::Status SpaceParser::ParseSpaceFile(const char * file_name, Space & if( file ) { - ParseRootSpace(clear_space); + parse_root_space(clear_space); file.close(); } else @@ -147,32 +147,32 @@ return status; -SpaceParser::Status SpaceParser::ParseSpaceFile(const std::string & file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space_file(const std::string & file_name, Space & out_space, bool clear_space) { - return ParseSpaceFile(file_name.c_str(), out_space, clear_space); + return parse_space_file(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpaceFile(const wchar_t * file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space_file(const wchar_t * file_name, Space & out_space, bool clear_space) { std::string file_name_utf8; wide_to_utf8(file_name, file_name_utf8); - return ParseSpaceFile(file_name_utf8.c_str(), out_space, clear_space); + return parse_space_file(file_name_utf8.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpaceFile(const std::wstring & file_name, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space_file(const std::wstring & file_name, Space & out_space, bool clear_space) { - return ParseSpaceFile(file_name.c_str(), out_space, clear_space); + return parse_space_file(file_name.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSON(const char * str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json(const char * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = false; @@ -181,19 +181,19 @@ SpaceParser::Status SpaceParser::ParseJSON(const char * str, Space & out_space, parsing_space = false; root_space = &out_space; - ParseRootSpace(clear_space); + parse_root_space(clear_space); return status; } -SpaceParser::Status SpaceParser::ParseJSON(const std::string & str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json(const std::string & str, Space & out_space, bool clear_space) { - return ParseJSON(str.c_str(), out_space, clear_space); + return parse_json(str.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseJSON(const wchar_t * str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json(const wchar_t * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = true; @@ -202,22 +202,22 @@ SpaceParser::Status SpaceParser::ParseJSON(const wchar_t * str, Space & out_spac parsing_space = false; root_space = &out_space; - ParseRootSpace(clear_space); + parse_root_space(clear_space); return status; } -SpaceParser::Status SpaceParser::ParseJSON(const std::wstring & str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_json(const std::wstring & str, Space & out_space, bool clear_space) { - return ParseJSON(str.c_str(), out_space, clear_space); + return parse_json(str.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpace(const char * str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space(const char * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = false; @@ -226,19 +226,19 @@ SpaceParser::Status SpaceParser::ParseSpace(const char * str, Space & out_space, parsing_space = true; root_space = &out_space; - ParseRootSpace(clear_space); + parse_root_space(clear_space); return status; } -SpaceParser::Status SpaceParser::ParseSpace(const std::string & str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space(const std::string & str, Space & out_space, bool clear_space) { - return ParseSpace(str.c_str(), out_space, clear_space); + return parse_space(str.c_str(), out_space, clear_space); } -SpaceParser::Status SpaceParser::ParseSpace(const wchar_t * str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space(const wchar_t * str, Space & out_space, bool clear_space) { reading_from_file = false; reading_from_wchar_string = true; @@ -247,22 +247,22 @@ SpaceParser::Status SpaceParser::ParseSpace(const wchar_t * str, Space & out_spa parsing_space = true; root_space = &out_space; - ParseRootSpace(clear_space); + parse_root_space(clear_space); return status; } -SpaceParser::Status SpaceParser::ParseSpace(const std::wstring & str, Space & out_space, bool clear_space) +SpaceParser::Status SpaceParser::parse_space(const std::wstring & str, Space & out_space, bool clear_space) { - return ParseSpace(str.c_str(), out_space, clear_space); + return parse_space(str.c_str(), out_space, clear_space); } -void SpaceParser::ParseRootSpace(bool clear_root_space) +void SpaceParser::parse_root_space(bool clear_root_space) { line = 1; status = ok; @@ -272,24 +272,24 @@ void SpaceParser::ParseRootSpace(bool clear_root_space) root_space->set_empty_object(); } - ReadChar(); // put first character to lastc + read_char(); // put first character to lastc if( parsing_space ) { separator = '='; table_start = '('; table_end = ')'; - ParseSpace(root_space); + parse_space(root_space); } else { separator = ':'; table_start = '['; table_end = ']'; - Parse(root_space, false, false); + parse(root_space, false, false); } - SkipWhite(); + skip_white(); if( lastc != -1 ) status = syntax_error; @@ -298,27 +298,27 @@ void SpaceParser::ParseRootSpace(bool clear_root_space) } -void SpaceParser::Parse(Space * space, bool is_object_value, bool is_table_value) +void SpaceParser::parse(Space * space, bool is_object_value, bool is_table_value) { - SkipWhite(); + skip_white(); if( lastc == space_start ) { - ParseSpace(space); + parse_space(space); } else if( lastc == table_start ) { - ParseTable(space); + parse_table(space); } else if( lastc == '"' ) // IMPROVEME define a variable { - ParseTextValue(space); + parse_text_value(space); } else { - ReadStringValue(token, is_object_value, is_table_value); + read_string_value(token, is_object_value, is_table_value); if( token == L"null" ) { @@ -337,12 +337,12 @@ void SpaceParser::Parse(Space * space, bool is_object_value, bool is_table_value else if( is_integer_token() ) { - ParseIntegerValue(space); + parse_integer_value(space); } else if( is_floating_point_token() ) { - ParseFloatingPointValue(space); + parse_floating_point_value(space); } else { @@ -362,7 +362,7 @@ void SpaceParser::Parse(Space * space, bool is_object_value, bool is_table_value -void SpaceParser::ParseSpace(Space * space) +void SpaceParser::parse_space(Space * space) { /* * in Space format in global namespace the space start character is not required @@ -371,19 +371,19 @@ void SpaceParser::ParseSpace(Space * space) if( need_space_start_character ) { - ReadChar(); // inserting a next character after the space_start char to lastc + read_char(); // inserting a next character after the space_start char to lastc } if( !space->is_object() ) space->set_empty_object(); - ParseKeyValuePairs(space); + parse_key_value_pairs(space); if( need_space_start_character ) { if( lastc == space_end ) { - ReadChar(); + read_char(); } else { @@ -396,19 +396,19 @@ void SpaceParser::ParseSpace(Space * space) -void SpaceParser::ParseTextValue(Space * space) +void SpaceParser::parse_text_value(Space * space) { space->set_empty_wstring(); std::wstring * str = space->get_wstr(); if( parsing_space ) - ReadMultilineTokenQuoted(*str); + read_multiline_token_quoted(*str); else - ReadTokenQuoted(*str); + read_token_quoted(*str); } -void SpaceParser::ParseIntegerValue(Space * space) +void SpaceParser::parse_integer_value(Space * space) { const wchar_t * after_str = nullptr; bool was_overflow = false; @@ -440,7 +440,7 @@ void SpaceParser::ParseIntegerValue(Space * space) } -void SpaceParser::ParseFloatingPointValue(Space * space) +void SpaceParser::parse_floating_point_value(Space * space) { wchar_t * after_str = nullptr; double val = wcstod(token.c_str(), &after_str); @@ -463,15 +463,15 @@ void SpaceParser::ParseFloatingPointValue(Space * space) -void SpaceParser::ParseTable(Space * space) +void SpaceParser::parse_table(Space * space) { - ReadChar(); // inserting a next character after the table_start char to lastc + read_char(); // inserting a next character after the table_start char to lastc space->set_empty_table(); - ParseValuesList(space); + parse_values_list(space); if( lastc == table_end ) { - ReadChar(); + read_char(); } else { @@ -482,25 +482,25 @@ void SpaceParser::ParseTable(Space * space) -void SpaceParser::ParseKeyValuePairs(Space * space) +void SpaceParser::parse_key_value_pairs(Space * space) { bool is_first = true; - SkipWhite(); + skip_white(); while( status == ok && lastc != space_end && lastc != -1 ) { if( !is_first ) { - SkipWhite(); + skip_white(); if( lastc == option_delimiter ) { - ReadChar(); // inserting a next character after the option_delimiter to lastc + read_char(); // inserting a next character after the option_delimiter to lastc if( parsing_space ) { // in space format a space_end character is allowed to be after the last table item - SkipWhite(); + skip_white(); if( lastc == space_end ) break; @@ -516,24 +516,24 @@ void SpaceParser::ParseKeyValuePairs(Space * space) if( status == ok ) { - ReadKey(); + read_key(); if( status == ok ) { - SkipWhite(); + skip_white(); if( lastc == separator ) { - ReadChar(); // inserting a next character after the separator to lastc + read_char(); // inserting a next character after the separator to lastc Space & new_space = space->add(token.c_str(), new Space()); - Parse(&new_space, true, false); + parse(&new_space, true, false); } else if( parsing_space && lastc == space_start ) { Space & new_space = space->add_child_space(token.c_str()); - ParseSpace(&new_space); + parse_space(&new_space); } else { @@ -543,32 +543,32 @@ void SpaceParser::ParseKeyValuePairs(Space * space) } is_first = false; - SkipWhite(); + skip_white(); } } -void SpaceParser::ParseValuesList(Space * space) +void SpaceParser::parse_values_list(Space * space) { bool is_first = true; - SkipWhite(); + skip_white(); while( status == ok && lastc != table_end && lastc != -1 ) { if( !is_first ) { - SkipWhite(); + skip_white(); if( lastc == option_delimiter ) // may add a new delimiter for tables? default the same as for objects... { - ReadChar(); // inserting a next character after the delimiter + read_char(); // inserting a next character after the delimiter if( parsing_space ) { // in space format a table_end character is allowed to be after the last table item - SkipWhite(); + skip_white(); if( lastc == table_end ) break; @@ -585,11 +585,11 @@ void SpaceParser::ParseValuesList(Space * space) if( status == ok ) { Space * new_space = &space->add(new Space()); - Parse(new_space, false, true); + parse(new_space, false, true); } is_first = false; - SkipWhite(); + skip_white(); } } @@ -686,14 +686,14 @@ bool SpaceParser::is_floating_point_token() -bool SpaceParser::IsWhite(int c) +bool SpaceParser::is_white(int c) { // 13 (\r) is at the end of a line in a dos file \r\n // 160 is an unbreakable space if( c==' ' || c=='\t' || c==13 || c==160 || c==10 ) return true; -return false; + return false; } @@ -706,41 +706,41 @@ bool SpaceParser::is_alfa_numeric_char(int c) } -void SpaceParser::SkipLine() +void SpaceParser::skip_line() { while( lastc != -1 && (char_was_escaped || lastc != '\n') ) - ReadChar(); + read_char(); } -void SpaceParser::SkipWhite() +void SpaceParser::skip_white() { if( parsing_space ) { - while( IsWhite(lastc) || (!char_was_escaped && lastc == '#') ) + while( is_white(lastc) || (!char_was_escaped && lastc == '#') ) { if( lastc == '#' ) - SkipLine(); + skip_line(); else - ReadChar(); + read_char(); } } else { - while( IsWhite(lastc) ) + while( is_white(lastc) ) { - ReadChar(); + read_char(); } } } -void SpaceParser::TrimLastWhite(std::wstring & s) +void SpaceParser::trim_last_white(std::wstring & s) { std::wstring::size_type i; - for(i=s.size() ; i>0 && IsWhite(s[i-1]) ; --i) + for(i=s.size() ; i>0 && is_white(s[i-1]) ; --i) { } @@ -752,86 +752,86 @@ void SpaceParser::TrimLastWhite(std::wstring & s) -void SpaceParser::ReadTokenUntilDelimiter(std::wstring & token, int delimiter1, int delimiter2) +void SpaceParser::read_token_until_delimiter(std::wstring & token, int delimiter1, int delimiter2) { token.clear(); while( lastc != -1 && (char_was_escaped || (lastc != '\n' && lastc != '#' && lastc != delimiter1 && lastc != delimiter2)) ) { token += static_cast(lastc); - ReadChar(); + read_char(); } - TrimLastWhite(token); + trim_last_white(token); } -void SpaceParser::ReadAlfaNumericToken(std::wstring & token) +void SpaceParser::read_alfa_numeric_token(std::wstring & token) { token.clear(); while( is_alfa_numeric_char(lastc) ) { token += static_cast(lastc); - ReadChar(); + read_char(); } } -void SpaceParser::ReadStringValue(std::wstring & token, bool is_object_value, bool is_table_value) +void SpaceParser::read_string_value(std::wstring & token, bool is_object_value, bool is_table_value) { if( parsing_space ) { if( is_object_value ) { - ReadTokenUntilDelimiter(token, space_end, -1); + read_token_until_delimiter(token, space_end, -1); } else if( is_table_value ) { - ReadTokenUntilDelimiter(token, table_end, option_delimiter); + read_token_until_delimiter(token, table_end, option_delimiter); } else { - ReadTokenUntilDelimiter(token, -1, -1); + read_token_until_delimiter(token, -1, -1); } } else { - ReadAlfaNumericToken(token); + read_alfa_numeric_token(token); } } -void SpaceParser::ReadSpaceFieldToken(std::wstring & token) +void SpaceParser::read_space_field_token(std::wstring & token) { token.clear(); while( lastc != -1 && (char_was_escaped || (lastc != separator && lastc != 10 && lastc != space_start && lastc != '#' )) ) { token += static_cast(lastc); - ReadChar(); + read_char(); } - TrimLastWhite(token); + trim_last_white(token); } // IMPROVEME in JSON we should not allow non-escaped a new line character -void SpaceParser::ReadTokenQuoted(std::wstring & token) +void SpaceParser::read_token_quoted(std::wstring & token) { token.clear(); - ReadChar(); // skipping the first quotation mark + read_char(); // skipping the first quotation mark while( lastc != -1 && (char_was_escaped || (lastc != '"' && lastc != 10)) ) { token += static_cast(lastc); - ReadChar(); + read_char(); } if( !char_was_escaped && lastc == '"' ) { - ReadChar(); // skipping the last quotation mark + read_char(); // skipping the last quotation mark } else { @@ -840,20 +840,20 @@ void SpaceParser::ReadTokenQuoted(std::wstring & token) } -void SpaceParser::ReadMultilineTokenQuoted(std::wstring & token) +void SpaceParser::read_multiline_token_quoted(std::wstring & token) { token.clear(); - ReadChar(); // skipping the first quotation mark + read_char(); // skipping the first quotation mark while( lastc != -1 && (char_was_escaped || lastc != '"') ) { token += static_cast(lastc); - ReadChar(); + read_char(); } if( !char_was_escaped && lastc == '"' ) { - ReadChar(); // skipping the last quotation mark + read_char(); // skipping the last quotation mark } else { @@ -866,26 +866,26 @@ void SpaceParser::ReadMultilineTokenQuoted(std::wstring & token) * this method is used to read the field name (key) in an object * or to read the space child name (used in Space format) */ -void SpaceParser::ReadKey() +void SpaceParser::read_key() { - SkipWhite(); + skip_white(); if( parsing_space ) { if( lastc == '"' ) { - ReadMultilineTokenQuoted(token); + read_multiline_token_quoted(token); } else { - ReadSpaceFieldToken(token); + read_space_field_token(token); } } else { if( lastc == '"' ) { - ReadTokenQuoted(token); + read_token_quoted(token); } else { @@ -897,7 +897,7 @@ void SpaceParser::ReadKey() -int SpaceParser::ReadUTF8Char() +int SpaceParser::read_utf8_char() { int c; bool correct; @@ -923,7 +923,7 @@ return lastc; -int SpaceParser::ReadASCIIChar() +int SpaceParser::read_ascii_char() { lastc = file.get(); @@ -936,7 +936,7 @@ return lastc; -int SpaceParser::ReadCharFromWcharString() +int SpaceParser::read_char_from_wchar_string() { if( *pchar_unicode == 0 ) lastc = -1; @@ -950,7 +950,7 @@ return lastc; } -int SpaceParser::ReadCharFromUTF8String() +int SpaceParser::read_char_from_utf8_string() { int c; bool correct; @@ -975,7 +975,7 @@ return lastc; } -int SpaceParser::ReadCharFromAsciiString() +int SpaceParser::read_char_from_ascii_string() { if( *pchar_ascii == 0 ) lastc = -1; @@ -989,32 +989,32 @@ return lastc; } -int SpaceParser::ReadCharNoEscape() +int SpaceParser::read_char_no_escape() { if( reading_from_file ) { if( input_as_utf8 ) - return ReadUTF8Char(); + return read_utf8_char(); else - return ReadASCIIChar(); + return read_ascii_char(); } else { if( reading_from_wchar_string ) { - return ReadCharFromWcharString(); + return read_char_from_wchar_string(); } else { if( input_as_utf8 ) - return ReadCharFromUTF8String(); + return read_char_from_utf8_string(); else - return ReadCharFromAsciiString(); + return read_char_from_ascii_string(); } } } -bool SpaceParser::IsHexDigit(wchar_t c) +bool SpaceParser::is_hex_digit(wchar_t c) { return ((c>='0' && c<='9') || (c>='a' && c<='f') || @@ -1022,7 +1022,7 @@ bool SpaceParser::IsHexDigit(wchar_t c) } -int SpaceParser::HexToInt(wchar_t c) +int SpaceParser::hex_to_int(wchar_t c) { if( c>='0' && c<='9' ) return c - '0'; @@ -1037,37 +1037,37 @@ return 0; } -void SpaceParser::ReadUnicodeCodePoint() +void SpaceParser::read_unicode_code_point() { wchar_t c; int value = 0; for(int i=0 ; i<4 ; ++i) { - c = ReadCharNoEscape(); + c = read_char_no_escape(); - if( !IsHexDigit(c) ) + if( !is_hex_digit(c) ) { status = syntax_error; return; } - value = (value << 4) | HexToInt(c); + value = (value << 4) | hex_to_int(c); } lastc = (wchar_t)value; } -int SpaceParser::ReadChar() +int SpaceParser::read_char() { char_was_escaped = false; - ReadCharNoEscape(); + read_char_no_escape(); if( lastc == '\\' ) { char_was_escaped = true; - ReadCharNoEscape(); + read_char_no_escape(); switch(lastc) { @@ -1077,7 +1077,7 @@ int SpaceParser::ReadChar() case 'n': lastc = '\n'; break; case 'b': lastc = 0x08; break; case 'f': lastc = 0x0c; break; - case 'u': ReadUnicodeCodePoint(); break; + case 'u': read_unicode_code_point(); break; // "in other cases we return the last character, so two \\ returns one \ " } } diff --git a/src/space/spaceparser.h b/src/space/spaceparser.h index 7af36db..8b89772 100644 --- a/src/space/spaceparser.h +++ b/src/space/spaceparser.h @@ -67,7 +67,7 @@ public: /* - the last status of parsing, set by Parse() methods + the last status of parsing, set by parse() methods */ Status status; @@ -78,48 +78,48 @@ public: main methods used to parse a JSON file file_name is the path to a file */ - Status ParseJSONFile(const char * file_name, Space & out_space, bool clear_space = true); - Status ParseJSONFile(const std::string & file_name, Space & out_space, bool clear_space = true); - Status ParseJSONFile(const wchar_t * file_name, Space & out_space, bool clear_space = true); - Status ParseJSONFile(const std::wstring & file_name, Space & out_space, bool clear_space = true); + Status parse_json_file(const char * file_name, Space & out_space, bool clear_space = true); + Status parse_json_file(const std::string & file_name, Space & out_space, bool clear_space = true); + Status parse_json_file(const wchar_t * file_name, Space & out_space, bool clear_space = true); + Status parse_json_file(const std::wstring & file_name, Space & out_space, bool clear_space = true); /* main methods used to parse a Space file file_name is the path to a file */ - Status ParseSpaceFile(const char * file_name, Space & out_space, bool clear_space = true); - Status ParseSpaceFile(const std::string & file_name, Space & out_space, bool clear_space = true); - Status ParseSpaceFile(const wchar_t * file_name, Space & out_space, bool clear_space = true); - Status ParseSpaceFile(const std::wstring & file_name, Space & out_space, bool clear_space = true); + Status parse_space_file(const char * file_name, Space & out_space, bool clear_space = true); + Status parse_space_file(const std::string & file_name, Space & out_space, bool clear_space = true); + Status parse_space_file(const wchar_t * file_name, Space & out_space, bool clear_space = true); + Status parse_space_file(const std::wstring & file_name, Space & out_space, bool clear_space = true); /* main methods used to parse str - input string (either 8bit ascii or UTF-8 -- see UTF8() method) */ - Status ParseJSON(const char * str, Space & out_space, bool clear_space = true); - Status ParseJSON(const std::string & str, Space & out_space, bool clear_space = true); + Status parse_json(const char * str, Space & out_space, bool clear_space = true); + Status parse_json(const std::string & str, Space & out_space, bool clear_space = true); /* main methods used to parse here input string is always in unicode (wide characters) */ - Status ParseJSON(const wchar_t * str, Space & out_space, bool clear_space = true); - Status ParseJSON(const std::wstring & str, Space & out_space, bool clear_space = true); + Status parse_json(const wchar_t * str, Space & out_space, bool clear_space = true); + Status parse_json(const std::wstring & str, Space & out_space, bool clear_space = true); - Status ParseSpace(const char * str, Space & out_space, bool clear_space = true); - Status ParseSpace(const std::string & str, Space & out_space, bool clear_space = true); - Status ParseSpace(const wchar_t * str, Space & out_space, bool clear_space = true); - Status ParseSpace(const std::wstring & str, Space & out_space, bool clear_space = true); + Status parse_space(const char * str, Space & out_space, bool clear_space = true); + Status parse_space(const std::string & str, Space & out_space, bool clear_space = true); + Status parse_space(const wchar_t * str, Space & out_space, bool clear_space = true); + Status parse_space(const std::wstring & str, Space & out_space, bool clear_space = true); /* - * add two args Parse method - * Status Parse(const char * str, Space & output_space); + * add two args parse method + * Status parse(const char * str, Space & output_space); * */ @@ -160,7 +160,7 @@ private: int line; /* - true if Parse() method was called + true if parse() method was called false if ParseString() was called */ bool reading_from_file; @@ -260,51 +260,47 @@ private: - void ParseRootSpace(bool clear_root_space); - void Parse(Space * space, bool is_object_value, bool is_table_value); - void ParseSpace(Space * space); - void ParseTable(Space * space); + void parse_root_space(bool clear_root_space); + void parse(Space * space, bool is_object_value, bool is_table_value); + void parse_space(Space * space); + void parse_table(Space * space); - void ParseKeyValuePairs(Space * space); - void ParseValuesList(Space * space); + void parse_key_value_pairs(Space * space); + void parse_values_list(Space * space); - void ReadKey(); - - void ParseTextValue(Space * space); - void ParseIntegerValue(Space * space); - void ParseFloatingPointValue(Space * space); + void read_key(); + void parse_text_value(Space * space); + void parse_integer_value(Space * space); + void parse_floating_point_value(Space * space); bool is_alfa_numeric_char(int c); - void ReadTokenUntilDelimiter(std::wstring & token, int delimiter1, int delimiter2); - void ReadAlfaNumericToken(std::wstring & token); - void ReadStringValue(std::wstring & token, bool is_object_value, bool is_table_value); - + void read_token_until_delimiter(std::wstring & token, int delimiter1, int delimiter2); + void read_alfa_numeric_token(std::wstring & token); + void read_string_value(std::wstring & token, bool is_object_value, bool is_table_value); bool is_integer_token(); bool is_floating_point_token(); - void ReadSpaceFieldToken(std::wstring & token); - void ReadTokenQuoted(std::wstring & token); - void ReadMultilineTokenQuoted(std::wstring & token); + void read_space_field_token(std::wstring & token); + void read_token_quoted(std::wstring & token); + void read_multiline_token_quoted(std::wstring & token); - - - int ReadUTF8Char(); - int ReadASCIIChar(); - int ReadCharFromWcharString(); - int ReadCharFromUTF8String(); - int ReadCharFromAsciiString(); - int ReadCharNoEscape(); - int ReadChar(); - bool IsWhite(int c); - void SkipLine(); - void SkipWhite(); - void TrimLastWhite(std::wstring & s); - bool IsHexDigit(wchar_t c); - int HexToInt(wchar_t c); - void ReadUnicodeCodePoint(); + int read_utf8_char(); + int read_ascii_char(); + int read_char_from_wchar_string(); + int read_char_from_utf8_string(); + int read_char_from_ascii_string(); + int read_char_no_escape(); + int read_char(); + bool is_white(int c); + void skip_line(); + void skip_white(); + void trim_last_white(std::wstring & s); + bool is_hex_digit(wchar_t c); + int hex_to_int(wchar_t c); + void read_unicode_code_point(); }; From 5ce36ea84450cfea52a5ae83ad97c4d62061f424 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 21 May 2021 17:13:11 +0200 Subject: [PATCH 66/67] changed the way how child_spaces are created in Space class - removed child_spaces and name pointers - now a table with child spaces is created under "child_spaces" object field - a name of the child space is stored in "name" field of the child object added methods for manipulating with child spaces: TableType * find_child_space_table() bool child_spaces_empty() size_t child_spaces_size() Space * find_child_space(size_t table_index) Space & add_child_space(const wchar_t * space_name) Space & add_child_space(const std::wstring & space_name) std::wstring * find_child_space_name() std::wstring get_child_space_name() bool is_child_space_name(const wchar_t * name) added additional methods: size_t str_size() size_t wstr_size() size_t object_size() size_t table_size() --- src/space/space.cpp | 343 +++++++++++++++++++++++++++++--------------- src/space/space.h | 98 ++++++------- 2 files changed, 272 insertions(+), 169 deletions(-) diff --git a/src/space/space.cpp b/src/space/space.cpp index f4157ad..a70dc0e 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -36,7 +36,6 @@ */ #include -#include #include "space.h" #include "utf8/utf8.h" #include "convert/convert.h" @@ -81,8 +80,6 @@ Space & Space::operator=(Space && space) Space::~Space() { remove_value(); - remove_child_spaces(); - remove_space_name(); } @@ -194,6 +191,54 @@ void Space::clear() +size_t Space::str_size() const +{ + if( is_str() ) + { + return value.value_string.size(); + } + + return 0; +} + + +size_t Space::wstr_size() const +{ + if( is_wstr() ) + { + return value.value_wstring.size(); + } + + return 0; +} + + +size_t Space::object_size() const +{ + if( is_object() ) + { + return value.value_object.size(); + } + + return 0; +} + + +size_t Space::table_size() const +{ + if( is_table() ) + { + return value.value_table.size(); + } + + return 0; +} + + + + + + void Space::set_null() { initialize_value_null_if_needed(); @@ -678,21 +723,6 @@ Space & Space::add_empty_space(const std::wstring & field) -Space & Space::add_child_space(const wchar_t * space_name) -{ - initialize_child_spaces_if_needed(); - - child_spaces->push_back(new Space()); - Space * last_space = child_spaces->back(); - - last_space->initialize_space_name_if_needed(); - last_space->name->append(space_name); - - return *last_space; -} - - - bool Space::is_null() const { return type == type_null; @@ -1884,31 +1914,143 @@ bool Space::has_value(const wchar_t * field, const std::wstring & val) const +const Space * Space::find_child_space_const(const wchar_t * name) const +{ + const TableType * child_table = find_child_space_table(); + + if( child_table ) + { + for(const Space & space : *child_table) + { + if( space.is_equal(child_spaces_name, name) ) + { + return &space; + } + } + } + + return nullptr; +} + + + +const Space * Space::find_child_space_const(size_t table_index) const +{ + const TableType * child_table = find_child_space_table(); + + if( child_table && table_index < child_table->size() ) + { + return (*child_table)[table_index]; + } + + return nullptr; +} + + + +Space::TableType * Space::find_child_space_table() +{ + return get_table(child_spaces_field_table_name); +} + + +const Space::TableType * Space::find_child_space_table() const +{ + return get_table(child_spaces_field_table_name); +} + + +bool Space::child_spaces_empty() const +{ + const TableType * child_table = find_child_space_table(); + + if( child_table ) + { + return child_table->empty(); + } + + return true; +} + +size_t Space::child_spaces_size() const +{ + const TableType * child_table = find_child_space_table(); + + if( child_table ) + { + return child_table->size(); + } + + return 0; +} + Space * Space::find_child_space(const wchar_t * name) { - return find_child_space_generic(name); + return const_cast(find_child_space_const(name)); } + Space * Space::find_child_space(const std::wstring & name) { - return find_child_space_generic(name); + return find_child_space(name.c_str()); } const Space * Space::find_child_space(const wchar_t * name) const { - return find_child_space_generic(name); + return find_child_space_const(name); } const Space * Space::find_child_space(const std::wstring & name) const { - return find_child_space_generic(name); + return find_child_space(name.c_str()); } +Space * Space::find_child_space(size_t table_index) +{ + return const_cast(find_child_space_const(table_index)); +} + +const Space * Space::find_child_space(size_t table_index) const +{ + return find_child_space_const(table_index); +} + + +Space & Space::add_child_space() +{ + initialize_child_spaces_if_needed(); + + TableType * child_table = find_child_space_table(); + child_table->push_back(new Space()); + + return child_table->back(); +} + + +Space & Space::add_child_space(const wchar_t * space_name) +{ + initialize_child_spaces_if_needed(); + + TableType * child_table = find_child_space_table(); + child_table->push_back(new Space()); + Space * last_space = child_table->back(); + last_space->add(child_spaces_name, space_name); + + return *last_space; +} + + +Space & Space::add_child_space(const std::wstring & space_name) +{ + return add_child_space(space_name.c_str()); +} + + Space & Space::find_add_child_space(const wchar_t * name) { Space * space = find_child_space(name); @@ -1928,19 +2070,62 @@ Space & Space::find_add_child_space(const std::wstring & name) } +std::wstring * Space::find_child_space_name() +{ + return get_wstr(child_spaces_name); +} + + +const std::wstring * Space::find_child_space_name() const +{ + return get_wstr(child_spaces_name); +} + + +std::wstring Space::get_child_space_name() const +{ + const std::wstring * name = find_child_space_name(); + + if( name ) + { + return *name; + } + else + { + return std::wstring(); + } +} + + + +bool Space::is_child_space_name(const wchar_t * name) const +{ + return is_equal(child_spaces_name, name); +} + + +bool Space::is_child_space_name(const std::wstring & name) const +{ + return is_equal(child_spaces_name, name.c_str()); +} + + + + void Space::remove_child_space(const wchar_t * name) { - if( child_spaces ) - { - for(size_t i=0 ; isize() ; ) - { - Space * child = (*child_spaces)[i]; + TableType * child_table = find_child_space_table(); - if( child->name && (*child->name) == name ) + if( child_table ) + { + for(size_t i=0 ; isize() ; ) + { + Space * child = (*child_table)[i]; + + if( child->is_equal(child_spaces_name, name) ) { delete child; - child = nullptr; - child_spaces->erase(child_spaces->begin() + i); + child_table->erase(child_table->begin() + i); } else { @@ -1958,13 +2143,13 @@ void Space::remove_child_space(const std::wstring & name) void Space::remove_child_space(size_t index) { - if( child_spaces && index < child_spaces->size() ) - { - Space * child = (*child_spaces)[index]; - delete child; - child = nullptr; + TableType * child_table = find_child_space_table(); - child_spaces->erase(child_spaces->begin() + index); + if( child_table && index < child_table->size() ) + { + Space * child = (*child_table)[index]; + delete child; + child_table->erase(child_table->begin() + index); } } @@ -2022,46 +2207,10 @@ void Space::copy_value_from(const Space & space) } -void Space::copy_child_spaces_from(const Space & space) -{ - if( space.child_spaces ) - { - initialize_child_spaces_if_needed(); - child_spaces->clear(); - - for(size_t i = 0 ; i < space.child_spaces->size() ; ++i) - { - child_spaces->push_back(new Space((*space.child_spaces)[i])); - } - } - else - if( child_spaces ) - { - remove_child_spaces(); - } -} - - -void Space::copy_space_name_from(const Space & space) -{ - if( space.name ) - { - initialize_space_name_if_needed(); - *name = *space.name; - } - else - if( name ) - { - remove_space_name(); - } -} - void Space::copy_from(const Space & space) { copy_value_from(space); - copy_child_spaces_from(space); - copy_space_name_from(space); } @@ -2126,9 +2275,6 @@ void Space::move_from(Space && space) { move_value_from(std::move(space)); space.type = Type::type_null; - - std::swap(child_spaces, space.child_spaces); - std::swap(name, space.name); } @@ -2137,8 +2283,6 @@ void Space::move_from(Space && space) void Space::initialize() { type = type_null; - child_spaces = nullptr; - name = nullptr; } void Space::initialize_value_null_if_needed() @@ -2300,18 +2444,17 @@ void Space::initialize_value_table_if_needed(TableType && tab) void Space::initialize_child_spaces_if_needed() { - if( child_spaces == nullptr ) + Space * child_spaces = get_object_field(child_spaces_field_table_name); + + if( child_spaces ) { - child_spaces = new TableType(); + if( !child_spaces->is_table() ) + child_spaces->set_empty_table(); } -} - - -void Space::initialize_space_name_if_needed() -{ - if( name == nullptr ) + else { - name = new std::wstring(); + Space & new_child_spaces = add_empty_space(child_spaces_field_table_name); + new_child_spaces.set_empty_table(); } } @@ -2396,34 +2539,6 @@ void Space::remove_value_table() } -void Space::remove_child_spaces() -{ - if( child_spaces ) - { - for(size_t i = 0 ; i < child_spaces->size() ; ++i) - { - delete (*child_spaces)[i]; - (*child_spaces)[i] = nullptr; - } - - delete child_spaces; - child_spaces = nullptr; - } -} - -void Space::remove_space_name() -{ - if( name ) - { - delete name; - name = nullptr; - } -} - - - } // namespace - - diff --git a/src/space/space.h b/src/space/space.h index 96dea3b..8cba9f2 100644 --- a/src/space/space.h +++ b/src/space/space.h @@ -135,6 +135,9 @@ public: typedef std::map ObjectType; typedef std::vector TableType; + constexpr static const wchar_t * child_spaces_field_table_name = L"child_spaces"; + constexpr static const wchar_t * child_spaces_name = L"name"; + enum Escape { no_escape, @@ -179,10 +182,6 @@ public: Type type; Value value; - std::wstring * name; - TableType * child_spaces; - - Space(); Space(const Space & space); @@ -211,6 +210,12 @@ public: void clear(); + size_t str_size() const; + size_t wstr_size() const; + size_t object_size() const; + size_t table_size() const; + + // set a new value void set_null(); void set_empty_string(); @@ -576,16 +581,35 @@ public: // for child spaces (used only in Space format) - Space * find_child_space(const wchar_t * name); - Space * find_child_space(const std::wstring & name); + TableType * find_child_space_table(); + const TableType * find_child_space_table() const; + + bool child_spaces_empty() const; + size_t child_spaces_size() const; + + Space * find_child_space(const wchar_t * name); + Space * find_child_space(const std::wstring & name); const Space * find_child_space(const wchar_t * name) const; const Space * find_child_space(const std::wstring & name) const; + Space * find_child_space(size_t table_index); + const Space * find_child_space(size_t table_index) const; + + Space & add_child_space(); Space & add_child_space(const wchar_t * space_name); + Space & add_child_space(const std::wstring & space_name); Space & find_add_child_space(const wchar_t * name); Space & find_add_child_space(const std::wstring & name); + std::wstring * find_child_space_name(); + const std::wstring * find_child_space_name() const; + + std::wstring get_child_space_name() const; + + bool is_child_space_name(const wchar_t * name) const; + bool is_child_space_name(const std::wstring & name) const; + void remove_child_space(const wchar_t * name); void remove_child_space(const std::wstring & name); void remove_child_space(size_t index); @@ -739,44 +763,6 @@ protected: } - template - Space * find_child_space_generic(const ArgType & name) - { - if( child_spaces ) - { - for(size_t i = 0 ; i < child_spaces->size() ; ++i) - { - Space * space = (*child_spaces)[i]; - - if( space->name && *space->name == name ) - { - return space; - } - } - } - - return nullptr; - } - - - template - Space * find_child_space_generic(const ArgType & name) const - { - if( child_spaces ) - { - for(size_t i = 0 ; i < child_spaces->size() ; ++i) - { - Space * space = (*child_spaces)[i]; - - if( space->name && *space->name == name ) - { - return space; - } - } - } - - return nullptr; - } template @@ -969,7 +955,7 @@ protected: if( !is_main_object ) { str << '{'; - print_if(pretty_print && (!value.value_object.empty() || (child_spaces && !child_spaces->empty())), str, '\n'); + print_if(pretty_print && (!value.value_object.empty() || !child_spaces_empty()), str, '\n'); } bool is_first = true; @@ -1009,21 +995,25 @@ protected: template void serialize_child_spaces(StreamType & str, bool pretty_print, int level) const { - if( child_spaces && !child_spaces->empty() ) + const TableType * child_table = find_child_space_table(); + + if( child_table && !child_table->empty() ) { print_if(pretty_print, str, '\n'); - for(Space * child_space : *child_spaces) + for(Space * child_space : *child_table) { print_if(!pretty_print, str, ' '); - if( child_space->name && !child_space->name->empty() ) + const std::wstring * name = child_space->get_wstr(child_spaces_name); + + if( name && !name->empty() ) { - bool quote_field = should_field_be_quoted(*child_space->name); + bool quote_field = should_field_be_quoted(*name); print_level(pretty_print, level, str); print_if(quote_field, str, '"'); - serialize_string_buffer(child_space->name->c_str(), str, Escape::escape_space); + serialize_string_buffer(name->c_str(), str, Escape::escape_space); print_if(quote_field, str, '"'); str << ' '; @@ -1287,8 +1277,6 @@ protected: void copy_value_from(const Space & space); - void copy_child_spaces_from(const Space & space); - void copy_space_name_from(const Space & space); void copy_from(const Space & space); void copy_value_object(const Value & value_from); @@ -1312,15 +1300,15 @@ protected: void initialize_value_table_if_needed(); void initialize_value_table_if_needed(TableType && tab); void initialize_child_spaces_if_needed(); - void initialize_space_name_if_needed(); void remove_value(); void remove_value_string(); void remove_value_wstring(); void remove_value_object(); void remove_value_table(); - void remove_child_spaces(); - void remove_space_name(); + + const Space * find_child_space_const(const wchar_t * name) const; + const Space * find_child_space_const(size_t table_index) const; }; From 49c2b478c0ec5834cbf8eaec33d4a7278125df78 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 21 May 2021 17:32:10 +0200 Subject: [PATCH 67/67] fixed return value from Space::add_child_space() --- src/space/space.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/space/space.cpp b/src/space/space.cpp index a70dc0e..bc334c2 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -2028,7 +2028,7 @@ Space & Space::add_child_space() TableType * child_table = find_child_space_table(); child_table->push_back(new Space()); - return child_table->back(); + return *child_table->back(); }