Browse Source
If you dont like reformatting of complete codebases, the solution is to USE this.master

17 changed files with 825 additions and 727 deletions
@ -0,0 +1,45 @@ |
|||
BasedOnStyle: LLVM |
|||
Language: Cpp |
|||
Standard: c++17 |
|||
DerivePointerAlignment: true |
|||
SortIncludes: Never |
|||
ReflowComments: false |
|||
PointerAlignment: Left |
|||
AlignAfterOpenBracket: AlwaysBreak |
|||
AlignOperands: AlignAfterOperator |
|||
BreakConstructorInitializers: AfterColon |
|||
AlignTrailingComments: true |
|||
AllowAllArgumentsOnNextLine: false |
|||
AllowAllParametersOfDeclarationOnNextLine: false |
|||
AllowShortEnumsOnASingleLine: false |
|||
AllowShortFunctionsOnASingleLine: Empty |
|||
AllowShortIfStatementsOnASingleLine: Never |
|||
AllowShortLoopsOnASingleLine: false |
|||
AlwaysBreakTemplateDeclarations: Yes |
|||
BinPackArguments: false |
|||
BinPackParameters: false |
|||
ExperimentalAutoDetectBinPacking: true |
|||
BreakBeforeBraces: Custom |
|||
BraceWrapping: |
|||
AfterFunction: true |
|||
ColumnLimit: 100 |
|||
AllowAllConstructorInitializersOnNextLine: false |
|||
#BreakConstructorInitializersBeforeComma: true |
|||
ConstructorInitializerAllOnOneLineOrOnePerLine: true |
|||
AlwaysBreakAfterDefinitionReturnType: None |
|||
AlwaysBreakAfterReturnType: None |
|||
PenaltyBreakBeforeFirstCallParameter: 0 |
|||
PenaltyReturnTypeOnItsOwnLine: 1000000 |
|||
PenaltyBreakAssignment: 1000000 |
|||
PenaltyExcessCharacter: 10 |
|||
IndentCaseLabels: true |
|||
IndentWidth: 4 |
|||
MaxEmptyLinesToKeep: 2 |
|||
NamespaceIndentation: All |
|||
SpaceAfterTemplateKeyword: false |
|||
AccessModifierOffset: -4 |
|||
AllowShortBlocksOnASingleLine: Always |
|||
IndentPPDirectives: BeforeHash |
|||
IndentExternBlock: Indent |
|||
Cpp11BracedListStyle: false |
|||
BreakStringLiterals: false |
@ -1,26 +1,24 @@ |
|||
#include "crlf.hh" |
|||
|
|||
namespace pEp |
|||
{ |
|||
namespace pEp { |
|||
|
|||
std::string operator""_CRLF(const char* str, size_t length) |
|||
{ |
|||
static const std::string CRLF{"\r\n"}; |
|||
|
|||
std::string ret; |
|||
ret.reserve(length + ((length+29)/30) + 2 ); // rough guess for average line length of 30.
|
|||
const char* end = str + length; |
|||
|
|||
// N.B.: Loop could be more optimized, but not necessary because it is only used for string literals.
|
|||
for(; str != end; ++str) |
|||
std::string operator""_CRLF(const char* str, size_t length) |
|||
{ |
|||
if(*str == '\n') |
|||
ret += CRLF; |
|||
else |
|||
ret += *str; |
|||
static const std::string CRLF{ "\r\n" }; |
|||
|
|||
std::string ret; |
|||
ret.reserve(length + ((length + 29) / 30) + 2); // rough guess for average line length of 30.
|
|||
const char* end = str + length; |
|||
|
|||
// N.B.: Loop could be more optimized, but not necessary because it is only used for string literals.
|
|||
for (; str != end; ++str) { |
|||
if (*str == '\n') |
|||
ret += CRLF; |
|||
else |
|||
ret += *str; |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
} // end of namespace pEp
|
|||
|
@ -1,85 +1,81 @@ |
|||
#include <gtest/gtest.h> |
|||
|
|||
#include "../src/nfc.hh" // for illegal_utf8 exception |
|||
#include "../src/nfc.hh" // for illegal_utf8 exception |
|||
#include <vector> |
|||
|
|||
using namespace pEp; |
|||
using std::u16string_view; |
|||
|
|||
namespace pEp |
|||
{ |
|||
std::string escape_utf16(u16string_view s); |
|||
namespace pEp { |
|||
std::string escape_utf16(u16string_view s); |
|||
} |
|||
|
|||
namespace { |
|||
|
|||
struct TestEntry |
|||
{ |
|||
u16string_view input; |
|||
bool is_nfc; |
|||
IsNFC quick; |
|||
u16string_view nfc; |
|||
}; |
|||
struct TestEntry { |
|||
u16string_view input; |
|||
bool is_nfc; |
|||
IsNFC quick; |
|||
u16string_view nfc; |
|||
}; |
|||
|
|||
typedef TestEntry TE; |
|||
typedef TestEntry TE; |
|||
|
|||
|
|||
std::ostream& operator<<(std::ostream& o, const TestEntry& tt) |
|||
{ |
|||
return o << "input=«" << pEp::escape_utf16(tt.input) << "», isNfc=" << tt.is_nfc << ", quick=" << tt.quick << ". "; |
|||
} |
|||
std::ostream& operator<<(std::ostream& o, const TestEntry& tt) |
|||
{ |
|||
return o << "input=«" << pEp::escape_utf16(tt.input) << "», isNfc=" << tt.is_nfc |
|||
<< ", quick=" << tt.quick << ". "; |
|||
} |
|||
|
|||
|
|||
const char16_t nullo[4] = {0,0,0,0}; |
|||
const char16_t nullo[4] = { 0, 0, 0, 0 }; |
|||
|
|||
const std::vector<TestEntry> testValues = |
|||
{ |
|||
{ u"" , true, IsNFC::Yes, u"" }, // always start with the simple case ;-)
|
|||
{ u"123" , true, IsNFC::Yes, u"123" }, // some ASCII digits. Still easy.
|
|||
{ u"\n\\\b" , true, IsNFC::Yes, u"\n\\\b" }, // backslash escapes for ASCII and control chars
|
|||
{ u"ä" , true, IsNFC::Yes, u"ä" }, // <U+00E4> small a with diaeresis
|
|||
{ u"\u0105" , true, IsNFC::Yes, u"\u0105" }, // <U+0105> small a with ogonek
|
|||
const std::vector<TestEntry> testValues = { |
|||
{ u"", true, IsNFC::Yes, u"" }, // always start with the simple case ;-)
|
|||
{ u"123", true, IsNFC::Yes, u"123" }, // some ASCII digits. Still easy.
|
|||
{ u"\n\\\b", true, IsNFC::Yes, u"\n\\\b" }, // backslash escapes for ASCII and control chars
|
|||
{ u"ä", true, IsNFC::Yes, u"ä" }, // <U+00E4> small a with diaeresis
|
|||
{ u"\u0105", true, IsNFC::Yes, u"\u0105" }, // <U+0105> small a with ogonek
|
|||
|
|||
{ u"a\u0308" , false, IsNFC::Maybe, u"ä" }, // a + <U+0308> combining diaresis
|
|||
{ u"a\u0328" , false, IsNFC::Maybe, u"\u0105" }, // a + <U+0328> combining ogonek
|
|||
{ u"a\u0328\u0308", false, IsNFC::Maybe, u"\u0105\u0308" }, // a + <U+0328> + <U+0308> (ogonek + diaeresis)
|
|||
{ u"a\u0308\u0328", false, IsNFC::Maybe, u"\u0105\u0308" }, // a + <U+0308> + <U+0328> (diaeresis + ogonek)
|
|||
{ u"a\u0308", false, IsNFC::Maybe, u"ä" }, // a + <U+0308> combining diaresis
|
|||
{ u"a\u0328", false, IsNFC::Maybe, u"\u0105" }, // a + <U+0328> combining ogonek
|
|||
{ u"a\u0328\u0308", false, IsNFC::Maybe, u"\u0105\u0308" }, // a + <U+0328> + <U+0308> (ogonek + diaeresis)
|
|||
{ u"a\u0308\u0328", false, IsNFC::Maybe, u"\u0105\u0308" }, // a + <U+0308> + <U+0328> (diaeresis + ogonek)
|
|||
|
|||
{ u"\u0105\u0308" , true, IsNFC::Maybe, u"\u0105\u0308" }, // <U+0105> small a with ogonek + combining diaeresis
|
|||
{ u"ä\u0328" , false, IsNFC::Maybe, u"\u0105\u0308" }, // a diaeresis + <U+0328> combining ogonek
|
|||
{ u"\u0105\u0308", true, IsNFC::Maybe, u"\u0105\u0308" }, // <U+0105> small a with ogonek + combining diaeresis
|
|||
{ u"ä\u0328", false, IsNFC::Maybe, u"\u0105\u0308" }, // a diaeresis + <U+0328> combining ogonek
|
|||
|
|||
// Already implemented, because <U+305> and <U+33C> have neither "No" nor "Maybe" NFC class:
|
|||
{ u"a\u0305\u033c", false, IsNFC::No , u"a\u033c\u0305"}, // a + <U+0305> + <U+033C> (overline + seagull_below)
|
|||
{ u"a\u033c\u0305", true, IsNFC::Yes , u"a\u033c\u0305"}, // a + <U+033C> + <U+0305> (seagull_below + overline)
|
|||
// Already implemented, because <U+305> and <U+33C> have neither "No" nor "Maybe" NFC class:
|
|||
{ u"a\u0305\u033c", false, IsNFC::No, u"a\u033c\u0305" }, // a + <U+0305> + <U+033C> (overline + seagull_below)
|
|||
{ u"a\u033c\u0305", true, IsNFC::Yes, u"a\u033c\u0305" }, // a + <U+033C> + <U+0305> (seagull_below + overline)
|
|||
|
|||
// MUSICAL SYMBOL SIXTEENTH NOTE -> will be decomposed and not re-composed according to Unicode data, for whatever reason. :-/
|
|||
{ u"\U0001D161", false, IsNFC::No, u"\U0001d15f\U0001d16f" }, |
|||
{ u16string_view(nullo, 1), true, IsNFC::Yes, u16string_view(nullo, 1) }, // Yeah, 1 NUL byte
|
|||
{ u16string_view(nullo, 4), true, IsNFC::Yes, u16string_view(nullo, 4) }, // Yeah, 4 NUL bytes
|
|||
|
|||
{ u"EOF", true, IsNFC::Yes, u"EOF" } |
|||
}; |
|||
// MUSICAL SYMBOL SIXTEENTH NOTE -> will be decomposed and not re-composed according to Unicode data, for whatever reason. :-/
|
|||
{ u"\U0001D161", false, IsNFC::No, u"\U0001d15f\U0001d16f" }, |
|||
{ u16string_view(nullo, 1), true, IsNFC::Yes, u16string_view(nullo, 1) }, // Yeah, 1 NUL byte
|
|||
{ u16string_view(nullo, 4), true, IsNFC::Yes, u16string_view(nullo, 4) }, // Yeah, 4 NUL bytes
|
|||
|
|||
{ u"EOF", true, IsNFC::Yes, u"EOF" } |
|||
}; |
|||
|
|||
} // end of anonymous namespace
|
|||
|
|||
|
|||
class Nfc16Test : public ::testing::TestWithParam<TestEntry> |
|||
{ |
|||
// intentionally left blank for now.
|
|||
class Nfc16Test : public ::testing::TestWithParam<TestEntry> { |
|||
// intentionally left blank for now.
|
|||
}; |
|||
|
|||
INSTANTIATE_TEST_SUITE_P(Nfc16TestInstance, Nfc16Test, testing::ValuesIn(testValues) ); |
|||
INSTANTIATE_TEST_SUITE_P(Nfc16TestInstance, Nfc16Test, testing::ValuesIn(testValues)); |
|||
|
|||
TEST_P( Nfc16Test, Meh ) |
|||
TEST_P(Nfc16Test, Meh) |
|||
{ |
|||
const auto& v = GetParam(); |
|||
EXPECT_EQ( v.quick, UTF16::isNFC_quick_check(v.input) ); |
|||
|
|||
EXPECT_EQ( v.is_nfc, UTF16::isNFC(v.input) ); |
|||
EXPECT_EQ( v.nfc , UTF16::toNFC(v.input) ); |
|||
|
|||
if(v.is_nfc) |
|||
{ |
|||
EXPECT_EQ( v.input, UTF16::toNFC(v.input) ); |
|||
} |
|||
const auto& v = GetParam(); |
|||
EXPECT_EQ(v.quick, UTF16::isNFC_quick_check(v.input)); |
|||
|
|||
EXPECT_EQ(v.is_nfc, UTF16::isNFC(v.input)); |
|||
EXPECT_EQ(v.nfc, UTF16::toNFC(v.input)); |
|||
|
|||
if (v.is_nfc) { |
|||
EXPECT_EQ(v.input, UTF16::toNFC(v.input)); |
|||
} |
|||
} |
|||
|
Loading…
Reference in new issue