WIP: Simple SPICE reader.

This commit is contained in:
Matthias Koefferlein
2019-04-01 22:46:33 +02:00
parent 9613ad72c8
commit 89ffd7e3da
15 changed files with 1176 additions and 37 deletions
+59 -12
View File
@@ -42,7 +42,7 @@ namespace tl
static std::locale c_locale ("C");
// -------------------------------------------------------------------------
// lower and upper case for wchar_t
// lower and upper case for wchar_t and uint32_t
#include "utf_casefolding.h"
@@ -66,9 +66,44 @@ wchar_t wupcase (wchar_t c)
}
}
uint32_t utf32_downcase (uint32_t c32)
{
if (sizeof (wchar_t) == 2 && c32 >= 0x10000) {
return c32;
} else {
return uint32_t (wdowncase (wchar_t (c32)));
}
}
uint32_t utf32_upcase (uint32_t c32)
{
if (sizeof (wchar_t) == 2 && c32 >= 0x10000) {
return c32;
} else {
return uint32_t (wupcase (wchar_t (c32)));
}
}
// -------------------------------------------------------------------------
// Conversion of UTF8 to wchar_t
uint32_t utf32_from_utf8 (const char *&cp, const char *cpe = 0)
{
uint32_t c32 = (unsigned char) *cp++;
if (c32 >= 0xf0 && ((cpe && cp + 2 < cpe) || (! cpe && cp [0] && cp [1] && cp [2]))) {
c32 = ((c32 & 0x7) << 18) | ((uint32_t (cp [0]) & 0x3f) << 12) | ((uint32_t (cp [1]) & 0x3f) << 6) | (uint32_t (cp [2]) & 0x3f);
cp += 3;
} else if (c32 >= 0xe0 && ((cpe && cp + 1 < cpe) || (! cpe && cp [0] && cp [1]))) {
c32 = ((c32 & 0xf) << 12) | ((uint32_t (cp [0]) & 0x3f) << 6) | (uint32_t (cp [1]) & 0x3f);
cp += 2;
} else if (c32 >= 0xc0 && ((cpe && cp < cpe) || (! cpe && cp [0]))) {
c32 = ((c32 & 0x1f) << 6) | (uint32_t (*cp) & 0x3f);
++cp;
}
return c32;
}
std::wstring to_wstring (const std::string &s)
{
std::wstring ws;
@@ -76,17 +111,7 @@ std::wstring to_wstring (const std::string &s)
const char *cpe = s.c_str () + s.size ();
for (const char *cp = s.c_str (); cp < cpe; ) {
uint32_t c32 = (unsigned char) *cp++;
if (c32 >= 0xf0 && cp + 2 < cpe) {
c32 = ((c32 & 0x7) << 18) | ((uint32_t (cp [0]) & 0x3f) << 12) | ((uint32_t (cp [1]) & 0x3f) << 6) | (uint32_t (cp [2]) & 0x3f);
cp += 3;
} else if (c32 >= 0xe0 && cp + 1 < cpe) {
c32 = ((c32 & 0xf) << 12) | ((uint32_t (cp [0]) & 0x3f) << 6) | (uint32_t (cp [1]) & 0x3f);
cp += 2;
} else if (c32 >= 0xc0 && cp < cpe) {
c32 = ((c32 & 0x1f) << 6) | (uint32_t (*cp) & 0x3f);
++cp;
}
uint32_t c32 = utf32_from_utf8 (cp, cpe);
if (sizeof (wchar_t) == 2 && c32 >= 0x10000) {
c32 -= 0x10000;
@@ -1324,6 +1349,28 @@ Extractor::test (const char *token)
}
}
bool
Extractor::test_without_case (const char *token)
{
skip ();
const char *cp = m_cp;
while (*cp && *token) {
uint32_t c = utf32_downcase (utf32_from_utf8 (cp));
uint32_t ct = utf32_downcase (utf32_from_utf8 (token));
if (c != ct) {
return false;
}
}
if (! *token) {
m_cp = cp;
return true;
} else {
return false;
}
}
const char *
Extractor::skip ()
{
+7
View File
@@ -669,6 +669,13 @@ public:
*/
bool test (const char *token);
/**
* @brief Test for a token (a certain string) in case-insensitive mode
*
* If the token is not present, return false.
*/
bool test_without_case (const char *token);
/**
* @brief Skip blanks
*
+27
View File
@@ -388,6 +388,33 @@ TEST(8)
EXPECT_EQ (x.try_read_quoted (s), true);
EXPECT_EQ (s, "a_word\'!");
EXPECT_EQ (x.at_end (), true);
x = Extractor (" foobar");
EXPECT_EQ (x.test ("foo"), true);
EXPECT_EQ (x.test ("bar"), true);
x = Extractor (" foo bar");
EXPECT_EQ (x.test ("foo"), true);
EXPECT_EQ (x.test ("bar"), true);
x = Extractor (" FOObar");
EXPECT_EQ (x.test ("foo"), false);
EXPECT_EQ (x.test ("BAR"), false);
x = Extractor (" FOObar");
EXPECT_EQ (x.test_without_case ("foo"), true);
EXPECT_EQ (x.test_without_case ("BAR"), true);
x = Extractor (" µm");
EXPECT_EQ (x.test ("µm"), true);
x = Extractor (" µM");
EXPECT_EQ (x.test ("µm"), false);
EXPECT_EQ (x.test_without_case ("µm"), true);
x = Extractor (" µm");
EXPECT_EQ (x.test ("µM"), false);
EXPECT_EQ (x.test_without_case ("µM"), true);
}
TEST(9)