From 0cc89434e8409b1353ea19e84583bfcfb4d0159a Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Fri, 17 Feb 2023 11:12:10 -0500 Subject: [PATCH] Squashed 'externals/coda-oss/' changes from 5e0f5d614..f1ad69fd4 f1ad69fd4 Merge branch 'main' into cpp17 ba8547621 don't put 'struct' in the macro fd75f84b6 Merge branch 'main' into cpp17 bd79aa11f require Python 3.7, do MD5 check ce34286c8 Merge branch 'main' into cpp17 ecfa687c5 use std::filesystem (instead of sys::filesystem) where possible (#652) 89df1b508 Merge branch 'main' into cpp17 243bc9991 add 'override' c0fd2124d wrap common "file open" routines to support sys::expandEnviromentVariables() (#651) 8d7de5125 restore C++17 02f488f3a Merge branch 'main' into cpp17 0657f3297 adjust compiler flags for clean CMake builds (#650) git-subtree-dir: externals/coda-oss git-subtree-split: f1ad69fd4c578c5c3ac9f110a7a75ce9f53e44a9 --- CMakeLists.txt | 15 +- modules/c++/CMakeLists.txt | 21 +- modules/c++/coda-oss-lite.vcxproj | 1 + modules/c++/coda-oss-lite.vcxproj.filters | 3 + .../config/disable_compiler_warnings.h | 8 +- modules/c++/io/include/io/ByteStream.h | 10 +- modules/c++/io/include/io/CountingStreams.h | 2 +- modules/c++/io/include/io/DataStream.h | 4 +- modules/c++/io/include/io/DbgStream.h | 2 +- modules/c++/io/include/io/FileInputStreamOS.h | 8 +- .../c++/io/include/io/FileOutputStreamOS.h | 10 +- modules/c++/io/include/io/NullStreams.h | 12 +- modules/c++/io/include/io/PipeStream.h | 6 +- modules/c++/io/include/io/ProxyStreams.h | 12 +- .../io/include/io/RotatingFileOutputStream.h | 2 +- modules/c++/io/include/io/SerializableFile.h | 4 +- modules/c++/io/include/io/StandardStreams.h | 8 +- modules/c++/io/include/io/StringStream.h | 8 +- modules/c++/mem/include/mem/ComplexView.h | 1 + .../c++/mem/tests/ScratchVisualization.cpp | 2 +- .../c++/mem/unittests/test_scratch_memory.cpp | 6 +- .../c++/mt/include/mt/BalancedRunnable1D.h | 2 +- .../mt/CPUAffinityThreadInitializerLinux.h | 2 +- .../c++/mt/include/mt/GenerationThreadPool.h | 4 +- .../c++/mt/include/mt/GenericRequestHandler.h | 2 +- modules/c++/mt/include/mt/ThreadGroup.h | 2 +- .../mt/WorkSharingBalancedRunnable1D.h | 2 +- .../mt/source/CPUAffinityInitializerLinux.cpp | 4 +- modules/c++/mt/tests/MTSingletonTest.cpp | 6 +- modules/c++/mt/tests/ThreadExceptionTest.cpp | 6 +- modules/c++/mt/unittests/ThreadGroupTest.cpp | 2 +- modules/c++/re/include/re/RegexPredicate.h | 2 +- modules/c++/str/include/str/utf8.h | 8 +- .../c++/sys/include/sys/ConditionVarPosix.h | 12 +- modules/c++/sys/include/sys/Err.h | 2 +- modules/c++/sys/include/sys/Exec.h | 4 +- modules/c++/sys/include/sys/File.h | 64 ++++- modules/c++/sys/include/sys/FileFinder.h | 14 +- modules/c++/sys/include/sys/LocalDateTime.h | 6 +- modules/c++/sys/include/sys/MutexCpp11.h | 4 +- modules/c++/sys/include/sys/MutexPosix.h | 4 +- modules/c++/sys/include/sys/OSUnix.h | 64 ++--- .../c++/sys/include/sys/ProcessInterface.h | 2 +- modules/c++/sys/include/sys/ProcessUnix.h | 4 +- modules/c++/sys/include/sys/SemaphorePosix.h | 4 +- modules/c++/sys/include/sys/StopWatch.h | 16 +- modules/c++/sys/include/sys/ThreadInterface.h | 2 +- modules/c++/sys/include/sys/ThreadPosix.h | 6 +- modules/c++/sys/include/sys/UTCDateTime.h | 4 +- modules/c++/sys/source/AbstractOS.cpp | 6 + modules/c++/sys/source/File.cpp | 238 ++++++++++++++++++ modules/c++/sys/source/FileUnix.cpp | 18 +- modules/c++/sys/source/FileWin32.cpp | 18 +- modules/c++/sys/tests/MutexTest.cpp | 2 +- modules/c++/sys/tests/ReadWriteMutexTest.cpp | 2 +- modules/c++/sys/tests/ReentrantTest.cpp | 2 +- modules/c++/sys/tests/ThreadFreeTest.cpp | 2 +- modules/c++/sys/tests/ThreadTest4.cpp | 4 +- modules/c++/sys/tests/ThreadTest5.cpp | 2 +- .../c++/sys/unittests/test_atomic_counter.cpp | 4 +- modules/c++/sys/unittests/test_os.cpp | 118 ++++++++- modules/c++/xml.lite/CMakeLists.txt | 4 + .../include/xml/lite/UtilitiesXerces.h | 6 +- .../c++/xml.lite/include/xml/lite/XMLReader.h | 1 + modules/c++/zip/source/ZipEntry.cpp | 2 + modules/drivers/CMakeLists.txt | 12 +- modules/drivers/hdf5/CMakeLists.txt | 1 + modules/drivers/zlib/CMakeLists.txt | 4 - modules/python/CMakeLists.txt | 12 + 69 files changed, 664 insertions(+), 193 deletions(-) create mode 100644 modules/c++/sys/source/File.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c929f5df8..b063bbe618 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,11 @@ # Author: Scott A. Colcord cmake_minimum_required(VERSION 3.14) +project(coda-oss) -set(TARGET_LANGUAGE c++) set(CMAKE_CXX_STANDARD 17) set(CXX_STANDARD_REQUIRED true) -project(coda-oss) - if (EXISTS "${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") # build and package with conan include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") @@ -21,14 +19,13 @@ endif() if (${CMAKE_PROJECT_NAME} STREQUAL coda-oss) # this is the top level project - # set up warnings + # Always turn on "warnings as errors" to avoid lots of (meaningless?) build output; + # we'll dial-back warnings as necessary. if (MSVC) - # set warning level to /W3 - string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - add_compile_options(/std:c++17) + add_compile_options(/WX) # warnings as errors + add_compile_options(/MP) # multi-processor compile elseif (UNIX) - add_compile_options(-std=c++17) + add_compile_options(-Werror) # warnings as errors endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") diff --git a/modules/c++/CMakeLists.txt b/modules/c++/CMakeLists.txt index 7ca6fdffa3..34495bbfd0 100644 --- a/modules/c++/CMakeLists.txt +++ b/modules/c++/CMakeLists.txt @@ -1,10 +1,25 @@ set(TARGET_LANGUAGE c++) -# turn on warnings as errors +# turn on maximum warnings if (MSVC) - add_compile_options(/WX /W4) # /Wall + add_compile_options(/std:c++17) + + # By default, there is a /W3 on the command-line from somewhere (?); adding + # /Wn results in a compiler warning. + #add_compile_options(/W4) # /Wall + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") # /Wall + elseif (UNIX) - add_compile_options(-Werror -Wall -Wpedantic -Wextra) + add_compile_options(-std=c++17) + + add_compile_options(-Wall -pedantic -Wextra) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wregister") # -Wvolatile + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weffc++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wzero-as-null-pointer-constant") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-final-types -Wsuggest-final-methods") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override") endif() # add an interface library for unittests diff --git a/modules/c++/coda-oss-lite.vcxproj b/modules/c++/coda-oss-lite.vcxproj index fba2d0b1f3..9b1eac0299 100644 --- a/modules/c++/coda-oss-lite.vcxproj +++ b/modules/c++/coda-oss-lite.vcxproj @@ -345,6 +345,7 @@ + diff --git a/modules/c++/coda-oss-lite.vcxproj.filters b/modules/c++/coda-oss-lite.vcxproj.filters index b409b14392..76ec00124b 100644 --- a/modules/c++/coda-oss-lite.vcxproj.filters +++ b/modules/c++/coda-oss-lite.vcxproj.filters @@ -1062,6 +1062,9 @@ sys + + sys + diff --git a/modules/c++/config/include/config/disable_compiler_warnings.h b/modules/c++/config/include/config/disable_compiler_warnings.h index a87d281089..a3b1a5125e 100644 --- a/modules/c++/config/include/config/disable_compiler_warnings.h +++ b/modules/c++/config/include/config/disable_compiler_warnings.h @@ -25,7 +25,7 @@ #include "compiler_extensions.h" -#if _MSC_VER +#if defined(_MSC_VER) // We don't care about any padding added to structs #pragma warning(disable: 4820) // '...': '...' bytes padding added after data member '...' @@ -38,6 +38,12 @@ // ??? #pragma warning(disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified + +#elif defined(__GNUC__) || defined(__clang__) + +// don't care about compatibility between different -std=c++nn values +CODA_OSS_disable_warning(-Wnoexcept-type) + #endif // _MSC_VER #endif // CODA_OSS_config_disable_compiler_warnings_h_INCLUDED_ diff --git a/modules/c++/io/include/io/ByteStream.h b/modules/c++/io/include/io/ByteStream.h index fe2efe1844..a64b7efc82 100644 --- a/modules/c++/io/include/io/ByteStream.h +++ b/modules/c++/io/include/io/ByteStream.h @@ -68,20 +68,20 @@ struct CODA_OSS_API ByteStream : public SeekableInputStream, public SeekableOutp } virtual - sys::Off_T tell() + sys::Off_T tell() override { return mPosition; } virtual - sys::Off_T seek(sys::Off_T offset, Whence whence); + sys::Off_T seek(sys::Off_T offset, Whence whence) override; /*! * Returns the available bytes to read from the stream * \return the available bytes to read */ virtual - sys::Off_T available(); + sys::Off_T available() override; using OutputStream::write; using InputStream::streamTo; @@ -92,7 +92,7 @@ struct CODA_OSS_API ByteStream : public SeekableInputStream, public SeekableOutp * \param size the number of bytes to write to the stream */ virtual - void write(const void* buffer, size_t size); + void write(const void* buffer, size_t size) override; void reset() { @@ -132,7 +132,7 @@ struct CODA_OSS_API ByteStream : public SeekableInputStream, public SeekableOutp * \throw IoException * \return The number of bytes read */ - virtual sys::SSize_T readImpl(void* buffer, size_t len); + virtual sys::SSize_T readImpl(void* buffer, size_t len) override; private: std::vector mData; diff --git a/modules/c++/io/include/io/CountingStreams.h b/modules/c++/io/include/io/CountingStreams.h index bebca3a5f5..9e7707f378 100644 --- a/modules/c++/io/include/io/CountingStreams.h +++ b/modules/c++/io/include/io/CountingStreams.h @@ -48,7 +48,7 @@ struct CODA_OSS_API CountingOutputStream : public ProxyOutputStream * \param buffer The byte array to write to the stream * \param len The length of the byte array to write to the stream */ - virtual void write(const void* buffer, size_t len) + virtual void write(const void* buffer, size_t len) override { ProxyOutputStream::write(buffer, len); mByteCount += len; diff --git a/modules/c++/io/include/io/DataStream.h b/modules/c++/io/include/io/DataStream.h index 599a609e17..ec42d215eb 100644 --- a/modules/c++/io/include/io/DataStream.h +++ b/modules/c++/io/include/io/DataStream.h @@ -76,7 +76,7 @@ struct DataStream: public io::Serializable * Outputs this object into an output stream. * \param os the OutputStream to write to */ - virtual void serialize(io::OutputStream& os) + virtual void serialize(io::OutputStream& os) override { mStringStream.streamTo(os); } @@ -85,7 +85,7 @@ struct DataStream: public io::Serializable * Unpack this input stream to the object * \param is Stream to read object from */ - virtual void deserialize(io::InputStream& is) + virtual void deserialize(io::InputStream& is) override { is.streamTo(mStringStream); } diff --git a/modules/c++/io/include/io/DbgStream.h b/modules/c++/io/include/io/DbgStream.h index b582104099..0750f84566 100644 --- a/modules/c++/io/include/io/DbgStream.h +++ b/modules/c++/io/include/io/DbgStream.h @@ -89,7 +89,7 @@ struct DbgStream : public OutputStream * \param len The length * \throw IOException */ - virtual void write(const void* buffer, sys::Size_T len) + virtual void write(const void* buffer, sys::Size_T len) override { if (mOn) { diff --git a/modules/c++/io/include/io/FileInputStreamOS.h b/modules/c++/io/include/io/FileInputStreamOS.h index 14389ba1e5..6c16641b7d 100644 --- a/modules/c++/io/include/io/FileInputStreamOS.h +++ b/modules/c++/io/include/io/FileInputStreamOS.h @@ -99,7 +99,7 @@ struct CODA_OSS_API FileInputStreamOS : public SeekableInputStream * \return number of bytes which are readable * */ - virtual sys::Off_T available(); + virtual sys::Off_T available() override; /*! * Report whether or not the file is open @@ -130,7 +130,7 @@ struct CODA_OSS_API FileInputStreamOS : public SeekableInputStream * Go to the offset at the location specified. * \return The number of bytes between off and our origin. */ - virtual sys::Off_T seek(sys::Off_T off, Whence whence) + virtual sys::Off_T seek(sys::Off_T off, Whence whence) override { int from = sys::File::FROM_CURRENT; switch (whence) @@ -154,7 +154,7 @@ struct CODA_OSS_API FileInputStreamOS : public SeekableInputStream * Tell the current offset * \return The byte offset */ - virtual sys::Off_T tell() + virtual sys::Off_T tell() override { return mFile.getCurrentOffset(); } @@ -175,7 +175,7 @@ struct CODA_OSS_API FileInputStreamOS : public SeekableInputStream * \return The number of bytes read * */ - virtual sys::SSize_T readImpl(void* buffer, size_t len); + virtual sys::SSize_T readImpl(void* buffer, size_t len) override; }; } diff --git a/modules/c++/io/include/io/FileOutputStreamOS.h b/modules/c++/io/include/io/FileOutputStreamOS.h index 56fa70dd6e..9156c36f31 100644 --- a/modules/c++/io/include/io/FileOutputStreamOS.h +++ b/modules/c++/io/include/io/FileOutputStreamOS.h @@ -95,16 +95,16 @@ class FileOutputStreamOS : public SeekableOutputStream int creationFlags = sys::File::CREATE | sys::File::TRUNCATE); //! Close the file - void close() + void close() override { mFile.close(); } - virtual void flush(); + virtual void flush() override; - sys::Off_T seek(sys::Off_T offset, io::Seekable::Whence whence); + sys::Off_T seek(sys::Off_T offset, io::Seekable::Whence whence) override; - sys::Off_T tell(); + sys::Off_T tell() override; using OutputStream::write; @@ -116,7 +116,7 @@ class FileOutputStreamOS : public SeekableOutputStream * \param len the length of bytes to write * \throw IoException */ - virtual void write(const void* buffer, size_t len); + virtual void write(const void* buffer, size_t len) override; }; } diff --git a/modules/c++/io/include/io/NullStreams.h b/modules/c++/io/include/io/NullStreams.h index 40f7ed37fd..3243185305 100644 --- a/modules/c++/io/include/io/NullStreams.h +++ b/modules/c++/io/include/io/NullStreams.h @@ -41,19 +41,19 @@ struct NullInputStream : public InputStream { } - virtual sys::Off_T available() + virtual sys::Off_T available() override { return mAvailable; } virtual sys::SSize_T readln(sys::byte *cStr, - const sys::Size_T strLenPlusNullByte) + const sys::Size_T strLenPlusNullByte) override { return read(cStr, strLenPlusNullByte); } virtual sys::SSize_T streamTo(OutputStream& soi, - sys::SSize_T numBytes = IS_END) + sys::SSize_T numBytes = IS_END) override { const sys::SSize_T toProcess = (numBytes == IS_END) ? numBytes : (mAvailable >= numBytes ? numBytes : mAvailable); @@ -77,7 +77,7 @@ struct NullInputStream : public InputStream memset(buffer, 0, len); } - virtual sys::SSize_T readImpl(void* buffer, size_t len) + virtual sys::SSize_T readImpl(void* buffer, size_t len) override { const auto numToRead = mAvailable >= gsl::narrow(len) ? len : gsl::narrow(mAvailable); @@ -108,11 +108,11 @@ struct NullOutputStream : public OutputStream { } - virtual void write(const void* , size_t ) + virtual void write(const void* , size_t ) override { } - virtual void flush() + virtual void flush() override { } }; diff --git a/modules/c++/io/include/io/PipeStream.h b/modules/c++/io/include/io/PipeStream.h index eab02769eb..0a6b910355 100644 --- a/modules/c++/io/include/io/PipeStream.h +++ b/modules/c++/io/include/io/PipeStream.h @@ -76,7 +76,7 @@ struct PipeStream : InputStream * (default 0 means read until max or newline) */ virtual sys::SSize_T readln(sys::byte *cStr, - const sys::Size_T strLenPlusNullByte = 0); + const sys::Size_T strLenPlusNullByte = 0) override; /*! * The streaming occurs as follows: If the numBytes is IS_END, @@ -90,7 +90,7 @@ struct PipeStream : InputStream * input stream to the output stream */ virtual sys::SSize_T streamTo(OutputStream& soi, - sys::SSize_T numBytes = IS_END); + sys::SSize_T numBytes = IS_END) override; PipeStream(const PipeStream&) = delete; PipeStream& operator=(const PipeStream&) = delete; @@ -99,7 +99,7 @@ struct PipeStream : InputStream /*! * \brief returns the requested size in bytes from the stream */ - virtual sys::SSize_T readImpl(void* buffer, size_t len); + virtual sys::SSize_T readImpl(void* buffer, size_t len) override; sys::ExecPipe mExecPipe; diff --git a/modules/c++/io/include/io/ProxyStreams.h b/modules/c++/io/include/io/ProxyStreams.h index 806149ddea..7ec3c11c7c 100644 --- a/modules/c++/io/include/io/ProxyStreams.h +++ b/modules/c++/io/include/io/ProxyStreams.h @@ -47,7 +47,7 @@ struct CODA_OSS_API ProxyInputStream : public InputStream mProxy.release(); } - virtual sys::Off_T available() + virtual sys::Off_T available() override { return mProxy->available(); } @@ -61,7 +61,7 @@ struct CODA_OSS_API ProxyInputStream : public InputStream } protected: - virtual sys::SSize_T readImpl(void* buffer, size_t len) + virtual sys::SSize_T readImpl(void* buffer, size_t len) override { return mProxy->read(buffer, len); } @@ -93,17 +93,17 @@ struct CODA_OSS_API ProxyOutputStream : public OutputStream using OutputStream::write; - virtual void write(const void* buffer, size_t len) + virtual void write(const void* buffer, size_t len) override { mProxy->write(buffer, len); } - virtual void flush() + virtual void flush() override { mProxy->flush(); } - virtual void close() + virtual void close() override { mProxy->close(); } @@ -152,7 +152,7 @@ struct CODA_OSS_API ToggleOutputStream : public io::ProxyOutputStream return mEnabled; } - void close() + void close() override { if (mEnabled && mPtr) mPtr->close(); diff --git a/modules/c++/io/include/io/RotatingFileOutputStream.h b/modules/c++/io/include/io/RotatingFileOutputStream.h index c1c30dcefb..c766bfdb68 100644 --- a/modules/c++/io/include/io/RotatingFileOutputStream.h +++ b/modules/c++/io/include/io/RotatingFileOutputStream.h @@ -46,7 +46,7 @@ struct CODA_OSS_API RotatingFileOutputStream : public CountingOutputStream using CountingOutputStream::write; - virtual void write(const void* buffer, size_t len); + virtual void write(const void* buffer, size_t len) override; protected: std::string mFilename; diff --git a/modules/c++/io/include/io/SerializableFile.h b/modules/c++/io/include/io/SerializableFile.h index 7895bf1c45..f4244586b6 100644 --- a/modules/c++/io/include/io/SerializableFile.h +++ b/modules/c++/io/include/io/SerializableFile.h @@ -55,13 +55,13 @@ class SerializableFile: public Serializable /*! * Transfer this object into a byte stream */ - void serialize(io::OutputStream& os); + void serialize(io::OutputStream& os) override; /*! * Unpack this input stream to the object * \param is Stream to read object from */ - void deserialize(io::InputStream& is); + void deserialize(io::InputStream& is) override; protected: std::string mFilename; diff --git a/modules/c++/io/include/io/StandardStreams.h b/modules/c++/io/include/io/StandardStreams.h index 633fd7a8de..791ffded7c 100644 --- a/modules/c++/io/include/io/StandardStreams.h +++ b/modules/c++/io/include/io/StandardStreams.h @@ -62,12 +62,12 @@ struct StandardOutStream final : public OutputStream * \param len the length of bytes to read * \throw except::IOException */ - virtual void write(const void* buffer, size_t len); + virtual void write(const void* buffer, size_t len) override; /*! * Flushes stdout */ - virtual void flush(); + virtual void flush() override; using OutputStream::write; using OutputStream::writeln; @@ -91,12 +91,12 @@ struct StandardErrStream final : public OutputStream * \param len the length of bytes to read * \throw except::IOException */ - virtual void write(const void* buffer, sys::Size_T len); + virtual void write(const void* buffer, sys::Size_T len) override; /*! * Flushes stderr */ - virtual void flush(); + virtual void flush() override; protected: _STDSTREAM_DECLARE_MUTEX_SEMICOLON_ diff --git a/modules/c++/io/include/io/StringStream.h b/modules/c++/io/include/io/StringStream.h index d8a03ddb9c..80e147d51b 100644 --- a/modules/c++/io/include/io/StringStream.h +++ b/modules/c++/io/include/io/StringStream.h @@ -63,12 +63,12 @@ struct StringStreamT final : public SeekableBidirectionalStream return mData; } - sys::Off_T tell() + sys::Off_T tell() override { return mData.tellg(); } - sys::Off_T seek(sys::Off_T offset, Whence whence) + sys::Off_T seek(sys::Off_T offset, Whence whence) override { std::ios::seekdir flags = std::ios::cur; switch (whence) @@ -94,7 +94,7 @@ struct StringStreamT final : public SeekableBidirectionalStream * Returns the available bytes to read from the stream * \return the available bytes to read */ - sys::Off_T available() + sys::Off_T available() override { const auto where = tell(); @@ -112,7 +112,7 @@ struct StringStreamT final : public SeekableBidirectionalStream * \param buffer the data to write to the stream * \param size the number of bytes to write to the stream */ - void write(const void* buffer, sys::Size_T size) + void write(const void* buffer, sys::Size_T size) override { auto buffer_ = static_cast(buffer); mData.write(buffer_, gsl::narrow(size)); diff --git a/modules/c++/mem/include/mem/ComplexView.h b/modules/c++/mem/include/mem/ComplexView.h index f43ae8c5ae..6b8a60c0dc 100644 --- a/modules/c++/mem/include/mem/ComplexView.h +++ b/modules/c++/mem/include/mem/ComplexView.h @@ -35,6 +35,7 @@ #include #include "coda_oss/span.h" +#include "config/disable_compiler_warnings.h" namespace mem { diff --git a/modules/c++/mem/tests/ScratchVisualization.cpp b/modules/c++/mem/tests/ScratchVisualization.cpp index d9058e0f75..2585f7473f 100644 --- a/modules/c++/mem/tests/ScratchVisualization.cpp +++ b/modules/c++/mem/tests/ScratchVisualization.cpp @@ -329,7 +329,7 @@ int main(int argc, char** argv) const cli::Results* options(parser.parse(argc, argv)); const std::string testType(options->get("test")); - srand((unsigned)time(0)); + srand((unsigned)time(nullptr)); std::ofstream htmlFile; htmlFile.open("scratch_release.html"); diff --git a/modules/c++/mem/unittests/test_scratch_memory.cpp b/modules/c++/mem/unittests/test_scratch_memory.cpp index 421f4eb052..8ef51ee4fd 100644 --- a/modules/c++/mem/unittests/test_scratch_memory.cpp +++ b/modules/c++/mem/unittests/test_scratch_memory.cpp @@ -254,7 +254,7 @@ struct Operation TEST_CASE(testReleaseConcurrentKeys) { - srand((unsigned)time(0)); + srand((unsigned)time(nullptr)); mem::ScratchMemory scratch; std::vector operations; @@ -344,7 +344,7 @@ TEST_CASE(testReleaseConcurrentKeys) TEST_CASE(testReleaseConnectedKeys) { - srand((unsigned)time(0)); + srand((unsigned)time(nullptr)); mem::ScratchMemory scratch; std::vector operations; @@ -434,7 +434,7 @@ TEST_CASE(testReleaseConnectedKeys) TEST_CASE(testGenerateBuffersForRelease) { - srand((unsigned)time(0)); + srand((unsigned)time(nullptr)); for (unsigned int run = 0; run < 50; ++run) { diff --git a/modules/c++/mt/include/mt/BalancedRunnable1D.h b/modules/c++/mt/include/mt/BalancedRunnable1D.h index dc2248df01..c7af782fb7 100644 --- a/modules/c++/mt/include/mt/BalancedRunnable1D.h +++ b/modules/c++/mt/include/mt/BalancedRunnable1D.h @@ -74,7 +74,7 @@ class BalancedRunnable1D : public sys::Runnable { } - virtual void run() + virtual void run() override { while (true) { diff --git a/modules/c++/mt/include/mt/CPUAffinityThreadInitializerLinux.h b/modules/c++/mt/include/mt/CPUAffinityThreadInitializerLinux.h index 8fb26d8bab..ea3349939a 100644 --- a/modules/c++/mt/include/mt/CPUAffinityThreadInitializerLinux.h +++ b/modules/c++/mt/include/mt/CPUAffinityThreadInitializerLinux.h @@ -58,7 +58,7 @@ class CPUAffinityThreadInitializerLinux : * * \throws if setting the thread affinity fails */ - virtual void initialize(); + virtual void initialize() override; private: std::unique_ptr mCPU; diff --git a/modules/c++/mt/include/mt/GenerationThreadPool.h b/modules/c++/mt/include/mt/GenerationThreadPool.h index f22b6be4b0..6a2e53d2fb 100644 --- a/modules/c++/mt/include/mt/GenerationThreadPool.h +++ b/modules/c++/mt/include/mt/GenerationThreadPool.h @@ -63,7 +63,7 @@ namespace mt // If we have a thread initializer, tie down our handler to a CPU virtual void initialize(); - virtual void run(); + virtual void run() override; }; class CODA_OSS_API GenerationThreadPool : public BasicThreadPool @@ -83,7 +83,7 @@ namespace mt GenerationThreadPool(const GenerationThreadPool&) = delete; GenerationThreadPool& operator=(const GenerationThreadPool&) = delete; - virtual TiedRequestHandler *newRequestHandler() + virtual TiedRequestHandler *newRequestHandler() override { TiedRequestHandler* handler = BasicThreadPool::newRequestHandler(); assert(handler != nullptr); diff --git a/modules/c++/mt/include/mt/GenericRequestHandler.h b/modules/c++/mt/include/mt/GenericRequestHandler.h index 0382594de5..5483cc4cd7 100644 --- a/modules/c++/mt/include/mt/GenericRequestHandler.h +++ b/modules/c++/mt/include/mt/GenericRequestHandler.h @@ -55,7 +55,7 @@ class GenericRequestHandler : public sys::Runnable /*! * Dequeue and run requests in a non-terminating loop */ - virtual void run(); + virtual void run() override; protected: RunnableRequestQueue *mRequest; diff --git a/modules/c++/mt/include/mt/ThreadGroup.h b/modules/c++/mt/include/mt/ThreadGroup.h index fa06ae9bcf..7bba1cf263 100644 --- a/modules/c++/mt/include/mt/ThreadGroup.h +++ b/modules/c++/mt/include/mt/ThreadGroup.h @@ -178,7 +178,7 @@ struct CODA_OSS_API ThreadGroup /*! * Call run() on the Runnable passed to createThread */ - virtual void run(); + virtual void run() override; private: std::unique_ptr mRunnable; diff --git a/modules/c++/mt/include/mt/WorkSharingBalancedRunnable1D.h b/modules/c++/mt/include/mt/WorkSharingBalancedRunnable1D.h index 48a83e48f9..dd8e4553de 100644 --- a/modules/c++/mt/include/mt/WorkSharingBalancedRunnable1D.h +++ b/modules/c++/mt/include/mt/WorkSharingBalancedRunnable1D.h @@ -99,7 +99,7 @@ struct WorkSharingBalancedRunnable1D : public sys::Runnable WorkSharingBalancedRunnable1D(WorkSharingBalancedRunnable1D&&) = default; WorkSharingBalancedRunnable1D& operator=(WorkSharingBalancedRunnable1D&&) = delete; - virtual void run() + virtual void run() override { // Operate over this thread's range processElements(mCounter, mEndElement); diff --git a/modules/c++/mt/source/CPUAffinityInitializerLinux.cpp b/modules/c++/mt/source/CPUAffinityInitializerLinux.cpp index bc5cbdd8a8..01181be6b7 100644 --- a/modules/c++/mt/source/CPUAffinityInitializerLinux.cpp +++ b/modules/c++/mt/source/CPUAffinityInitializerLinux.cpp @@ -60,7 +60,7 @@ class AvailableCPUProvider : public AbstractNextCPUProviderLinux { } - virtual std::unique_ptr nextCPU() + virtual std::unique_ptr nextCPU() override { if (mNextCPUIndex >= mCPUs.size()) { @@ -87,7 +87,7 @@ class OffsetCPUProvider : public AbstractNextCPUProviderLinux { } - virtual std::unique_ptr nextCPU() + virtual std::unique_ptr nextCPU() override { std::unique_ptr mask(new sys::ScopedCPUMaskUnix()); CPU_SET_S(mNextCPU++, mask->getSize(), mask->getMask()); diff --git a/modules/c++/mt/tests/MTSingletonTest.cpp b/modules/c++/mt/tests/MTSingletonTest.cpp index 86405f3a03..0488595271 100644 --- a/modules/c++/mt/tests/MTSingletonTest.cpp +++ b/modules/c++/mt/tests/MTSingletonTest.cpp @@ -51,7 +51,7 @@ class StopsWhenEmpty : public GenericRequestHandler { } - void run() + void run() override { while (true) { @@ -101,7 +101,7 @@ class Thespian : public Runnable virtual ~Thespian() { } - void run() + void run() override { //__debugln__(FmtX("[%s]:", mName.c_str())); doLines(); @@ -122,7 +122,7 @@ class Soothsayer : public Thespian { } - void doLines() + void doLines() override { //__warning__("Beware the ides of March."); } diff --git a/modules/c++/mt/tests/ThreadExceptionTest.cpp b/modules/c++/mt/tests/ThreadExceptionTest.cpp index 189f12f275..efc5ee9853 100644 --- a/modules/c++/mt/tests/ThreadExceptionTest.cpp +++ b/modules/c++/mt/tests/ThreadExceptionTest.cpp @@ -29,7 +29,7 @@ class PrintChar : public sys::Runnable { } - virtual void run() + virtual void run() override { print(a); } @@ -61,7 +61,7 @@ class AddInts : public sys::Runnable { } - virtual void run() + virtual void run() override { add(x,y); } @@ -88,7 +88,7 @@ class ConcatStr: public sys::Runnable { } - virtual void run() + virtual void run() override { printConcat(x,y); } diff --git a/modules/c++/mt/unittests/ThreadGroupTest.cpp b/modules/c++/mt/unittests/ThreadGroupTest.cpp index 9622600560..09641ef551 100644 --- a/modules/c++/mt/unittests/ThreadGroupTest.cpp +++ b/modules/c++/mt/unittests/ThreadGroupTest.cpp @@ -41,7 +41,7 @@ struct MyRunTask final : public sys::Runnable (*num_deleted)++; } - virtual void run() + virtual void run() override { while (result == 1) result = *state; diff --git a/modules/c++/re/include/re/RegexPredicate.h b/modules/c++/re/include/re/RegexPredicate.h index b34f9cfb3e..ffccf71afc 100644 --- a/modules/c++/re/include/re/RegexPredicate.h +++ b/modules/c++/re/include/re/RegexPredicate.h @@ -37,7 +37,7 @@ struct RegexPredicate : public sys::FilePredicate mRegex.compile(match); } - bool operator()(const std::string& filename) const + bool operator()(const std::string& filename) const override { return mRegex.matches(filename); } diff --git a/modules/c++/str/include/str/utf8.h b/modules/c++/str/include/str/utf8.h index c4e2666a8d..27baba0859 100644 --- a/modules/c++/str/include/str/utf8.h +++ b/modules/c++/str/include/str/utf8.h @@ -391,7 +391,7 @@ class invalid_code_point final : public exception invalid_code_point(uint32_t cp) : cp(cp) { } - virtual const char* what() const noexcept + virtual const char* what() const noexcept override { return "Invalid code point"; } @@ -409,7 +409,7 @@ class invalid_utf8 final : public exception invalid_utf8(uint8_t u) : u8(u) { } - virtual const char* what() const noexcept + virtual const char* what() const noexcept override { return "Invalid UTF-8"; } @@ -427,7 +427,7 @@ class invalid_utf16 final : public exception invalid_utf16(uint16_t u) : u16(u) { } - virtual const char* what() const noexcept + virtual const char* what() const noexcept override { return "Invalid UTF-16"; } @@ -440,7 +440,7 @@ class invalid_utf16 final : public exception class not_enough_room final : public exception { public: - virtual const char* what() const noexcept + virtual const char* what() const noexcept override { return "Not enough space"; } diff --git a/modules/c++/sys/include/sys/ConditionVarPosix.h b/modules/c++/sys/include/sys/ConditionVarPosix.h index b5aef09461..2144ac63d8 100644 --- a/modules/c++/sys/include/sys/ConditionVarPosix.h +++ b/modules/c++/sys/include/sys/ConditionVarPosix.h @@ -66,17 +66,17 @@ class ConditionVarPosix final : public ConditionVarInterface /*! * Acquire the lock */ - virtual void acquireLock(); + virtual void acquireLock() override; /*! * Drop (release) the lock */ - virtual void dropLock(); + virtual void dropLock() override; /*! * Signal using pthread_cond_signal */ - virtual void signal(); + virtual void signal() override; /*! * Wait using pthread_cond_wait @@ -86,7 +86,7 @@ class ConditionVarPosix final : public ConditionVarInterface * certain systems, undefined/unfavorable behavior may * result. */ - virtual void wait(); + virtual void wait() override; /*! * Wait using pthread_cond_timed_wait. I kept this and the above @@ -99,12 +99,12 @@ class ConditionVarPosix final : public ConditionVarInterface * certain systems, undefined/unfavorable behavior may * result. */ - virtual void wait(double seconds); + virtual void wait(double seconds) override; /*! * Broadcast (notify all) */ - virtual void broadcast(); + virtual void broadcast() override; /*! * Returns the native type. diff --git a/modules/c++/sys/include/sys/Err.h b/modules/c++/sys/include/sys/Err.h index 161c27618a..c7163f35bd 100644 --- a/modules/c++/sys/include/sys/Err.h +++ b/modules/c++/sys/include/sys/Err.h @@ -168,7 +168,7 @@ struct SocketErr : public Err } //! Redefined for socket errors - virtual int getLast() const; + virtual int getLast() const override; }; diff --git a/modules/c++/sys/include/sys/Exec.h b/modules/c++/sys/include/sys/Exec.h index 27eeaedde6..baee2e581e 100644 --- a/modules/c++/sys/include/sys/Exec.h +++ b/modules/c++/sys/include/sys/Exec.h @@ -62,7 +62,7 @@ class Exec : public sys::Runnable /*! * Execute a command */ - virtual void run() + virtual void run() override { if (::system(mCmd.c_str()) == -1) { @@ -96,7 +96,7 @@ struct ExecPipe : Exec } //! start the child process and connect the pipe - virtual void run() + virtual void run() override { mOutStream = openPipe(mCmd, "r"); if (mOutStream == nullptr) diff --git a/modules/c++/sys/include/sys/File.h b/modules/c++/sys/include/sys/File.h index 613e289368..0eacf0e320 100644 --- a/modules/c++/sys/include/sys/File.h +++ b/modules/c++/sys/include/sys/File.h @@ -20,8 +20,17 @@ * */ -#ifndef __SYS_FILE_H__ -#define __SYS_FILE_H__ +#ifndef CODA_OSS_sys_File_h_INCLUDED_ +#define CODA_OSS_sys_File_h_INCLUDED_ +#pragma once + +#include +#include +#include +#include + +#include +#include #include "sys/Conf.h" #include "sys/SystemException.h" @@ -100,12 +109,22 @@ struct CODA_OSS_API File { create(path.getPath(), accessFlags, creationFlags); } + File(std::nothrow_t, const coda_oss::filesystem::path& path, + int accessFlags = READ_ONLY, int creationFlags = EXISTING) noexcept // caller MUST check isOpen() + { + create(std::nothrow, path, accessFlags, creationFlags); + } File(const Path& parent, std::string name, int accessFlags = READ_ONLY, int creationFlags = EXISTING) { create(parent.join(name).getPath(), accessFlags, creationFlags); } + File(std::nothrow_t, const coda_oss::filesystem::path& parent, const coda_oss::filesystem::path& name, + int accessFlags = READ_ONLY, int creationFlags = EXISTING) noexcept // caller MUST check isOpen() + { + create(std::nothrow, parent / name, accessFlags, creationFlags); + } /*! * Constructor. Initializes to a file. @@ -128,6 +147,11 @@ struct CODA_OSS_API File close(); } + File(const File&) = default; + File& operator=(const File&) = default; + File(File&&) = default; + File& operator=(File&&) = default; + /*! * Is the file open? * \return true if open, false if invalid handle @@ -162,8 +186,13 @@ struct CODA_OSS_API File * \param accessFlags File access flags * \param creationFlags File creation flags */ - void create(const std::string& str, int accessFlags, - int creationFlags); + void create(const std::string& str, int accessFlags, int creationFlags); + void create(std::nothrow_t, const coda_oss::filesystem::path& path, + int accessFlags, int creationFlags) // caller MUST check isOpen() + { + mHandle = createFile(path, accessFlags, creationFlags); + mPath = path.string(); + } /*! * Read from the File into a buffer 'size' bytes. @@ -235,10 +264,35 @@ struct CODA_OSS_API File protected: _SYS_HANDLE_TYPE mHandle = SYS_INVALID_HANDLE; std::string mPath; + + static _SYS_HANDLE_TYPE createFile(const coda_oss::filesystem::path&, int accessFlags, int creationFlags) noexcept; }; -} +// These routines use sys::expandEnvironmentVariables() if the initial open attempt fails. +CODA_OSS_API File make_File(const coda_oss::filesystem::path&, int accessFlags = File::READ_ONLY, int creationFlags = File::EXISTING); +CODA_OSS_API File make_File(const coda_oss::filesystem::path& parent, const coda_oss::filesystem::path& name, + int accessFlags = File::READ_ONLY, int creationFlags = File::EXISTING); + +// Call sys::expandEnvironmentVariables() if the initial fopen() fails. +CODA_OSS_API FILE* fopen(const coda_oss::filesystem::path&, const std::string& mode); +CODA_OSS_API int open(const coda_oss::filesystem::path&, int flags); +CODA_OSS_API int open(const coda_oss::filesystem::path&, int flags, int mode); +CODA_OSS_API int close(int fd); // needed to close a FD from open() + +#ifdef _WIN32 +#define CODA_OSS_stat _stat +#else +#define CODA_OSS_stat stat #endif +// Call sys::expandEnvironmentVariables() if the initial stat() attempt fails. +CODA_OSS_API int stat(const coda_oss::filesystem::path&, struct CODA_OSS_stat &buffer); + +// Call sys::expandEnvironmentVariables() if the initial open attempt fails. +CODA_OSS_API std::ifstream make_ifstream(const coda_oss::filesystem::path&, std::ios_base::openmode mode = std::ios_base::in); // https://en.cppreference.com/w/cpp/io/basic_ifstream/basic_ifstream +CODA_OSS_API void open(std::ifstream&, const coda_oss::filesystem::path&, std::ios_base::openmode mode = std::ios_base::in); // https://en.cppreference.com/w/cpp/io/basic_ifstream/open + +} +#endif // CODA_OSS_sys_File_h_INCLUDED_ diff --git a/modules/c++/sys/include/sys/FileFinder.h b/modules/c++/sys/include/sys/FileFinder.h index d3ffd5600b..be9ae0bcf8 100644 --- a/modules/c++/sys/include/sys/FileFinder.h +++ b/modules/c++/sys/include/sys/FileFinder.h @@ -51,7 +51,7 @@ struct FilePredicate struct ExistsPredicate : FilePredicate { virtual ~ExistsPredicate() = default; - virtual bool operator()(const std::string& entry) const; + virtual bool operator()(const std::string& entry) const override; }; /** @@ -60,7 +60,7 @@ struct ExistsPredicate : FilePredicate struct FileOnlyPredicate: public FilePredicate { virtual ~FileOnlyPredicate() = default; - virtual bool operator()(const std::string& entry) const; + virtual bool operator()(const std::string& entry) const override; }; /** @@ -69,7 +69,7 @@ struct FileOnlyPredicate: public FilePredicate struct DirectoryOnlyPredicate: public FilePredicate { virtual ~DirectoryOnlyPredicate() = default; - virtual bool operator()(const std::string& entry) const; + virtual bool operator()(const std::string& entry) const override; }; /** @@ -78,7 +78,7 @@ struct DirectoryOnlyPredicate: public FilePredicate struct FragmentPredicate : public FilePredicate { FragmentPredicate(const std::string& fragment, bool ignoreCase = true); - bool operator()(const std::string& entry) const; + bool operator()(const std::string& entry) const override; private: std::string mFragment; @@ -96,7 +96,7 @@ struct FragmentPredicate : public FilePredicate struct ExtensionPredicate: public FileOnlyPredicate { ExtensionPredicate(const std::string& ext, bool ignoreCase = true); - bool operator()(const std::string& filename) const; + bool operator()(const std::string& filename) const override; private: std::string mExt; @@ -111,7 +111,7 @@ struct NotPredicate : public FilePredicate NotPredicate(FilePredicate* filter, bool ownIt = false); virtual ~NotPredicate(); - virtual bool operator()(const std::string& entry) const; + virtual bool operator()(const std::string& entry) const override; protected: typedef std::pair PredicatePair; @@ -132,7 +132,7 @@ struct LogicalPredicate : public FilePredicate sys::LogicalPredicate& addPredicate(FilePredicate* filter, bool ownIt = false); - virtual bool operator()(const std::string& entry) const; + virtual bool operator()(const std::string& entry) const override; protected: bool mOrOperator = true; diff --git a/modules/c++/sys/include/sys/LocalDateTime.h b/modules/c++/sys/include/sys/LocalDateTime.h index 5f36e3c58c..5effbcaa69 100644 --- a/modules/c++/sys/include/sys/LocalDateTime.h +++ b/modules/c++/sys/include/sys/LocalDateTime.h @@ -39,15 +39,15 @@ class CODA_OSS_API LocalDateTime : public DateTime int mDST; //! @brief Set members from the tm struct value. - virtual void fromMillis(const tm& t); + virtual void fromMillis(const tm& t) override; /** * @brief Set the millis value from the members */ - virtual void toMillis(); + virtual void toMillis() override; // ! Given seconds since the epoch, provides the local time - virtual void getTime(time_t numSecondsSinceEpoch, tm& t) const; + virtual void getTime(time_t numSecondsSinceEpoch, tm& t) const override; public: /*! diff --git a/modules/c++/sys/include/sys/MutexCpp11.h b/modules/c++/sys/include/sys/MutexCpp11.h index 1a3438a7ec..b95738d349 100644 --- a/modules/c++/sys/include/sys/MutexCpp11.h +++ b/modules/c++/sys/include/sys/MutexCpp11.h @@ -50,12 +50,12 @@ struct MutexCpp11 final : public MutexInterface /*! * Lock the mutex. */ - virtual void lock(); + virtual void lock() override; /*! * Unlock the mutex. */ - virtual void unlock(); + virtual void unlock() override; /*! * Returns the native type. diff --git a/modules/c++/sys/include/sys/MutexPosix.h b/modules/c++/sys/include/sys/MutexPosix.h index e954c33129..8ffbaf88f0 100644 --- a/modules/c++/sys/include/sys/MutexPosix.h +++ b/modules/c++/sys/include/sys/MutexPosix.h @@ -54,12 +54,12 @@ class MutexPosix : public MutexInterface /*! * Lock the mutex. */ - virtual void lock(); + virtual void lock() override; /*! * Unlock the mutex. */ - virtual void unlock(); + virtual void unlock() override; /*! * Returns the native type. diff --git a/modules/c++/sys/include/sys/OSUnix.h b/modules/c++/sys/include/sys/OSUnix.h index 9e94df4902..eb1a52dd36 100644 --- a/modules/c++/sys/include/sys/OSUnix.h +++ b/modules/c++/sys/include/sys/OSUnix.h @@ -38,9 +38,9 @@ struct OSUnix final : public AbstractOS OSUnix() = default; virtual ~OSUnix() = default; - virtual std::string getPlatformName() const; + virtual std::string getPlatformName() const override; - virtual std::string getNodeName() const; + virtual std::string getNodeName() const override; /*! * Get the path delimiter for this operating system. @@ -48,7 +48,7 @@ struct OSUnix final : public AbstractOS * For unix it will be one slash / * \return The path delimiter */ - virtual const char* getDelimiter() const + virtual const char* getDelimiter() const override { return "/"; } @@ -64,64 +64,64 @@ struct OSUnix final : public AbstractOS * \param path The path to check for * \return True if it does, false otherwise */ - virtual bool exists(const std::string& path) const; + virtual bool exists(const std::string& path) const override; /*! * Move file with this path name to the newPath * \return True upon success, false if failure */ virtual bool move(const std::string& path, - const std::string& newPath) const; + const std::string& newPath) const override; /*! * Does this path resolve to a file? * \param path The path * \return True if it does, false if not */ - virtual bool isFile(const std::string& path) const; + virtual bool isFile(const std::string& path) const override; /*! * Does this path resolve to a directory? * \param path The path * \return True if it does, false if not */ - virtual bool isDirectory(const std::string& path) const; + virtual bool isDirectory(const std::string& path) const override; - virtual bool makeDirectory(const std::string& path) const; + virtual bool makeDirectory(const std::string& path) const override; - virtual Pid_T getProcessId() const; + virtual Pid_T getProcessId() const override; /*! * Retrieve the current working directory. * \return The current working directory */ - virtual std::string getCurrentWorkingDirectory() const; + virtual std::string getCurrentWorkingDirectory() const override; /*! * Change the current working directory. * \return true if the directory was changed, otherwise false. */ - virtual bool changeDirectory(const std::string& path) const; + virtual bool changeDirectory(const std::string& path) const override; /*! * Get a suitable temporary file name * \return The file name */ virtual std::string getTempName(const std::string& path = ".", - const std::string& prefix = "TMP") const; + const std::string& prefix = "TMP") const override; /*! * Return the size in bytes of a file * \return The file size */ - virtual sys::Off_T getSize(const std::string& path) const; + virtual sys::Off_T getSize(const std::string& path) const override; /** * Returns the last modified time of the file/directory */ - virtual sys::Off_T getLastModifiedTime(const std::string& path) const; + virtual sys::Off_T getLastModifiedTime(const std::string& path) const override; /*! * This is a system independent sleep function. @@ -130,59 +130,59 @@ struct OSUnix final : public AbstractOS * use nanosleep * \param milliseconds The params */ - virtual void millisleep(int milliseconds) const; + virtual void millisleep(int milliseconds) const override; - virtual std::string operator[](const std::string& s) const; + virtual std::string operator[](const std::string& s) const override; /*! * Get an environment variable */ - virtual std::string getEnv(const std::string& s) const; + virtual std::string getEnv(const std::string& s) const override; /*! * Returns true if environment variable is set, false otherwise */ - virtual bool isEnvSet(const std::string& s) const; + virtual bool isEnvSet(const std::string& s) const override; /*! * Set an environment variable */ virtual void setEnv(const std::string& var, const std::string& val, - bool overwrite); + bool overwrite) override; /*! * Unset an environment variable */ - virtual void unsetEnv(const std::string& var); + virtual void unsetEnv(const std::string& var) override; - virtual std::string getDSOSuffix() const; + virtual std::string getDSOSuffix() const override; /*! * \return the number of logical CPUs present on the machine * (includes hyperthreading) */ - virtual size_t getNumCPUs() const; + virtual size_t getNumCPUs() const override; /*! * \return the number of logical CPUs available. This will be * affected by pinning (e.g. numactl/taskset), and will * always be <= getNumCPUs. */ - virtual size_t getNumCPUsAvailable() const; + virtual size_t getNumCPUsAvailable() const override; /*! * \return the number of physical CPUs present on the machine * (excludes hyperthreading) */ - virtual size_t getNumPhysicalCPUs() const; + virtual size_t getNumPhysicalCPUs() const override; /*! * \return the number of physical CPUs available. This will be * affected by pinning (e.g. numactl/taskset), and will * always be <= getNumPhysicalCPUs. */ - virtual size_t getNumPhysicalCPUsAvailable() const; + virtual size_t getNumPhysicalCPUsAvailable() const override; /*! * Divide the available CPUs (pinned with numactl/taskset) into @@ -199,41 +199,41 @@ struct OSUnix final : public AbstractOS * getNumCPUsAvailable() - getNumPhysicalCPUsAvailable(). */ virtual void getAvailableCPUs(std::vector& physicalCPUs, - std::vector& htCPUs) const; + std::vector& htCPUs) const override; /*! * Create a symlink, pathnames can be either absolute or relative */ virtual void createSymlink(const std::string& origPathname, - const std::string& symlinkPathname) const; + const std::string& symlinkPathname) const override; /*! * Remove a symlink, pathname can be absolute or relative */ - virtual void removeSymlink(const std::string& symlinkPathname) const; + virtual void removeSymlink(const std::string& symlinkPathname) const override; /*! * Get the total RAM and available RAM on the system in megabytes */ - virtual void getMemInfo(size_t& totalPhysMem, size_t& freePhysMem) const; + virtual void getMemInfo(size_t& totalPhysMem, size_t& freePhysMem) const override; /*! * Get the absolute path to the current executable */ virtual std::string getCurrentExecutable( - const std::string& argvPathname="") const; + const std::string& argvPathname="") const override; protected: /*! * Remove file with this pathname */ - virtual void removeFile(const std::string& pathname) const; + virtual void removeFile(const std::string& pathname) const override; /*! * Remove directory with this pathname * NOTE: This will throw if the directory is not empty */ - virtual void removeDirectory(const std::string& pathname) const; + virtual void removeDirectory(const std::string& pathname) const override; }; struct DirectoryUnix final : public AbstractDirectory diff --git a/modules/c++/sys/include/sys/ProcessInterface.h b/modules/c++/sys/include/sys/ProcessInterface.h index 930a514f9d..a93d3c749d 100644 --- a/modules/c++/sys/include/sys/ProcessInterface.h +++ b/modules/c++/sys/include/sys/ProcessInterface.h @@ -60,7 +60,7 @@ template class ProcessInterface : public sys::Runnable virtual void start() = 0; virtual void waitFor() = 0; - virtual void run() = 0; + virtual void run() override = 0; protected: Pid_T mChildProcessID; diff --git a/modules/c++/sys/include/sys/ProcessUnix.h b/modules/c++/sys/include/sys/ProcessUnix.h index f435d33dbb..fed0a83044 100644 --- a/modules/c++/sys/include/sys/ProcessUnix.h +++ b/modules/c++/sys/include/sys/ProcessUnix.h @@ -48,8 +48,8 @@ class ProcessUnix : public ProcessInterface< Pid_T > {} virtual ~ProcessUnix() {} - void start(); - void waitFor(); + void start() override; + void waitFor() override; }; } diff --git a/modules/c++/sys/include/sys/SemaphorePosix.h b/modules/c++/sys/include/sys/SemaphorePosix.h index fc1731d8f0..6afaf6ada0 100644 --- a/modules/c++/sys/include/sys/SemaphorePosix.h +++ b/modules/c++/sys/include/sys/SemaphorePosix.h @@ -44,8 +44,8 @@ class SemaphorePosix : public SemaphoreInterface public: SemaphorePosix(unsigned int count = 0); virtual ~SemaphorePosix(); - void wait(); - void signal(); + void wait() override; + void signal() override; sem_t& getNative(); /*! diff --git a/modules/c++/sys/include/sys/StopWatch.h b/modules/c++/sys/include/sys/StopWatch.h index ac71fde2e0..0eab55a12a 100644 --- a/modules/c++/sys/include/sys/StopWatch.h +++ b/modules/c++/sys/include/sys/StopWatch.h @@ -66,13 +66,13 @@ class RealTimeStopWatch : public StopWatch ~RealTimeStopWatch(); - double start(); + double start() override; - double stop(); + double stop() override; - double pause(); + double pause() override; - void clear(); + void clear() override; }; class CPUStopWatch : public StopWatch @@ -88,13 +88,13 @@ class CPUStopWatch : public StopWatch ~CPUStopWatch(); - double start(); + double start() override; - double stop(); + double stop() override; - double pause(); + double pause() override; - void clear(); + void clear() override; }; } diff --git a/modules/c++/sys/include/sys/ThreadInterface.h b/modules/c++/sys/include/sys/ThreadInterface.h index 70c8d622f0..576f643471 100644 --- a/modules/c++/sys/include/sys/ThreadInterface.h +++ b/modules/c++/sys/include/sys/ThreadInterface.h @@ -212,7 +212,7 @@ struct CODA_OSS_API ThreadInterface : public Runnable * This function is called by start if no target is defined, * allowing the implementor to inherit this class directly */ - virtual void run() + virtual void run() override {} /*! diff --git a/modules/c++/sys/include/sys/ThreadPosix.h b/modules/c++/sys/include/sys/ThreadPosix.h index 596a246fcb..5e5efe8c29 100644 --- a/modules/c++/sys/include/sys/ThreadPosix.h +++ b/modules/c++/sys/include/sys/ThreadPosix.h @@ -96,7 +96,7 @@ struct ThreadPosix : public ThreadInterface /*! * The startpoint for thread processing */ - virtual void start(); + virtual void start() override; /*! @@ -110,12 +110,12 @@ struct ThreadPosix : public ThreadInterface /*! * Calls the native destroy stuff */ - virtual void kill(); + virtual void kill() override; /*! * Join the pthread */ - virtual void join(); + virtual void join() override; /*! * Calls sched_yield to yield the thread of control diff --git a/modules/c++/sys/include/sys/UTCDateTime.h b/modules/c++/sys/include/sys/UTCDateTime.h index 3f58fdaed7..7d4e712078 100644 --- a/modules/c++/sys/include/sys/UTCDateTime.h +++ b/modules/c++/sys/include/sys/UTCDateTime.h @@ -41,10 +41,10 @@ class CODA_OSS_API UTCDateTime : public DateTime /** * @brief Set the millis value from the members */ - virtual void toMillis(); + virtual void toMillis() override; //! Given seconds since the epoch, provides the UTC time - virtual void getTime(time_t numSecondsSinceEpoch, tm& t) const; + virtual void getTime(time_t numSecondsSinceEpoch, tm& t) const override; public: /*! diff --git a/modules/c++/sys/source/AbstractOS.cpp b/modules/c++/sys/source/AbstractOS.cpp index 2304f9261a..5494156802 100644 --- a/modules/c++/sys/source/AbstractOS.cpp +++ b/modules/c++/sys/source/AbstractOS.cpp @@ -415,6 +415,12 @@ std::string AbstractOS::getSpecialEnv(const std::string& envVar) const return str::toString(sys::DateTime::getEpochSeconds()); } + if (envVar == "OSTYPE") + { + // TODO: Mac + return sys::Platform == sys::PlatformType::Linux ? " linux-gnu" : "Windows"; + } + if (envVar == "OSTYPE") { // TODO: Mac diff --git a/modules/c++/sys/source/File.cpp b/modules/c++/sys/source/File.cpp new file mode 100644 index 0000000000..82fe2ab8ab --- /dev/null +++ b/modules/c++/sys/source/File.cpp @@ -0,0 +1,238 @@ +/* ========================================================================= + * This file is part of sys-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * sys-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include "sys/File.h" + +#include + +#ifdef _WIN32 +#include +#endif + +#include "config/compiler_extensions.h" +#include "sys/Path.h" +#include "str/Manip.h" + +sys::File sys::make_File(const coda_oss::filesystem::path& path, int accessFlags, int creationFlags) +{ + sys::File retval(std::nothrow, path, accessFlags, creationFlags); + if (retval.isOpen()) + { + return retval; + } + + const auto checkIfExists = (creationFlags & sys::File::EXISTING) == sys::File::EXISTING; + auto expanded = sys::Path::expandEnvironmentVariables(path.string(), checkIfExists); + if (expanded.empty()) + { + expanded = path.string(); // Throw exception with non-empty path. + } + return sys::File(expanded, accessFlags, creationFlags); +} + +sys::File sys::make_File(const coda_oss::filesystem::path& parent, const coda_oss::filesystem::path& name, + int accessFlags, int creationFlags) +{ + sys::File retval(std::nothrow, parent, name, accessFlags, creationFlags); + if (retval.isOpen()) + { + return retval; + } + + const auto expanded_parent = sys::Path::expandEnvironmentVariables(parent.string(), coda_oss::filesystem::file_type::directory); + // 'name' probably won't work without 'parent' so no need to checkIfExists + const auto expanded_name = sys::Path::expandEnvironmentVariables(name.string(), false /*checkIfExists*/); + + // let the File constructor deal with combining the expanded paths as well as checking for existence. + return sys::File(expanded_parent, expanded_name, accessFlags, creationFlags); +} + +#ifdef _WIN32 +// '...': This function or variable may be unsafe. Consider using _sopen_s instead. +static FILE* fopen_(const std::string& fname, const std::string& mode) +{ + FILE* retval = nullptr; + const auto result = fopen_s(&retval, fname.c_str(), mode.c_str()); + if (result != 0) // "Zero if successful; ..." + { + return nullptr; + } + return retval; +} +#else +static inline FILE* fopen_(const std::string& fname, const std::string& mode) +{ + return fopen(fname.c_str(), mode.c_str()); +} +#endif + +FILE* sys::fopen(const coda_oss::filesystem::path& fname, const std::string& mode) +{ + // Call sys::expandEnvironmentVariables() if the initial fopen() fails. + auto retval = fopen_(fname.string(), mode); + if (retval != nullptr) + { + return retval; + } + + const auto r_pos = mode.find('r'); + const auto checkIfExists = r_pos != mode.npos; + const auto expanded = sys::Path::expandEnvironmentVariables(fname.string(), checkIfExists); + if (expanded.empty()) + { + return nullptr; // no need to even try fopen() + } + return fopen_(expanded, mode); +} + +#ifdef _WIN32 +#define CODA_OSS_open ::_open +#else +#define CODA_OSS_open ::open +#endif + +static inline int open_(const std::string& pathname, int flags) +{ + const auto p = pathname.c_str(); + CODA_OSS_disable_warning_push + #ifdef _MSC_VER + #pragma warning(disable: 4996) // '...': This function or variable may be unsafe. Consider using _sopen_s instead. + #endif + return CODA_OSS_open(p, flags); + CODA_OSS_disable_warning_pop +} +int sys::open(const coda_oss::filesystem::path& path, int flags) +{ + // Call sys::expandEnvironmentVariables() if the initial open() fails. + const auto retval = open_(path.string(), flags); + if (retval > -1) // "On error, -1 is returned ..." + { + return retval; + } + + constexpr bool checkIfExists = false; // TODO: look for O_CREAT ? + const auto expanded = sys::Path::expandEnvironmentVariables(path.string(), checkIfExists); + if (expanded.empty()) + { + return retval; // no need to even try another open() + } + return open_(expanded, flags); +} + +static inline int open_(const std::string& pathname, int flags, int mode) +{ + const auto p = pathname.c_str(); + CODA_OSS_disable_warning_push + #ifdef _MSC_VER + #pragma warning(disable: 4996) // '...': This function or variable may be unsafe. Consider using _sopen_s instead. + #endif + return CODA_OSS_open(p, flags, mode); + CODA_OSS_disable_warning_pop +} +int sys::open(const coda_oss::filesystem::path& path, int flags, int mode) +{ + // Call sys::expandEnvironmentVariables() if the initial open() fails. + const auto retval = open_(path.string(), flags, mode); + if (retval > -1) // "On error, -1 is returned ..." + { + return retval; + } + + constexpr bool checkIfExists = false; // TODO: look for O_CREAT ? + const auto expanded = sys::Path::expandEnvironmentVariables(path.string(), checkIfExists); + if (expanded.empty()) + { + return retval; // no need to even try another open() + } + return open_(expanded, flags, mode); +} +#undef CODA_OSS_open + +#ifdef _WIN32 +#define CODA_OSS_close ::_close +#else +#define CODA_OSS_close ::close +#endif +int sys::close(int fd) +{ + return CODA_OSS_close(fd); +} +#undef CODA_OSS_close + +#ifdef _WIN32 +#define CODA_OSS_stat_ ::_stat +#else +#define CODA_OSS_stat_ ::stat +#endif +static inline int stat_(const std::string& pathname, struct CODA_OSS_stat &buffer) +{ + const auto p = pathname.c_str(); + CODA_OSS_disable_warning_push + #ifdef _MSC_VER + #pragma warning(disable: 4996) // '...': This function or variable may be unsafe. Consider using _sopen_s instead. + #endif + return CODA_OSS_stat_(p, &buffer); + CODA_OSS_disable_warning_pop +} +#undef CODA_OSS_stat_ +int sys::stat(const coda_oss::filesystem::path& path, struct CODA_OSS_stat &buffer) +{ + // Call sys::expandEnvironmentVariables() if the initial stat() fails. + const auto retval = stat_(path.string(), buffer); + if (retval > -1) // "On error, -1 is returned ..." + { + return retval; + } + + constexpr bool checkIfExists = true; + const auto expanded = sys::Path::expandEnvironmentVariables(path.string(), checkIfExists); + if (expanded.empty()) + { + return retval; // no need to even try another stat() + } + return stat_(expanded, buffer); +} + +void sys::open(std::ifstream& ifs, const coda_oss::filesystem::path& path, std::ios_base::openmode mode) +{ + // Call sys::expandEnvironmentVariables() if the initial open() fails. + ifs.open(path.string(), mode); + if (ifs.is_open()) + { + return; + } + + const auto checkIfExists = (mode & std::ios_base::in) == std::ios_base::in; + auto expanded = sys::Path::expandEnvironmentVariables(path.string(), checkIfExists); + if (expanded.empty()) + { + expanded = path.string(); // Throw exception with non-empty path. + } + ifs.open(expanded, mode); +} +std::ifstream sys::make_ifstream(const coda_oss::filesystem::path& path, std::ios_base::openmode mode) +{ + std::ifstream retval; + open(retval, path, mode); + return retval; +} diff --git a/modules/c++/sys/source/FileUnix.cpp b/modules/c++/sys/source/FileUnix.cpp index 21e212f22b..f046f7db3d 100644 --- a/modules/c++/sys/source/FileUnix.cpp +++ b/modules/c++/sys/source/FileUnix.cpp @@ -28,19 +28,23 @@ #include #include -void sys::File::create(const std::string& str, int accessFlags, - int creationFlags) +_SYS_HANDLE_TYPE sys::File::createFile(const coda_oss::filesystem::path& str_, int accessFlags, int creationFlags) noexcept { + const auto str = str_.string(); + if (accessFlags & sys::File::WRITE_ONLY) creationFlags |= sys::File::TRUNCATE; - mHandle = open(str.c_str(), accessFlags | creationFlags, _SYS_DEFAULT_PERM); - + return open(str.c_str(), accessFlags | creationFlags, _SYS_DEFAULT_PERM); +} +void sys::File::create(const std::string& str, int accessFlags, + int creationFlags) +{ + create(std::nothrow, str, accessFlags, creationFlags); if (mHandle < 0) { - throw sys::SystemException(Ctxt(FmtX("Error opening file [%d]: [%s]", - mHandle, str.c_str()))); + throw sys::SystemException(Ctxt( + FmtX("Error opening file [%d]: [%s]", mHandle, str.c_str()))); } - mPath = str; } void sys::File::readInto(void* buffer, Size_T size) diff --git a/modules/c++/sys/source/FileWin32.cpp b/modules/c++/sys/source/FileWin32.cpp index 6db2751890..1b60a02010 100644 --- a/modules/c++/sys/source/FileWin32.cpp +++ b/modules/c++/sys/source/FileWin32.cpp @@ -26,10 +26,10 @@ #include #include "sys/File.h" -void sys::File::create(const std::string& str, - int accessFlags, - int creationFlags) +_SYS_HANDLE_TYPE sys::File::createFile(const coda_oss::filesystem::path& str_, int accessFlags, int creationFlags) noexcept { + const auto str = str_.string(); + // If the truncate bit is on AND the file does exist, // we need to set the mode to TRUNCATE_EXISTING if ((creationFlags & sys::File::TRUNCATE) && sys::OS().exists(str) ) @@ -43,18 +43,24 @@ void sys::File::create(const std::string& str, const auto dwDesiredAccess = static_cast(accessFlags); const auto dwCreationDisposition = static_cast(creationFlags); - mHandle = CreateFile(str.c_str(), + return CreateFile(str.c_str(), dwDesiredAccess, FILE_SHARE_READ, nullptr /*lpSecurityAttributes*/, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, static_cast(0) /*hTemplateFile*/); +} +void sys::File::create(const std::string& str, + int accessFlags, + int creationFlags) +{ + create(std::nothrow, str, accessFlags, creationFlags); if (mHandle == INVALID_HANDLE_VALUE) { - throw sys::SystemException(Ctxt(FmtX("Error opening file: [%s]", str.c_str()))); + throw sys::SystemException( + Ctxt(FmtX("Error opening file: [%s]", str.c_str()))); } - mPath = str; } void sys::File::readInto(void* buffer, size_t size) diff --git a/modules/c++/sys/tests/MutexTest.cpp b/modules/c++/sys/tests/MutexTest.cpp index a3dc1a0540..b30c51f791 100644 --- a/modules/c++/sys/tests/MutexTest.cpp +++ b/modules/c++/sys/tests/MutexTest.cpp @@ -42,7 +42,7 @@ std::string itos (int arg) { class DemoThread : public Thread { protected: - void run() { + void run() override { for (int i = 0 ; i < THREAD_LOOPS ; i++ ) { mutexCout.lock(); std::cout << getName() + " is running" << std::endl; diff --git a/modules/c++/sys/tests/ReadWriteMutexTest.cpp b/modules/c++/sys/tests/ReadWriteMutexTest.cpp index 1b8227fb68..262d3424cf 100644 --- a/modules/c++/sys/tests/ReadWriteMutexTest.cpp +++ b/modules/c++/sys/tests/ReadWriteMutexTest.cpp @@ -54,7 +54,7 @@ std::string BUFFER[1]; class ReadWriteThread : public Thread { protected: - void run() { + void run() override { for(int i=0; i < 5; ++i) { diff --git a/modules/c++/sys/tests/ReentrantTest.cpp b/modules/c++/sys/tests/ReentrantTest.cpp index f61823ed68..8955914862 100644 --- a/modules/c++/sys/tests/ReentrantTest.cpp +++ b/modules/c++/sys/tests/ReentrantTest.cpp @@ -29,7 +29,7 @@ class NoteThread : public Thread public: NoteThread() { std::cout << "Constructed a thread" << std::endl;} - void run() + void run() override { std::cout << "Running a thread" << std::endl;} ~NoteThread() diff --git a/modules/c++/sys/tests/ThreadFreeTest.cpp b/modules/c++/sys/tests/ThreadFreeTest.cpp index 9593239178..63e54d72a0 100644 --- a/modules/c++/sys/tests/ThreadFreeTest.cpp +++ b/modules/c++/sys/tests/ThreadFreeTest.cpp @@ -38,7 +38,7 @@ class MyRunTask : public Runnable { } - virtual void run() + virtual void run() override { result = 1; } diff --git a/modules/c++/sys/tests/ThreadTest4.cpp b/modules/c++/sys/tests/ThreadTest4.cpp index 94365acf95..f9b91cd1c1 100644 --- a/modules/c++/sys/tests/ThreadTest4.cpp +++ b/modules/c++/sys/tests/ThreadTest4.cpp @@ -35,7 +35,7 @@ class Getter : public sys::Runnable CODA_OSS_disable_warning_push CODA_OSS_DISABLE_UNREACHABLE_CODE - virtual void run() + virtual void run() override { for (int i = 0; i < 250; i++) { @@ -71,7 +71,7 @@ class Putter : public sys::Runnable CODA_OSS_disable_warning_push CODA_OSS_DISABLE_UNREACHABLE_CODE - virtual void run() + virtual void run() override { std::cout << "Putter::run: " << std::endl; diff --git a/modules/c++/sys/tests/ThreadTest5.cpp b/modules/c++/sys/tests/ThreadTest5.cpp index 560416b9e3..664109b0db 100644 --- a/modules/c++/sys/tests/ThreadTest5.cpp +++ b/modules/c++/sys/tests/ThreadTest5.cpp @@ -39,7 +39,7 @@ class TestThread : public Thread delete mVal; } - void run() + void run() override { cout << "mVal: " << *mVal << endl; } diff --git a/modules/c++/sys/unittests/test_atomic_counter.cpp b/modules/c++/sys/unittests/test_atomic_counter.cpp index fa56995992..8420b580fb 100644 --- a/modules/c++/sys/unittests/test_atomic_counter.cpp +++ b/modules/c++/sys/unittests/test_atomic_counter.cpp @@ -123,7 +123,7 @@ struct IncrementAtomicCounterT final : public sys::Runnable { } - virtual void run() + virtual void run() override { for (size_t ii = 0; ii < mNumIncrements; ++ii) { @@ -210,7 +210,7 @@ struct DecrementAtomicCounterT final : public sys::Runnable { } - virtual void run() + virtual void run() override { for (size_t ii = 0; ii < mNumDecrements; ++ii) { diff --git a/modules/c++/sys/unittests/test_os.cpp b/modules/c++/sys/unittests/test_os.cpp index d4265494bc..af07859a3f 100644 --- a/modules/c++/sys/unittests/test_os.cpp +++ b/modules/c++/sys/unittests/test_os.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "TestCase.h" void createFile(const std::string& pathname) @@ -400,6 +401,116 @@ TEST_CASE(testFsFileSize) } } +static sys::File makeFile_() +{ +#ifdef _WIN32 + static const std::filesystem::path name("explorer.exe"); + return sys::make_File("%SystemRoot%" / name); + +#else + static const std::filesystem::path dot_cshrc(".cshrc"); + try + { + return sys::make_File("$HOME" / dot_cshrc); + } + catch (const sys::SystemException&) { } // no .cshrc; try .bashrc + + static const std::filesystem::path dot_bashrc(".bashrc"); + return sys::make_File("$HOME" / dot_bashrc); +#endif +} +TEST_CASE(test_makeFile) +{ + auto file = makeFile_(); + TEST_ASSERT_TRUE(file.isOpen()); +} + +static FILE* sys_fopen() +{ + static const std::string mode("r"); + +#ifdef _WIN32 + static const std::filesystem::path name("explorer.exe"); + return sys::fopen("%SystemRoot%" / name, mode); + +#else + static const std::filesystem::path dot_cshrc(".cshrc"); + auto retval = sys::fopen("$HOME" / dot_cshrc, mode); + if (retval != nullptr) + { + return retval; + } + // no .cshrc; try .bashrc + static const std::filesystem::path dot_bashrc(".bashrc"); + return sys::fopen("$HOME" / dot_bashrc, mode); +#endif +} +TEST_CASE(test_sys_fopen) +{ + auto fp = sys_fopen(); + TEST_ASSERT_NOT_NULL(fp); + fclose(fp); +} + +TEST_CASE(test_sys_fopen_failure) +{ + static const std::string mode("r"); + static const std::filesystem::path name("does not exist . txt"); + const auto fp = sys::fopen("$ENV_VAR_NOT_SET" / name, mode); + TEST_ASSERT_NULL(fp); +} + +static int sys_open() +{ + constexpr int flags = 0; + +#ifdef _WIN32 + static const std::filesystem::path name("explorer.exe"); + return sys::open("%SystemRoot%" / name, flags); + +#else + static const std::filesystem::path dot_cshrc(".cshrc"); + auto retval = sys::open("$HOME" / dot_cshrc, flags); + if (retval > -1) + { + return retval; + } + // no .cshrc; try .bashrc + static const std::filesystem::path dot_bashrc(".bashrc"); + return sys::open("$HOME" / dot_bashrc, flags); +#endif +} +TEST_CASE(test_sys_open) +{ + auto fd = sys_open(); + TEST_ASSERT(fd > -1); + sys::close(fd); +} + +static std::ifstream make_ifstream_() +{ +#ifdef _WIN32 + static const std::filesystem::path name("explorer.exe"); + return sys::make_ifstream("%SystemRoot%" / name); + +#else + static const std::filesystem::path dot_cshrc(".cshrc"); + auto retval = sys::make_ifstream("$HOME" / dot_cshrc); + if (retval) + { + return retval; + } + // no .cshrc; try .bashrc + static const std::filesystem::path dot_bashrc(".bashrc"); + return sys::make_ifstream("$HOME" / dot_bashrc); +#endif +} +TEST_CASE(test_make_ifstream) +{ + const auto ifs = make_ifstream_(); + TEST_ASSERT_TRUE(ifs.is_open()); +} + TEST_MAIN( //sys::AbstractOS::setArgvPathname(argv[0]); TEST_CHECK(testRecursiveRemove); @@ -411,4 +522,9 @@ TEST_MAIN( TEST_CHECK(testBacktrace); TEST_CHECK(testSpecialEnvVars); TEST_CHECK(testFsFileSize); -) + TEST_CHECK(test_makeFile); + TEST_CHECK(test_sys_fopen); + TEST_CHECK(test_sys_fopen_failure); + TEST_CHECK(test_sys_open); + TEST_CHECK(test_make_ifstream); + ) diff --git a/modules/c++/xml.lite/CMakeLists.txt b/modules/c++/xml.lite/CMakeLists.txt index 16e64e7184..ee70ab4070 100644 --- a/modules/c++/xml.lite/CMakeLists.txt +++ b/modules/c++/xml.lite/CMakeLists.txt @@ -1,6 +1,10 @@ set(MODULE_NAME xml.lite) if(ENABLE_XML) + if (UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-zero-as-null-pointer-constant") + endif() + if(CONAN_PACKAGE_NAME) # import targets from xerces-c conan package find_package(coda-oss_xerces-c REQUIRED) diff --git a/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h b/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h index e9df3b4d6d..c9d78cfa15 100644 --- a/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h +++ b/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h @@ -29,10 +29,12 @@ #include #include +#include "config/compiler_extensions.h" #include "xml/lite/xml_lite_config.h" #if defined(USE_XERCES) +CODA_OSS_disable_warning_system_header_push #include #include #include @@ -52,11 +54,11 @@ #include #include -#include - #include #include +CODA_OSS_disable_warning_pop + #include #include #include diff --git a/modules/c++/xml.lite/include/xml/lite/XMLReader.h b/modules/c++/xml.lite/include/xml/lite/XMLReader.h index 8ec74f92d6..94334180df 100644 --- a/modules/c++/xml.lite/include/xml/lite/XMLReader.h +++ b/modules/c++/xml.lite/include/xml/lite/XMLReader.h @@ -38,6 +38,7 @@ #endif # include "xml/lite/XMLReaderXerces.h" + namespace xml { namespace lite diff --git a/modules/c++/zip/source/ZipEntry.cpp b/modules/c++/zip/source/ZipEntry.cpp index 2d9595f9ee..9f71cbef32 100644 --- a/modules/c++/zip/source/ZipEntry.cpp +++ b/modules/c++/zip/source/ZipEntry.cpp @@ -21,6 +21,8 @@ */ #include "zip/ZipEntry.h" +#undef Z_NULL +#define Z_NULL nullptr const static char* sZipFileMadeByStr[] = { "MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)", "Amiga", diff --git a/modules/drivers/CMakeLists.txt b/modules/drivers/CMakeLists.txt index cfe5ef7b07..2d580634e3 100644 --- a/modules/drivers/CMakeLists.txt +++ b/modules/drivers/CMakeLists.txt @@ -1,8 +1,14 @@ +# Turn off all warnings; this is code we don't control. if (MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) - add_compile_options(/W3) - add_compile_options(/wd4267) # '...': conversion from '...' to '...', possible loss of data - add_compile_options(/wd4244) # '...': conversion from '...' to '...', possible loss of data + + # By default, there is a /W3 on the command-line from somewhere (?); adding + # /Wn results in a compiler warning. + #add_compile_options(/W0) + string(REGEX REPLACE "/W[0-4]" "/W0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REGEX REPLACE "/W[0-4]" "/W0" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +elseif (UNIX) + add_compile_options(-w) # "Inhibit all warning messages" endif() #add_subdirectory("curl") # this is handled in coda_find_system_dependencies diff --git a/modules/drivers/hdf5/CMakeLists.txt b/modules/drivers/hdf5/CMakeLists.txt index 65db23cb38..dd8c01d3f8 100644 --- a/modules/drivers/hdf5/CMakeLists.txt +++ b/modules/drivers/hdf5/CMakeLists.txt @@ -1,4 +1,5 @@ set(MODULE_NAME hdf5) +set(TARGET_LANGUAGE c++) if(CODA_ENABLE_HDF5) # set up warnings diff --git a/modules/drivers/zlib/CMakeLists.txt b/modules/drivers/zlib/CMakeLists.txt index 7842daa03b..77ec31fa98 100644 --- a/modules/drivers/zlib/CMakeLists.txt +++ b/modules/drivers/zlib/CMakeLists.txt @@ -80,10 +80,6 @@ elseif(ENABLE_ZIP) ARCHIVE "zlib-1.2.13.tar" HASH "SHA256=A47CDCD8863424356B893B259CB57081EFDCC7FA3C2EB56CA1E881324958A2A9") - if (MSVC) - add_compile_options(/wd4996) # '...': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: .... See online help for details. - endif() - set(SOURCE_DIR "${${CMAKE_PROJECT_NAME}_${TARGET_NAME}_SOURCE_DIR}") # remove crypt.h due to name clash with glibc file(REMOVE "${SOURCE_DIR}/contrib/minizip/crypt.h") diff --git a/modules/python/CMakeLists.txt b/modules/python/CMakeLists.txt index cf7e1ad700..20c1e0873a 100644 --- a/modules/python/CMakeLists.txt +++ b/modules/python/CMakeLists.txt @@ -1,3 +1,15 @@ +set(TARGET_LANGUAGE c++) + +# Turn off all warnings; this is code we don't control. +if (MSVC) + # By default, there is a /W3 on the command-line from somewhere (?); adding + # /Wn results in a compiler warning. + #add_compile_options(/W0) + string(REGEX REPLACE "/W[0-4]" "/W0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") +elseif (UNIX) + add_compile_options(-w) # "Inhibit all warning messages" +endif() + add_subdirectory("config") add_subdirectory("except") add_subdirectory("sys")