From c9b6b9e473ffaacaec424ec94b667a17f1c16183 Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Mon, 2 Nov 2015 14:22:13 -0500 Subject: [PATCH] fix windows errors --- cmake/clean => clean | 2 +- clean.bat | 7 ++++ cmake/CMakeLists.txt | 10 +++-- cmake/configure | 19 --------- cmake/{generate-tests.sh => generate-tests} | 0 cmake/generate-tests.bat | 2 + cmake/xlnt.test.cmake | 2 +- configure | 41 +++++++++++++++++++ configure.bat | 7 ++++ include/xlnt/cell/cell.hpp | 2 +- source/cell/cell.cpp | 10 +++-- source/common/datetime.cpp | 14 ++++--- source/serialization/excel_serializer.cpp | 24 +++++++---- source/serialization/worksheet_serializer.cpp | 7 ++-- source/serialization/xml_document.cpp | 9 +++- tests/helpers/helper.hpp | 16 +++++--- tests/test_read.hpp | 8 +--- 17 files changed, 122 insertions(+), 58 deletions(-) rename cmake/clean => clean (80%) mode change 100755 => 100644 create mode 100644 clean.bat delete mode 100755 cmake/configure rename cmake/{generate-tests.sh => generate-tests} (100%) mode change 100755 => 100644 create mode 100644 cmake/generate-tests.bat create mode 100644 configure create mode 100644 configure.bat diff --git a/cmake/clean b/clean old mode 100755 new mode 100644 similarity index 80% rename from cmake/clean rename to clean index d71cb22e..444a76dd --- a/cmake/clean +++ b/clean @@ -5,7 +5,7 @@ import shutil os.chdir(os.path.dirname(os.path.abspath(__file__))) -dirs = ['../bin', '../lib', '../build'] +dirs = ['./bin', './lib', './build'] for dir in dirs: if os.path.isdir(dir): shutil.rmtree(dir) diff --git a/clean.bat b/clean.bat new file mode 100644 index 00000000..60b4c7b4 --- /dev/null +++ b/clean.bat @@ -0,0 +1,7 @@ +@echo off +setlocal EnableDelayedExpansion +for /f %%i in ('where python') DO (set PYTHON=%%i) & goto :done1 +:done1 +@where python3 > nul 2>&1 && for /f %%i in ('@where python3') DO (@set PYTHON=%%i) & goto :done2 +:done2 +!PYTHON! clean \ No newline at end of file diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5e7d93dc..8b35f3d1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,20 +1,24 @@ cmake_minimum_required(VERSION 2.8.7) +if(NOT DEFINED CMAKE_SUPPRESS_DEVELOPER_WARNINGS) + set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE INTERNAL "No dev warnings") +endif() + project(xlnt) if(APPLE) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10) endif(APPLE) -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") endif() -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") +elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y") -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") +elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") endif() set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) diff --git a/cmake/configure b/cmake/configure deleted file mode 100755 index bc4079d1..00000000 --- a/cmake/configure +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 - -import os -import subprocess -import sys - -os.chdir(os.path.dirname(os.path.abspath(__file__))) - -if not os.path.isdir('../build'): - os.mkdir('../build') - -generator = 'Unix Makefiles' - -if sys.platform == 'darwin': - generator = 'Unix Makefiles' -elif sys.platform == 'win32': - generator = 'Visual Studio 14 2015' - -subprocess.call(['cmake3', '-G', generator, '../cmake'], cwd='../build') diff --git a/cmake/generate-tests.sh b/cmake/generate-tests old mode 100755 new mode 100644 similarity index 100% rename from cmake/generate-tests.sh rename to cmake/generate-tests diff --git a/cmake/generate-tests.bat b/cmake/generate-tests.bat new file mode 100644 index 00000000..fa988575 --- /dev/null +++ b/cmake/generate-tests.bat @@ -0,0 +1,2 @@ +cd %~dp0 +../third-party/cxxtest/bin/cxxtestgen --runner=ErrorPrinter -o ../tests/runner-autogen.cpp ../tests/*.hpp \ No newline at end of file diff --git a/cmake/xlnt.test.cmake b/cmake/xlnt.test.cmake index 2b599a97..a92abce4 100644 --- a/cmake/xlnt.test.cmake +++ b/cmake/xlnt.test.cmake @@ -18,7 +18,7 @@ source_group(helpers FILES ${TEST_HELPERS_HEADERS} ${TEST_HELPERS_SOURCES}) target_link_libraries(xlnt.test xlnt) add_custom_target (generate-test-runner - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generate-tests.sh + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generate-tests COMMENT "Generating test runner tests/runner-autogen.cpp" ) diff --git a/configure b/configure new file mode 100644 index 00000000..57dd30e6 --- /dev/null +++ b/configure @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import sys + +def which(program): + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + + return None + +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +if not os.path.isdir('./build'): + os.mkdir('./build') + +generator = 'Unix Makefiles' + +if sys.platform == 'darwin': + generator = 'Unix Makefiles' +elif sys.platform == 'win32': + generator = 'Visual Studio 14 2015' + +cmake = 'cmake' + +if which('cmake3'): + cmake = 'cmake3' + +subprocess.call([cmake, '-G', generator, '../cmake'], cwd='./build') diff --git a/configure.bat b/configure.bat new file mode 100644 index 00000000..27bbebc0 --- /dev/null +++ b/configure.bat @@ -0,0 +1,7 @@ +@echo off +setlocal EnableDelayedExpansion +for /f %%i in ('where python') DO (set PYTHON=%%i) & goto :done1 +:done1 +@where python3 > nul 2>&1 && for /f %%i in ('@where python3') DO (@set PYTHON=%%i) & goto :done2 +:done2 +!PYTHON! configure \ No newline at end of file diff --git a/include/xlnt/cell/cell.hpp b/include/xlnt/cell/cell.hpp index 0f5e12e5..367dc364 100644 --- a/include/xlnt/cell/cell.hpp +++ b/include/xlnt/cell/cell.hpp @@ -83,7 +83,7 @@ class cell /// /// Return a map of error strings such as #DIV/0! and their associated indices. /// - static const std::unordered_map error_codes(); + static const std::unordered_map &error_codes(); // TODO: Should it be possible to construct and use a cell without a parent worksheet? //(cont'd) If so, it would need to be responsible for allocating and deleting its PIMPL. diff --git a/source/cell/cell.cpp b/source/cell/cell.cpp index b04e2815..d56df2e2 100644 --- a/source/cell/cell.cpp +++ b/source/cell/cell.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -763,7 +763,7 @@ std::string format_text(const std::string &text, const std::string &format) namespace xlnt { -const std::unordered_map cell::error_codes() +const std::unordered_map &cell::error_codes() { static const std::unordered_map codes = { { "#NULL!", 0 }, { "#DIV/0!", 1 }, { "#VALUE!", 2 }, { "#REF!", 3 }, { "#NAME?", 4 }, { "#NUM!", 5 }, @@ -910,7 +910,11 @@ template <> void cell::set_value(std::string s) { d_->set_string(s, get_parent().get_parent().get_guess_types()); - if(!s.empty()) get_parent().get_parent().add_shared_string(s); + + if (get_data_type() == type::string && !s.empty()) + { + get_parent().get_parent().add_shared_string(s); + } } template <> diff --git a/source/common/datetime.cpp b/source/common/datetime.cpp index 58123d4d..f8bed2a3 100644 --- a/source/common/datetime.cpp +++ b/source/common/datetime.cpp @@ -115,12 +115,14 @@ time::time(const std::string &time_string) : hour(0), minute(0), second(0), micr long double time::to_number() const { - std::size_t microseconds = static_cast(microsecond); - microseconds += static_cast(second * 1e6); - microseconds += static_cast(minute * 1e6 * 60); - microseconds += static_cast(hour * 1e6 * 60 * 60); - auto number = microseconds / (24.0L * 60 * 60 * 1e6L); - number = std::floor(number * 1e11L + 0.5L) / 1e11L; + std::uint64_t microseconds = static_cast(microsecond); + microseconds += static_cast(second * 1e6); + microseconds += static_cast(minute * 1e6 * 60); + auto microseconds_per_hour = static_cast(1e6) * 60 * 60; + microseconds += static_cast(hour * microseconds_per_hour); + auto number = microseconds / (24.0L * microseconds_per_hour); + auto hundred_billion = static_cast(1e9) * 100; + number = std::floor(number * hundred_billion + 0.5L) / hundred_billion; return number; } diff --git a/source/serialization/excel_serializer.cpp b/source/serialization/excel_serializer.cpp index de62c4b2..f73fb04f 100644 --- a/source/serialization/excel_serializer.cpp +++ b/source/serialization/excel_serializer.cpp @@ -50,7 +50,9 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl } xlnt::manifest_serializer ms(wb.get_manifest()); - ms.read_manifest(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcContentTypes))); + xlnt::xml_document manifest_xml; + manifest_xml.from_string(archive.read(xlnt::constants::ArcContentTypes)); + ms.read_manifest(manifest_xml); if (ms.determine_document_type() != "excel") { @@ -62,7 +64,9 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl if(archive.has_file(xlnt::constants::ArcCore)) { xlnt::workbook_serializer workbook_serializer_(wb); - workbook_serializer_.read_properties_core(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcCore))); + xlnt::xml_document core_properties_xml; + core_properties_xml.from_string(archive.read(xlnt::constants::ArcCore)); + workbook_serializer_.read_properties_core(core_properties_xml); } auto workbook_relationships = @@ -73,7 +77,8 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl wb.create_relationship(relationship.get_id(), relationship.get_target_uri(), relationship.get_type()); } - auto xml = xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcWorkbook)); + xlnt::xml_document xml; + xml.from_string(archive.read(xlnt::constants::ArcWorkbook)); auto root_node = xml.get_child("workbook"); @@ -87,8 +92,9 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl { xlnt::shared_strings_serializer shared_strings_serializer_; std::vector shared_strings; - shared_strings_serializer_.read_shared_strings( - xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcSharedString)), shared_strings); + xlnt::xml_document shared_strings_xml; + shared_strings_xml.from_string(archive.read(xlnt::constants::ArcSharedString)); + shared_strings_serializer_.read_shared_strings(shared_strings_xml, shared_strings); for (auto shared_string : shared_strings) { @@ -97,7 +103,9 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl } xlnt::style_serializer style_reader_(wb); - style_reader_.read_stylesheet(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcStyles))); + xlnt::xml_document style_xml; + style_xml.from_string(archive.read(xlnt::constants::ArcStyles)); + style_reader_.read_stylesheet(style_xml); auto sheets_node = root_node.get_child("sheets"); @@ -113,7 +121,9 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl if(sheet_type != "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml") continue; xlnt::worksheet_serializer worksheet_serializer(ws); - worksheet_serializer.read_worksheet(xlnt::xml_serializer::deserialize(archive.read(ws_filename))); + xlnt::xml_document worksheet_xml; + worksheet_xml.from_string(archive.read(ws_filename)); + worksheet_serializer.read_worksheet(worksheet_xml); } return true; diff --git a/source/serialization/worksheet_serializer.cpp b/source/serialization/worksheet_serializer.cpp index 2d259c91..ca9d93b5 100644 --- a/source/serialization/worksheet_serializer.cpp +++ b/source/serialization/worksheet_serializer.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -124,7 +125,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) std::string type = has_type ? cell_node.get_attribute("t") : ""; bool has_style = cell_node.has_attribute("s"); - int style_id = has_style ? std::stoull(cell_node.get_attribute("s")) : 0; + auto style_id = static_cast(has_style ? std::stoull(cell_node.get_attribute("s")) : 0LL); bool has_formula = cell_node.has_child("f"); bool has_shared_formula = has_formula && cell_node.get_child("f").has_attribute("t") && @@ -145,7 +146,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) } else if (has_type && type == "s" && !has_formula) // shared string { - auto shared_string_index = std::stoull(value_string); + auto shared_string_index = static_cast(std::stoull(value_string)); auto shared_string = shared_strings.at(shared_string_index); cell.set_value(shared_string); } @@ -190,7 +191,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) auto max = static_cast(std::stoull(col_node.get_attribute("max"))); auto width = std::stold(col_node.get_attribute("width")); bool custom = col_node.get_attribute("customWidth") == "1"; - auto column_style = col_node.has_attribute("style") ? std::stoull(col_node.get_attribute("style")) : 0; + auto column_style = static_cast(col_node.has_attribute("style") ? std::stoull(col_node.get_attribute("style")) : 0); for (auto column = min; column <= max; column++) { diff --git a/source/serialization/xml_document.cpp b/source/serialization/xml_document.cpp index 5fc63d0d..25c84fe3 100644 --- a/source/serialization/xml_document.cpp +++ b/source/serialization/xml_document.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -16,6 +17,11 @@ xml_document::xml_document(const xml_document &other) : xml_document() d_->doc.append_copy(other.d_->doc.root()); } +xml_document::xml_document(xml_document &&other) +{ + std::swap(d_, other.d_); +} + xml_document::~xml_document() { } @@ -59,8 +65,7 @@ std::string xml_document::to_string() const xml_document &xml_document::from_string(const std::string &xml_string) { - auto doc = xml_serializer::deserialize(xml_string); - std::swap(doc.d_, d_); + d_->doc.load(xml_string.c_str()); return *this; } diff --git a/tests/helpers/helper.hpp b/tests/helpers/helper.hpp index 9f1d5440..661ac789 100644 --- a/tests/helpers/helper.hpp +++ b/tests/helpers/helper.hpp @@ -49,17 +49,21 @@ public: expected_contents = s.str(); } - auto expected_xml = xlnt::xml_serializer::deserialize(expected_contents); - + xlnt::xml_document expected_xml; + expected_xml.from_string(expected_contents); + return compare_xml(expected_xml.get_root(), observed.get_root()); } static comparison_result compare_xml(const std::string &left_contents, const std::string &right_contents) { - auto left_doc = xlnt::xml_serializer::deserialize(left_contents); - auto right_doc = xlnt::xml_serializer::deserialize(right_contents); - - return compare_xml(left_doc.get_root(), right_doc.get_root()); + xlnt::xml_document left_xml; + left_xml.from_string(left_contents); + + xlnt::xml_document right_xml; + right_xml.from_string(right_contents); + + return compare_xml(left_xml.get_root(), right_xml.get_root()); } static comparison_result compare_xml(const xlnt::xml_node &left, const xlnt::xml_node &right) diff --git a/tests/test_read.hpp b/tests/test_read.hpp index 6b083e85..e0fb484b 100644 --- a/tests/test_read.hpp +++ b/tests/test_read.hpp @@ -161,9 +161,7 @@ public: auto path = PathHelper::GetDataDirectory("/reader/date_1904.xlsx"); xlnt::workbook wb; - xlnt::excel_serializer serializer(wb); - - serializer.load_workbook(path); + wb.load(path); return wb; } @@ -173,9 +171,7 @@ public: auto path = PathHelper::GetDataDirectory("/reader/date_1900.xlsx"); xlnt::workbook wb; - xlnt::excel_serializer serializer(wb); - - serializer.load_workbook(path); + wb.load(path); return wb; }