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" |
#include "crlf.hh" |
||||
|
|
||||
namespace pEp |
namespace pEp { |
||||
{ |
|
||||
|
|
||||
std::string operator""_CRLF(const char* str, size_t length) |
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) |
|
||||
{ |
{ |
||||
if(*str == '\n') |
static const std::string CRLF{ "\r\n" }; |
||||
ret += CRLF; |
|
||||
else |
std::string ret; |
||||
ret += *str; |
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
|
} // end of namespace pEp
|
||||
|
@ -1,85 +1,81 @@ |
|||||
#include <gtest/gtest.h> |
#include <gtest/gtest.h> |
||||
|
|
||||
#include "../src/nfc.hh" // for illegal_utf8 exception |
#include "../src/nfc.hh" // for illegal_utf8 exception |
||||
#include <vector> |
#include <vector> |
||||
|
|
||||
using namespace pEp; |
using namespace pEp; |
||||
using std::u16string_view; |
using std::u16string_view; |
||||
|
|
||||
namespace pEp |
namespace pEp { |
||||
{ |
std::string escape_utf16(u16string_view s); |
||||
std::string escape_utf16(u16string_view s); |
|
||||
} |
} |
||||
|
|
||||
namespace { |
namespace { |
||||
|
|
||||
struct TestEntry |
struct TestEntry { |
||||
{ |
u16string_view input; |
||||
u16string_view input; |
bool is_nfc; |
||||
bool is_nfc; |
IsNFC quick; |
||||
IsNFC quick; |
u16string_view nfc; |
||||
u16string_view nfc; |
}; |
||||
}; |
|
||||
|
|
||||
typedef TestEntry TE; |
typedef TestEntry TE; |
||||
|
|
||||
|
|
||||
std::ostream& operator<<(std::ostream& o, const TestEntry& tt) |
std::ostream& operator<<(std::ostream& o, const TestEntry& tt) |
||||
{ |
{ |
||||
return o << "input=«" << pEp::escape_utf16(tt.input) << "», isNfc=" << tt.is_nfc << ", quick=" << tt.quick << ". "; |
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 = |
const std::vector<TestEntry> testValues = { |
||||
{ |
{ u"", true, IsNFC::Yes, u"" }, // always start with the simple case ;-)
|
||||
{ u"" , true, IsNFC::Yes, u"" }, // always start with the simple case ;-)
|
{ u"123", true, IsNFC::Yes, u"123" }, // some ASCII digits. Still easy.
|
||||
{ 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"\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"ä" , true, IsNFC::Yes, u"ä" }, // <U+00E4> small a with diaeresis
|
{ u"\u0105", true, IsNFC::Yes, u"\u0105" }, // <U+0105> small a with ogonek
|
||||
{ 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\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", 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\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\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"\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"ä\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:
|
// 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\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)
|
{ 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. :-/
|
// 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" }, |
{ 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, 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
|
{ u16string_view(nullo, 4), true, IsNFC::Yes, u16string_view(nullo, 4) }, // Yeah, 4 NUL bytes
|
||||
|
|
||||
{ u"EOF", true, IsNFC::Yes, u"EOF" } |
{ u"EOF", true, IsNFC::Yes, u"EOF" } |
||||
}; |
}; |
||||
|
|
||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||
|
|
||||
|
|
||||
class Nfc16Test : public ::testing::TestWithParam<TestEntry> |
class Nfc16Test : public ::testing::TestWithParam<TestEntry> { |
||||
{ |
// intentionally left blank for now.
|
||||
// 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(); |
const auto& v = GetParam(); |
||||
EXPECT_EQ( v.quick, UTF16::isNFC_quick_check(v.input) ); |
EXPECT_EQ(v.quick, UTF16::isNFC_quick_check(v.input)); |
||||
|
|
||||
EXPECT_EQ( v.is_nfc, UTF16::isNFC(v.input) ); |
EXPECT_EQ(v.is_nfc, UTF16::isNFC(v.input)); |
||||
EXPECT_EQ( v.nfc , UTF16::toNFC(v.input) ); |
EXPECT_EQ(v.nfc, UTF16::toNFC(v.input)); |
||||
|
|
||||
if(v.is_nfc) |
if (v.is_nfc) { |
||||
{ |
EXPECT_EQ(v.input, UTF16::toNFC(v.input)); |
||||
EXPECT_EQ( v.input, UTF16::toNFC(v.input) ); |
} |
||||
} |
|
||||
} |
} |
||||
|
Loading…
Reference in new issue