Further MSVC compatibility

String assertions fixed, numerical issue with dbTrans fixed, iterator 
assertions fixed.
This commit is contained in:
Matthias Köfferlein 2018-09-02 19:18:42 +02:00
parent 356a468d66
commit 1bf4d95388
8 changed files with 80 additions and 47 deletions

4
.gitignore vendored
View File

@ -31,10 +31,11 @@
*.out
*.app
# Build and binary directories for shadow build:
# Build, temporary and binary directories for shadow build:
build-*
bin-*
mkqtdecl.tmp
testtmp
# private data
private
@ -48,7 +49,6 @@ src/plugins/*
# QTCreator files
src/klayout.pro.user
# python setuptools eggs
*.egg-info/
build/

View File

@ -1912,10 +1912,13 @@ LayoutQueryIterator::LayoutQueryIterator (const LayoutQuery &q, db::Layout *layo
m_eval.define_function (mp_q->property_name (i), new FilterStateFunction (i, &m_state));
}
init ();
// Avoid update() calls while iterating in modifying mode
mp_layout->update ();
mp_layout->start_changes ();
// NOTE: Stange - in modifying mode, init() will actually already execute the
// first modification. Hence start_changes() needs to be called before.
init ();
}
LayoutQueryIterator::LayoutQueryIterator (const LayoutQuery &q, const db::Layout *layout, tl::Eval *parent_eval, tl::AbsoluteProgress *progress)

View File

@ -25,6 +25,20 @@
namespace db
{
// -------------------------------------------------------------------------
// safe versions (assertion-less) of safe_isdigit, safe_isprint, safe_isalpha, safe_isalnum
// (required for debug mode of MSVC)
inline bool safe_isdigit (char c)
{
return c != 0 && static_cast<unsigned char> (c) < 0x80 && isdigit (c);
}
inline bool safe_isspace (char c)
{
return c != 0 && static_cast<unsigned char> (c) < 0x80 && isspace (c);
}
// ---------------------------------------------------------------
// NamedLayerReader
@ -58,8 +72,8 @@ extract_plain_layer (const char *s, int &l)
if (! *s) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
while (safe_isdigit (*s)) {
l = l * 10 + static_cast<int> (*s - '0');
++s;
}
return (*s == 0);
@ -74,27 +88,27 @@ extract_ld (const char *s, int &l, int &d, std::string &n)
++s;
}
if (! *s || ! isdigit (*s)) {
if (! safe_isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
while (safe_isdigit (*s)) {
l = l * 10 + static_cast<int> (*s - '0');
++s;
}
if (*s == 'D' || *s == '.') {
++s;
if (! *s || ! isdigit (*s)) {
if (! safe_isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
d = d * 10 + (unsigned int) (*s - '0');
while (safe_isdigit (*s)) {
d = d * 10 + static_cast<int> (*s - '0');
++s;
}
}
if (*s && (isspace (*s) || *s == '_')) {
if (safe_isspace (*s) || *s == '_') {
++s;
n = s;
return true;

View File

@ -1533,6 +1533,13 @@ public:
complex_trans (const simple_trans<I> &s, double acos, double mag)
: m_u (s.disp ())
{
// This prevents rounding issues (like acos = 1.0000000000002):
if (acos > 1.0) {
acos = 1.0;
} else if (acos < -1.0) {
acos = -1.0;
}
db::point<R> t (1.0, 0.0);
t = fixpoint_trans<R> (s.fp_trans ()) (t);
double asin = sqrt (1.0 - acos * acos); // we may to this since we know that the angle is between 0 and 90 degree

View File

@ -87,9 +87,9 @@ msvc {
} else {
# disable some warnings
QMAKE_CXXFLAGS += \
/wd4251 \ # DLL interface required
/wd4251 \ # Disable "DLL interface required"
/source-charset:utf-8 \ # Use UTF-8 for source files
}

View File

@ -165,6 +165,11 @@ inline bool safe_isprint (char c)
return c != 0 && static_cast<unsigned char> (c) < 0x80 && isprint (c);
}
inline bool safe_isspace (char c)
{
return c != 0 && static_cast<unsigned char> (c) < 0x80 && isspace (c);
}
// -------------------------------------------------------------------------
// Utility: a strtod version that is independent of the locale
@ -748,7 +753,7 @@ void
from_string (const std::string &s, double &v)
{
const char *cp = s.c_str ();
while (*cp && isspace (*cp)) {
while (safe_isspace (*cp)) {
++cp;
}
if (! *cp) {
@ -756,7 +761,7 @@ from_string (const std::string &s, double &v)
}
const char *cp_end = cp;
v = local_strtod (cp, cp_end);
while (*cp_end && isspace (*cp_end)) {
while (safe_isspace (*cp_end)) {
++cp_end;
}
if (*cp_end) {
@ -873,12 +878,12 @@ std::string
trim (const std::string &s)
{
const char *cp = s.c_str ();
while (isspace (*cp) && *cp) {
while (safe_isspace (*cp)) {
++cp;
}
const char *cq = s.c_str () + s.size ();
while (cq > cp && isspace (cq [-1])) {
while (cq > cp && safe_isspace (cq [-1])) {
--cq;
}
@ -1246,7 +1251,7 @@ Extractor::try_read (std::string &string, const char *term)
{
// if the terminating characters contain line feed for blank, we must not skip over them
if (strchr (term, '\n') || strchr (term, ' ')) {
while (isspace (*m_cp) && strchr (term, *m_cp) == 0 && *m_cp) {
while (safe_isspace (*m_cp) && strchr (term, *m_cp) == 0) {
++m_cp;
}
if (! *m_cp) {
@ -1258,11 +1263,11 @@ Extractor::try_read (std::string &string, const char *term)
bool term_is_space = false;
for (const char *t = term; *t && ! term_is_space; ++t) {
term_is_space = isspace (*t);
term_is_space = safe_isspace (*t);
}
string.clear ();
while (*m_cp && (term_is_space || ! isspace (*m_cp)) && strchr (term, *m_cp) == NULL) {
while (*m_cp && (term_is_space || ! safe_isspace (*m_cp)) && strchr (term, *m_cp) == NULL) {
string += *m_cp;
++m_cp;
}
@ -1321,7 +1326,7 @@ Extractor::test (const char *token)
const char *
Extractor::skip ()
{
while (isspace (*m_cp) && *m_cp) {
while (safe_isspace (*m_cp)) {
++m_cp;
}
return m_cp;

View File

@ -44,7 +44,7 @@ TEST(1)
EXPECT_EQ (to_string ((unsigned char *)" 12"), " 12");
EXPECT_EQ (to_string (std::string (" 12")), " 12");
#if defined(WIN32)
#if defined(_WIN32) && !defined(_MSC_VER)
EXPECT_EQ (tl::sprintf("%g %e %f",M_PI,M_PI*1e6,M_PI*0.001), "3.14159 3.141593e+006 0.003142");
EXPECT_EQ (tl::sprintf("%G %E %F",M_PI*1e6,M_PI*1e6,M_PI*1e6), "3.14159E+006 3.141593E+006 3141592.653590");
EXPECT_EQ (tl::sprintf("%-15g %15.8e %15.12f %g",M_PI,M_PI*1e6,M_PI*0.001,M_PI), "3.14159 3.14159265e+006 0.003141592654 3.14159");
@ -493,18 +493,18 @@ TEST(15)
}
try {
EXPECT_EQ (tl::to_string_from_local (tl::to_local ("Hällo\trld!").c_str ()), "Hällo\trld!");
EXPECT_EQ (tl::to_string_from_local (tl::to_local ("H\xc3\xa4llo\tW\xc3\xb6rld!").c_str ()), "H\xc3\xa4llo\tW\xc3\xb6rld!");
setlocale (LC_ALL, locale.c_str ());
} catch (...) {
setlocale (LC_ALL, locale.c_str ());
throw;
}
EXPECT_EQ (std::string ("Ä").size (), size_t (2));
EXPECT_EQ (tl::to_string (std::wstring (L"Ä")), "Ä");
EXPECT_EQ (tl::to_wstring (std::string ("Ä")).size (), size_t (1));
EXPECT_EQ (tl::to_string (tl::to_wstring ("Utf8 supports emoticons: \xF0\x9F\x98\x81\nand Umlauts: äüö")).c_str (), "Utf8 supports emoticons: \xF0\x9F\x98\x81\nand Umlauts: äüö");
EXPECT_EQ (std::string ("\xc3\x84").size (), size_t (2));
EXPECT_EQ (tl::to_string (std::wstring (L"Ä")), "\xc3\x84");
EXPECT_EQ (tl::to_wstring (std::string ("\xc3\x84")).size (), size_t (1));
EXPECT_EQ (tl::to_string (tl::to_wstring ("Utf8 supports emoticons: \xF0\x9F\x98\x81\nand Umlauts: \xc3\xa4\xc3\xbc\xc3\xb6")).c_str (), "Utf8 supports emoticons: \xF0\x9F\x98\x81\nand Umlauts: \xc3\xa4\xc3\xbc\xc3\xb6");
EXPECT_EQ (tl::to_upper_case ("nOrMaliI(äÄüÜöÖß-42°+6€)"), "NORMALII(ÄÄÜÜÖÖß-42°+6€)");
EXPECT_EQ (tl::to_lower_case ("nOrMaliI(äÄüÜöÖß-42°+6€)"), "normalii(ääüüööß-42°+6€)");
EXPECT_EQ (tl::to_upper_case ("nOrMaliI(\xc3\xa4\xc3\x84\xc3\xbc\xc3\x9c\xc3\xb6\xc3\x96\xc3\x9f-42\xc2\xb0+6\xe2\x82\xac)"), "NORMALII(\xc3\x84\xc3\x84\xc3\x9c\xc3\x9c\xc3\x96\xc3\x96\xc3\x9f-42\xc2\xb0+6\xe2\x82\xac)");
EXPECT_EQ (tl::to_lower_case ("nOrMaliI(\xc3\xa4\xc3\x84\xc3\xbc\xc3\x9c\xc3\xb6\xc3\x96\xc3\x9f-42\xc2\xb0+6\xe2\x82\xac)"), "normalii(\xc3\xa4\xc3\xa4\xc3\xbc\xc3\xbc\xc3\xb6\xc3\xb6\xc3\x9f-42\xc2\xb0+6\xe2\x82\xac)");
}

View File

@ -540,25 +540,31 @@ main_cont (int &argc, char **argv)
ut::noctrl << "TESTSRC=" << tl::testsrc ();
ut::noctrl << "TESTTMP=" << tl::absolute_file_path (tl::testtmp ());
const std::vector<tl::TestBase *> *selected_tests = 0;
std::vector<tl::TestBase *> subset;
if (! test_list.empty ()) {
selected_tests = &subset;
ut::noctrl << "Selected tests:";
ut::noctrl << "Selected tests:";
for (std::vector<tl::TestBase *>::const_iterator i = tl::TestRegistrar::instance()->tests ().begin (); i != tl::TestRegistrar::instance()->tests ().end (); ++i) {
for (std::vector<tl::TestBase *>::const_iterator i = tl::TestRegistrar::instance()->tests ().begin (); i != tl::TestRegistrar::instance()->tests ().end (); ++i) {
bool exclude = false;
bool exclude = false;
for (std::vector<std::string>::const_iterator m = exclude_test_list.begin (); m != exclude_test_list.end () && !exclude; ++m) {
tl::GlobPattern re (*m);
re.set_case_sensitive (false);
re.set_header_match (true);
if (re.match ((*i)->name ())) {
exclude = true;
}
for (std::vector<std::string>::const_iterator m = exclude_test_list.begin (); m != exclude_test_list.end () && !exclude; ++m) {
tl::GlobPattern re (*m);
re.set_case_sensitive (false);
re.set_header_match (true);
if (re.match ((*i)->name ())) {
exclude = true;
}
}
if (test_list.empty ()) {
if (!exclude) {
subset.push_back (*i);
ut::noctrl << " " << (*i)->name ();
}
} else {
for (std::vector<std::string>::const_iterator m = test_list.begin (); !exclude && m != test_list.end (); ++m) {
tl::GlobPattern re (*m);
@ -573,11 +579,9 @@ main_cont (int &argc, char **argv)
}
} else {
selected_tests = &tl::TestRegistrar::instance()->tests ();
}
result = run_tests (*selected_tests, editable, non_editable, slow, repeat, gsi_coverage, class_names);
result = run_tests (subset, editable, non_editable, slow, repeat, gsi_coverage, class_names);
ut::ctrl << "</testsuites>";