From 356a468d66508a3f8233d6028a26f1c69263e18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20K=C3=B6fferlein?= Date: Sun, 2 Sep 2018 00:40:35 +0200 Subject: [PATCH] A couple of changes to make MSVC work - not done yet. --- setup.py | 17 +++--- src/buddies/unit_tests/bdStrmcmpTests.cc | 2 +- src/db/db/dbLayoutDiff.cc | 9 ++- src/db/db/dbPath.h | 10 ++-- src/db/db/dbPoint.h | 1 + src/db/db/dbPolygon.h | 38 ++++++++++--- src/db/unit_tests/dbLayoutDiff.cc | 30 +++++----- src/gsi/gsi_test/gsiTest.cc | 10 +++- src/lay/lay/layMacroController.cc | 6 +- src/laybasic/laybasic/layEditable.cc | 4 ++ src/laybasic/laybasic/layLayerTreeModel.h | 5 -- .../oasis/db_plugin/dbOASISWriter.cc | 8 ++- src/pymod/unit_tests/pymod_tests.cc | 16 ++++-- src/rbastub/rba.cc | 7 ++- src/tl/tl/tlExpression.cc | 1 + src/tl/tl/tlFileUtils.cc | 4 +- src/tl/tl/tlObject.cc | 8 ++- src/tl/tl/tlObject.h | 6 ++ src/tl/tl/tlString.cc | 56 +++++++++++++------ src/tl/tl/tlTimer.cc | 6 +- src/tl/tl/tlVector.h | 24 +++++++- 21 files changed, 194 insertions(+), 74 deletions(-) diff --git a/setup.py b/setup.py index 23635782d..a9a33b99b 100644 --- a/setup.py +++ b/setup.py @@ -154,13 +154,15 @@ config = Config() # ------------------------------------------------------------------ # _tl dependency library -_tl_sources = glob.glob("src/tl/tl/*.cc") +_tl_path = os.path.join("src", "tl", "tl") + +_tl_sources = glob.glob(os.path.join(_tl_path, "*.cc")) # Exclude sources which are compatible with Qt only -_tl_sources.remove("src/tl/tl/tlHttpStreamQt.cc") -_tl_sources.remove("src/tl/tl/tlHttpStreamNoQt.cc") -_tl_sources.remove("src/tl/tl/tlFileSystemWatcher.cc") -_tl_sources.remove("src/tl/tl/tlDeferredExecutionQt.cc") +_tl_sources.remove(os.path.join(_tl_path, "tlHttpStreamQt.cc")) +_tl_sources.remove(os.path.join(_tl_path, "tlHttpStreamNoQt.cc")) +_tl_sources.remove(os.path.join(_tl_path, "tlFileSystemWatcher.cc")) +_tl_sources.remove(os.path.join(_tl_path, "tlDeferredExecutionQt.cc")) _tl = Extension(config.root + '._tl', define_macros=config.macros() + [('MAKE_TL_LIBRARY', 1)], @@ -201,10 +203,11 @@ _pya = Extension(config.root + '._pya', # ------------------------------------------------------------------ # _db dependency library -_db_sources = glob.glob("src/db/db/*.cc") +_db_path = os.path.join("src", "db", "db") +_db_sources = glob.glob(os.path.join(_db_path, "*.cc")) # Not a real source: -_db_sources.remove("src/db/db/fonts.cc") +_db_sources.remove(os.path.join(_db_path, "fonts.cc")) _db = Extension(config.root + '._db', define_macros=config.macros() + [('MAKE_DB_LIBRARY', 1)], diff --git a/src/buddies/unit_tests/bdStrmcmpTests.cc b/src/buddies/unit_tests/bdStrmcmpTests.cc index 966050a80..b0fff0316 100644 --- a/src/buddies/unit_tests/bdStrmcmpTests.cc +++ b/src/buddies/unit_tests/bdStrmcmpTests.cc @@ -459,10 +459,10 @@ TEST(9B) EXPECT_EQ (cap.captured_text (), "Texts differ for layer 8/1 in cell RINGO\n" "Not in b but in a:\n" + " ('VSS',r0 0,0)\n" " ('FB',r0 0,1800)\n" " ('OSC',r0 24560,1800)\n" " ('VDD',r0 0,2800)\n" - " ('VSS',r0 0,0)\n" "Not in a but in b:\n" "Layouts differ\n" ); diff --git a/src/db/db/dbLayoutDiff.cc b/src/db/db/dbLayoutDiff.cc index 3fd1e73a3..f95e760cf 100644 --- a/src/db/db/dbLayoutDiff.cc +++ b/src/db/db/dbLayoutDiff.cc @@ -1217,8 +1217,15 @@ PrintingDifferenceReceiver::print_cell_inst (const db::CellInstArrayWithProperti template void -PrintingDifferenceReceiver::print_diffs (const db::PropertiesRepository &pr, const std::vector > &a, const std::vector > &b) +PrintingDifferenceReceiver::print_diffs (const db::PropertiesRepository &pr, const std::vector > &_a, const std::vector > &_b) { + // the vectors may be in any order (specifically because of tolerances) but + // for the diff we need to make sure they are ordered. + std::vector > a = _a; + std::sort (a.begin (), a.end ()); + std::vector > b = _b; + std::sort (b.begin (), b.end ()); + std::vector > anotb; std::set_difference (a.begin (), a.end (), b.begin (), b.end (), std::back_inserter (anotb)); for (typename std::vector >::const_iterator s = anotb.begin (); s != anotb.end (); ++s) { diff --git a/src/db/db/dbPath.h b/src/db/db/dbPath.h index 4bde626f5..4a00b7bb0 100644 --- a/src/db/db/dbPath.h +++ b/src/db/db/dbPath.h @@ -224,6 +224,7 @@ public: typedef typename coord_traits::area_type area_type; typedef object_tag< path > tag; typedef tl::vector pointlist_type; + typedef typename tl::type_traits::relocate_requirements relocate_requirements; typedef db::path_point_iterator, db::unit_trans > iterator; /** @@ -1129,10 +1130,6 @@ Path round_path_corners (const Path &input, int rad, int npoints); } // namespace db -/** - * @brief Special extractors for the paths - */ - namespace tl { /** @@ -1141,7 +1138,7 @@ namespace tl template struct type_traits > : public type_traits { - typedef trivial_relocate_required relocate_requirements; + typedef typename db::path::relocate_requirements relocate_requirements; typedef true_tag has_efficient_swap; typedef true_tag supports_extractor; typedef true_tag supports_to_string; @@ -1149,6 +1146,9 @@ namespace tl typedef true_tag has_equal_operator; }; + /** + * @brief Special extractors for the paths + */ template<> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::Path &p); template<> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::DPath &p); diff --git a/src/db/db/dbPoint.h b/src/db/db/dbPoint.h index c767f7a57..fade5da34 100644 --- a/src/db/db/dbPoint.h +++ b/src/db/db/dbPoint.h @@ -686,6 +686,7 @@ namespace tl template struct type_traits > : public type_traits { + typedef trivial_relocate_required relocate_requirements; typedef true_tag supports_extractor; typedef true_tag supports_to_string; typedef true_tag has_less_operator; diff --git a/src/db/db/dbPolygon.h b/src/db/db/dbPolygon.h index ad32211e3..09a09832e 100644 --- a/src/db/db/dbPolygon.h +++ b/src/db/db/dbPolygon.h @@ -1011,6 +1011,29 @@ private: } }; +} + +namespace tl +{ + /** + * @brief The type traits for the contour type + */ + template + struct type_traits > : public type_traits + { + // the contour just uses one pointer, hence the relocation requirements are simple + typedef typename tl::trivial_relocate_required relocate_requirements; + typedef true_tag has_efficient_swap; + typedef false_tag supports_extractor; + typedef false_tag supports_to_string; + typedef true_tag has_less_operator; + typedef true_tag has_equal_operator; + }; +} + +namespace db +{ + /** * @brief The contour point iterator * @@ -1351,7 +1374,6 @@ private: } }; - /** * @brief A polygon class * @@ -1383,6 +1405,7 @@ public: typedef typename coord_traits::area_type area_type; typedef polygon_contour contour_type; typedef tl::vector contour_list_type; + typedef typename tl::type_traits::relocate_requirements relocate_requirements; typedef db::polygon_edge_iterator< polygon, db::unit_trans > polygon_edge_iterator; typedef db::polygon_contour_iterator< contour_type, db::unit_trans > polygon_contour_iterator; typedef db::object_tag< polygon > tag; @@ -2339,11 +2362,11 @@ public: typedef typename coord_traits::area_type area_type; typedef polygon_contour contour_type; typedef tl::vector contour_list_type; + typedef typename tl::type_traits::relocate_requirements relocate_requirements; typedef db::polygon_edge_iterator< simple_polygon, db::unit_trans > polygon_edge_iterator; typedef db::polygon_contour_iterator< contour_type, db::unit_trans > polygon_contour_iterator; typedef db::object_tag< simple_polygon > tag; - /** * @brief The default constructor. * @@ -3388,10 +3411,6 @@ void swap (db::simple_polygon &a, db::simple_polygon &b) } // namespace std -/** - * @brief Special extractors for the polygons - */ - namespace tl { /** @@ -3400,7 +3419,7 @@ namespace tl template struct type_traits > : public type_traits { - typedef trivial_relocate_required relocate_requirements; + typedef typename db::polygon::relocate_requirements relocate_requirements; typedef true_tag has_efficient_swap; typedef true_tag supports_extractor; typedef true_tag supports_to_string; @@ -3414,13 +3433,16 @@ namespace tl template struct type_traits > : public type_traits { - typedef trivial_relocate_required relocate_requirements; + typedef typename db::simple_polygon::relocate_requirements relocate_requirements; typedef true_tag supports_extractor; typedef true_tag supports_to_string; typedef true_tag has_less_operator; typedef true_tag has_equal_operator; }; + /** + * @brief Special extractors for the polygons + */ template<> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::Polygon &p); template<> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::DPolygon &p); template<> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::SimplePolygon &p); diff --git a/src/db/unit_tests/dbLayoutDiff.cc b/src/db/unit_tests/dbLayoutDiff.cc index ecccfff1a..964397834 100644 --- a/src/db/unit_tests/dbLayoutDiff.cc +++ b/src/db/unit_tests/dbLayoutDiff.cc @@ -122,8 +122,12 @@ TestDifferenceReceiver::print_cell_inst (const db::CellInstArrayWithProperties & template void -TestDifferenceReceiver::print_diffs (const db::PropertiesRepository & /*pr*/, const std::vector > &a, const std::vector > &b) +TestDifferenceReceiver::print_diffs (const db::PropertiesRepository & /*pr*/, const std::vector > &_a, const std::vector > &_b) { + std::vector > a = _a; + std::sort (a.begin (), a.end ()); + std::vector > b = _b; + std::sort (b.begin (), b.end ()); std::vector > anotb; std::set_difference (a.begin (), a.end (), b.begin (), b.end (), std::back_inserter (anotb)); for (typename std::vector >::const_iterator s = anotb.begin (); s != anotb.end (); ++s) { @@ -593,8 +597,8 @@ TEST(2) "layout_diff: boxes differ for layer 17/0 in cell c2x\n" "Not in b but in a:\n" "Not in a but in b:\n" - " (2,2;1003,1004)\n" " (1,2;1003,1006)\n" + " (2,2;1003,1004)\n" ); } @@ -736,8 +740,8 @@ TEST(2P) "Not in b but in a:\n" " (1,2;1003,1004) [1]\n" "Not in a but in b:\n" - " (1,2;1003,1006) [1]\n" " (1,2;1003,1005) [2]\n" + " (1,2;1003,1006) [1]\n" " (2,2;1003,1004) [3]\n" ); @@ -750,8 +754,8 @@ TEST(2P) "Not in b but in a:\n" " (1,2;1003,1004) [1]\n" "Not in a but in b:\n" - " (1,2;1003,1006) [1]\n" " (1,2;1003,1005) [2]\n" + " (1,2;1003,1006) [1]\n" " (2,2;1003,1004) [3]\n" ); @@ -809,8 +813,8 @@ TEST(2P) "layout_diff: boxes differ for layer 17/0 in cell c2x\n" "Not in b but in a:\n" "Not in a but in b:\n" - " (1,2;1003,1006) [2]\n" " (1,2;1003,1005) [3]\n" + " (1,2;1003,1006) [2]\n" ); h = hh; @@ -828,9 +832,9 @@ TEST(2P) "Not in b but in a:\n" " (1,2;1003,1004) [1]\n" "Not in a but in b:\n" - " (2,2;1003,1004)\n" - " (1,2;1003,1006) [1]\n" " (1,2;1003,1005) [1]\n" + " (1,2;1003,1006) [1]\n" + " (2,2;1003,1004)\n" ); } @@ -941,8 +945,8 @@ TEST(3) "layout_diff: polygons differ for layer 17/0 in cell c2x\n" "Not in b but in a:\n" "Not in a but in b:\n" - " (2,2;2,1004;1003,1004;1003,2)\n" " (1,2;1,1006;1003,1006;1003,2)\n" + " (2,2;2,1004;1003,1004;1003,2)\n" ); } @@ -1053,8 +1057,8 @@ TEST(4) "layout_diff: edges differ for layer 17/0 in cell c2x\n" "Not in b but in a:\n" "Not in a but in b:\n" - " (2,2;1003,1004)\n" " (1,2;1003,1006)\n" + " (2,2;1003,1004)\n" ); } @@ -1163,10 +1167,10 @@ TEST(5) "layout_diff: texts differ for layer 17/0 in cell c2x\n" "Not in b but in a:\n" "Not in a but in b:\n" - " ('X',r90 3,4)\n" " ('X',r90 2,3)\n" - " ('X',r180 2,3)\n" " ('Y',r90 2,3)\n" + " ('X',r90 3,4)\n" + " ('X',r180 2,3)\n" ); // two more to match more of h: @@ -1181,8 +1185,8 @@ TEST(5) "layout_diff: texts differ for layer 17/0 in cell c2x\n" "Not in b but in a:\n" "Not in a but in b:\n" - " ('X',r180 2,3)\n" " ('Y',r90 2,3)\n" + " ('X',r180 2,3)\n" ); } @@ -1297,9 +1301,9 @@ TEST(6) "layout_diff: paths differ for layer 17/0 in cell c2x\n" "Not in b but in a:\n" "Not in a but in b:\n" + " (1,2;11,12) w=17 bx=0 ex=0 r=true\n" " (1,2;11,12) w=17 bx=0 ex=-1 r=false\n" " (1,3;11,11) w=17 bx=0 ex=0 r=false\n" - " (1,2;11,12) w=17 bx=0 ex=0 r=true\n" " (1,2;11,12) w=17 bx=1 ex=0 r=false\n" " (1,2;11,12) w=18 bx=0 ex=0 r=false\n" ); diff --git a/src/gsi/gsi_test/gsiTest.cc b/src/gsi/gsi_test/gsiTest.cc index 74ba226ac..1f5092e68 100644 --- a/src/gsi/gsi_test/gsiTest.cc +++ b/src/gsi/gsi_test/gsiTest.cc @@ -237,12 +237,18 @@ static std::vector ::const_iterator b10e_ext (const B *b) static const A *b10bp_ext (const B *b) { - return &*(b->b10b ()); + if (b->b10b () == b->b10e ()) { + return 0; + } else { + return b->b10b ().operator-> (); + } } static const A *b10ep_ext (const B *b) { - return &*(b->b10e ()); + // The way this code is written there are no assertions from MSVC's + // iterator debug mode: + return b10bp_ext (b) + (b->b10e () - b->b10b ()); } // ---------------------------------------------------------------- diff --git a/src/lay/lay/layMacroController.cc b/src/lay/lay/layMacroController.cc index d312e52eb..c0a7d7ba3 100644 --- a/src/lay/lay/layMacroController.cc +++ b/src/lay/lay/layMacroController.cc @@ -46,8 +46,7 @@ MacroController::MacroController () dm_sync_file_watcher (this, &MacroController::sync_file_watcher), dm_sync_files (this, &MacroController::sync_files) { - connect (&m_temp_macros, SIGNAL (menu_needs_update ()), this, SLOT (macro_collection_changed ())); - connect (&m_temp_macros, SIGNAL (macro_collection_changed (lym::MacroCollection *)), this, SLOT (macro_collection_changed ())); + // .. nothing yet .. } static lay::MacroController::MacroCategory ruby_cat () @@ -159,6 +158,9 @@ MacroController::finish () void MacroController::initialized (lay::PluginRoot *root) { + connect (&m_temp_macros, SIGNAL (menu_needs_update ()), this, SLOT (macro_collection_changed ())); + connect (&m_temp_macros, SIGNAL (macro_collection_changed (lym::MacroCollection *)), this, SLOT (macro_collection_changed ())); + mp_mw = dynamic_cast (root); if (mp_mw) { mp_macro_editor = new lay::MacroEditorDialog (mp_mw, &lym::MacroCollection::root ()); diff --git a/src/laybasic/laybasic/layEditable.cc b/src/laybasic/laybasic/layEditable.cc index 55f02ef3a..0a4044d33 100644 --- a/src/laybasic/laybasic/layEditable.cc +++ b/src/laybasic/laybasic/layEditable.cc @@ -57,6 +57,10 @@ Editable::Editable (lay::Editables *editables) Editable::~Editable () { + // Reasoning for reset (): on MSVC, virtual functions must not be called inside + // the destructor. reset () avoids that lay::Editables::enable calls us. + reset (); + // erase the object from the table of enabled services if (mp_editables) { mp_editables->enable (this, false); diff --git a/src/laybasic/laybasic/layLayerTreeModel.h b/src/laybasic/laybasic/layLayerTreeModel.h index 82997900c..ecb856fca 100644 --- a/src/laybasic/laybasic/layLayerTreeModel.h +++ b/src/laybasic/laybasic/layLayerTreeModel.h @@ -209,11 +209,6 @@ public: */ void signal_layer_changed (); -signals: - void dataChanged (const QModelIndex & topLeft, const QModelIndex & bottomRight ); - void layoutAboutToBeChanged (); - void layoutChanged (); - private: lay::LayoutView *mp_view; size_t m_id_start, m_id_end; diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc index 0c423baf7..d9d9c5a17 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc @@ -1070,7 +1070,11 @@ OASISWriter::end_cblock () tl::OutputStream deflated_stream (m_cblock_compressed); tl::DeflateFilter deflate (deflated_stream); - deflate.put (m_cblock_buffer.data (), m_cblock_buffer.size ()); + // Reasoning for if(...): we don't want to access data from an empty vector through data() + if (m_cblock_buffer.size () > 0) { + deflate.put (m_cblock_buffer.data (), m_cblock_buffer.size ()); + } + deflate.flush (); const size_t compression_overhead = 4; @@ -1088,7 +1092,7 @@ OASISWriter::end_cblock () write_bytes (m_cblock_compressed.data (), m_cblock_compressed.size ()); - } else { + } else if (m_cblock_buffer.size () > 0) { // Reasoning for if(...): we don't want to access data from an empty vector through data() write_bytes (m_cblock_buffer.data (), m_cblock_buffer.size ()); } diff --git a/src/pymod/unit_tests/pymod_tests.cc b/src/pymod/unit_tests/pymod_tests.cc index 0ada3f98b..73dec29d2 100644 --- a/src/pymod/unit_tests/pymod_tests.cc +++ b/src/pymod/unit_tests/pymod_tests.cc @@ -36,9 +36,15 @@ int run_pymodtest (tl::TestBase *_this, const std::string &fn) { static std::string pypath; - pypath = "PYTHONPATH="; - pypath += STRINGIFY (PYTHONPATH); - putenv ((char *) pypath.c_str ()); + if (pypath.empty ()) { + pypath = "PYTHONPATH="; + pypath += STRINGIFY (PYTHONPATH); + } +#if defined(_WIN32) + _putenv (const_cast (pypath.c_str ())); +#else + putenv (const_cast (pypath.c_str ())); +#endif tl::info << pypath; std::string fp (tl::testsrc ()); @@ -47,7 +53,9 @@ int run_pymodtest (tl::TestBase *_this, const std::string &fn) std::string text; { - tl::InputPipe pipe (std::string (STRINGIFY (PYTHON)) + " " + fp + " 2>&1"); + std::string cmd = std::string ("\"") + STRINGIFY (PYTHON) + "\" " + fp + " 2>&1"; + tl::info << cmd; + tl::InputPipe pipe (cmd); tl::InputStream is (pipe); text = is.read_all (); } diff --git a/src/rbastub/rba.cc b/src/rbastub/rba.cc index def836aa7..42179c1db 100644 --- a/src/rbastub/rba.cc +++ b/src/rbastub/rba.cc @@ -21,6 +21,7 @@ */ #include "rba.h" +#include "tlExceptions.h" namespace rba { @@ -129,7 +130,11 @@ RubyInterpreter::available () const int RubyInterpreter::initialize (int &argc, char **argv, int (*main_cont)(int &, char **)) { - return (*main_cont) (argc, argv); + int res = 1; +BEGIN_PROTECTED + res = (*main_cont) (argc, argv); +END_PROTECTED + return res; } void diff --git a/src/tl/tl/tlExpression.cc b/src/tl/tl/tlExpression.cc index 65a8590df..6aa6a823b 100644 --- a/src/tl/tl/tlExpression.cc +++ b/src/tl/tl/tlExpression.cc @@ -31,6 +31,7 @@ #include #include #include +#include #define _USE_MATH_DEFINES // for MSVC #include #include diff --git a/src/tl/tl/tlFileUtils.cc b/src/tl/tl/tlFileUtils.cc index f9fc0e20b..1176da22b 100644 --- a/src/tl/tl/tlFileUtils.cc +++ b/src/tl/tl/tlFileUtils.cc @@ -789,7 +789,7 @@ get_inst_path_internal () wchar_t buffer[MAX_PATH]; int len; - if ((len = GetModuleFileName (NULL, buffer, MAX_PATH)) > 0) { + if ((len = GetModuleFileNameW (NULL, buffer, MAX_PATH)) > 0) { return tl::absolute_path (tl::to_string (std::wstring (buffer))); } @@ -833,7 +833,7 @@ get_module_path (void *addr) wchar_t buffer[MAX_PATH]; int len; - if ((len = GetModuleFileName(h_module, buffer, MAX_PATH)) > 0) { + if ((len = GetModuleFileNameW (h_module, buffer, MAX_PATH)) > 0) { return tl::absolute_file_path (tl::to_string (std::wstring (buffer, 0, len))); } diff --git a/src/tl/tl/tlObject.cc b/src/tl/tl/tlObject.cc index 42f476b85..0d1b4cfca 100644 --- a/src/tl/tl/tlObject.cc +++ b/src/tl/tl/tlObject.cc @@ -38,6 +38,12 @@ Object::Object () } Object::~Object () +{ + reset (); +} + +void +Object::reset () { WeakOrSharedPtr *ptrs; @@ -45,7 +51,7 @@ Object::~Object () // But this will easily create deadlocks and the // destructor should not be called while other threads // are accessing this object anyway. - while ((ptrs = (WeakOrSharedPtr *)(size_t (mp_ptrs) & ~size_t (1))) != 0) { + while ((ptrs = reinterpret_cast (size_t (mp_ptrs) & ~size_t (1))) != 0) { ptrs->reset_object (); } } diff --git a/src/tl/tl/tlObject.h b/src/tl/tl/tlObject.h index aa0399631..df78b0435 100644 --- a/src/tl/tl/tlObject.h +++ b/src/tl/tl/tlObject.h @@ -121,6 +121,12 @@ protected: */ void detach_from_all_events (); + /** + * @brief Resets all references to this object + * This method will release all references within weak and shared pointers. + */ + void reset (); + private: friend class WeakOrSharedPtr; diff --git a/src/tl/tl/tlString.cc b/src/tl/tl/tlString.cc index c7220c191..0da77d253 100644 --- a/src/tl/tl/tlString.cc +++ b/src/tl/tl/tlString.cc @@ -141,6 +141,30 @@ std::string to_string (const std::wstring &ws) return s; } +// ------------------------------------------------------------------------- +// 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 (c) < 0x80 && isdigit (c); +} + +inline bool safe_isalnum (char c) +{ + return c != 0 && static_cast (c) < 0x80 && isalnum (c); +} + +inline bool safe_isalpha (char c) +{ + return c != 0 && static_cast (c) < 0x80 && isalpha (c); +} + +inline bool safe_isprint (char c) +{ + return c != 0 && static_cast (c) < 0x80 && isprint (c); +} + // ------------------------------------------------------------------------- // Utility: a strtod version that is independent of the locale @@ -246,7 +270,7 @@ static double local_strtod (const char *cp, const char *&cp_new) // Extract upper digits int exponent = 0; double mant = 0.0; - while (isdigit (*cp)) { + while (safe_isdigit (*cp)) { mant = mant * 10.0 + double (*cp - '0'); ++cp; } @@ -254,7 +278,7 @@ static double local_strtod (const char *cp, const char *&cp_new) // Extract lower digits if (*cp == '.') { ++cp; - while (isdigit (*cp)) { + while (safe_isdigit (*cp)) { mant = mant * 10.0 + double (*cp - '0'); ++cp; --exponent; @@ -272,7 +296,7 @@ static double local_strtod (const char *cp, const char *&cp_new) ++cp; } int en = 0; - while (isdigit (*cp)) { + while (safe_isdigit (*cp)) { en = en * 10 + int (*cp - '0'); ++cp; } @@ -523,7 +547,7 @@ to_quoted_string (const std::string &s) r += "\\r"; } else if (*c == '\t') { r += "\\t"; - } else if (! isprint (*c) || (unsigned char) *c >= 0x80) { + } else if (! safe_isprint (*c) || (unsigned char) *c >= 0x80) { char b [20]; ::sprintf (b, "\\%03o", int ((unsigned char) *c)); r += b; @@ -549,7 +573,7 @@ escape_string (const std::string &s) r += "\\r"; } else if (*c == '\t') { r += "\\t"; - } else if (! isprint (*c)) { + } else if (! safe_isprint (*c)) { char b [20]; ::sprintf (b, "\\%03o", int ((unsigned char) *c)); r += b; @@ -562,9 +586,9 @@ escape_string (const std::string &s) inline char unescape_char (const char * &cp) { - if (isdigit (*cp)) { + if (safe_isdigit (*cp)) { int c = 0; - while (*cp && isdigit (*cp)) { + while (*cp && safe_isdigit (*cp)) { c = c * 8 + int (*cp - '0'); ++cp; } @@ -602,9 +626,9 @@ to_word_or_quoted_string (const std::string &s, const char *non_term) // If the string does not contain non_term characters, we may simply keep it. // Otherwise we need to quote it. const char *cp = s.c_str (); - if (*cp && (isalpha (*cp) || strchr (non_term, *cp) != NULL)) { + if (*cp && (safe_isalpha (*cp) || strchr (non_term, *cp) != NULL)) { ++cp; - for ( ; *cp && (isalnum (*cp) || strchr (non_term, *cp) != NULL); ++cp) { + for ( ; *cp && (safe_isalnum (*cp) || strchr (non_term, *cp) != NULL); ++cp) { ; } } @@ -1052,12 +1076,12 @@ Extractor::try_read_signed_int (T &value) ++m_cp; } - if (! isdigit (*m_cp)) { + if (! safe_isdigit (*m_cp)) { return false; } value = 0; - while (isdigit (*m_cp)) { + while (safe_isdigit (*m_cp)) { if (value > std::numeric_limits::max () / 10) { throw tl::Exception (overflow_msg_func () ()); } @@ -1083,12 +1107,12 @@ Extractor::try_read_unsigned_int (T &value) return false; } - if (! isdigit (*m_cp)) { + if (! safe_isdigit (*m_cp)) { return false; } value = 0; - while (isdigit (*m_cp)) { + while (safe_isdigit (*m_cp)) { if (value > std::numeric_limits::max () / 10) { throw tl::Exception (overflow_msg_func () ()); } @@ -1178,7 +1202,7 @@ Extractor::try_read_word (std::string &string, const char *non_term) } string.clear (); - while (*m_cp && (isalnum (*m_cp) || strchr (non_term, *m_cp) != NULL)) { + while (*m_cp && (safe_isalnum (*m_cp) || strchr (non_term, *m_cp) != NULL)) { string += *m_cp; ++m_cp; } @@ -1660,7 +1684,7 @@ sprintf (const char *f, const std::vector &vv, unsigned int a0) } unsigned int width = 0; - while (isdigit (*cp) && *cp) { + while (safe_isdigit (*cp) && *cp) { width = (width * 10) + (unsigned int)(*cp - '0'); ++cp; } @@ -1669,7 +1693,7 @@ sprintf (const char *f, const std::vector &vv, unsigned int a0) if (*cp == '.') { ++cp; unsigned int prec = 0; - while (isdigit (*cp) && *cp) { + while (safe_isdigit (*cp) && *cp) { prec = (prec * 10) + (unsigned int)(*cp - '0'); ++cp; } diff --git a/src/tl/tl/tlTimer.cc b/src/tl/tl/tlTimer.cc index a65379ea4..0c5d5c3ac 100644 --- a/src/tl/tl/tlTimer.cc +++ b/src/tl/tl/tlTimer.cc @@ -67,9 +67,9 @@ static int64_t ms_time () FILETIME ft; GetSystemTimeAsFileTime (&ft); - // device by 8192 -> should fit into a 64bit type - uint64_t t = (uint64_t (ft.dwHighDateTime) << (64 - 13)) | (uint64_t (ft.dwLowDateTime) >> 13); - return int64_t (0.5 + t / 0.8192); + uint64_t t = (uint64_t (ft.dwHighDateTime) << (sizeof (ft.dwHighDateTime) * 8)) | uint64_t (ft.dwLowDateTime); + // FILETIME uses 100ns resolution, hence divide by 10000 to get ms: + return int64_t (t / 10000); #else diff --git a/src/tl/tl/tlVector.h b/src/tl/tl/tlVector.h index 49cab3ae4..59731ed29 100644 --- a/src/tl/tl/tlVector.h +++ b/src/tl/tl/tlVector.h @@ -25,6 +25,7 @@ #define HDR_tlVector #include +#include "tlTypeTraits.h" namespace tl { @@ -39,6 +40,7 @@ namespace tl * 2.) by use of a special allocator provide a garbage collection * mechanism that may move and compact the blocks allocated by * the vectors. + * 3.) Avoid memory fragmentation by using blocks with a maximum size */ template @@ -56,7 +58,7 @@ public: /** * @brief Copy constructor */ - vector (const vector &d) : std::vector (d) { } + explicit vector (const tl::vector &d) : std::vector (d) { } /** * @brief Initialization with value and length @@ -64,6 +66,26 @@ public: vector (const T &v, int s) : std::vector (v, s) { } }; +/** + * @brief The type traits for the vector type + */ +template +struct type_traits > : public type_traits +{ +#if defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL != 0 + // With iterator debugging on, the vector carries additional + // information which cannot be copied trivially + typedef complex_relocate_required relocate_requirements; +#else + typedef trivial_relocate_required relocate_requirements; +#endif + typedef true_tag has_efficient_swap; + typedef false_tag supports_extractor; + typedef false_tag supports_to_string; + typedef true_tag has_less_operator; + typedef true_tag has_equal_operator; +}; + } // namespace tl #endif