MINIFICPP-472 Added date formatting EL functions This closes #315.
Signed-off-by: Aldrin Piri <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/commit/8777ab5f Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/tree/8777ab5f Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/diff/8777ab5f Branch: refs/heads/master Commit: 8777ab5f02cfc33e533fd9784b8721dcc5e348e7 Parents: 02f1823 Author: Andrew I. Christianson <[email protected]> Authored: Mon Apr 30 15:41:17 2018 -0400 Committer: Aldrin Piri <[email protected]> Committed: Fri May 18 20:06:12 2018 -0400 ---------------------------------------------------------------------- EXPRESSIONS.md | 91 +- LICENSE | 34 + extensions/expression-language/CMakeLists.txt | 5 + extensions/expression-language/Expression.cpp | 48 + extensions/expression-language/common/Value.h | 4 + .../impl/expression/Expression.h | 7 + .../ExpressionLanguageTests.cpp | 42 + thirdparty/date/.gitignore | 194 + thirdparty/date/CMakeLists.txt | 164 + thirdparty/date/LICENSE.txt | 31 + thirdparty/date/README.md | 58 + thirdparty/date/compile_fail.sh | 16 + thirdparty/date/include/date/chrono_io.h | 34 + thirdparty/date/include/date/date.h | 8022 ++++++++++++++++++ thirdparty/date/include/date/ios.h | 50 + thirdparty/date/include/date/islamic.h | 3031 +++++++ thirdparty/date/include/date/iso_week.h | 1745 ++++ thirdparty/date/include/date/julian.h | 3046 +++++++ thirdparty/date/include/date/ptz.h | 592 ++ thirdparty/date/include/date/tz.h | 2575 ++++++ thirdparty/date/include/date/tz_private.h | 318 + thirdparty/date/src/ios.mm | 337 + thirdparty/date/src/tz.cpp | 3788 +++++++++ thirdparty/date/test_fail.sh | 10 + 24 files changed, 24236 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/EXPRESSIONS.md ---------------------------------------------------------------------- diff --git a/EXPRESSIONS.md b/EXPRESSIONS.md index 1056900..79b9e0c 100644 --- a/EXPRESSIONS.md +++ b/EXPRESSIONS.md @@ -236,6 +236,12 @@ token, filename. - [`join`](#join) - [`count`](#count) +### Date Manipulation + +- [`format`](#format) +- [`toDate`](#todate) +- [`now`](#now) + ## Planned Features ### Searching @@ -249,12 +255,6 @@ token, filename. - `unescapeHtml3` - `unescapeHtml4` -### Date Manipulation - -- `format` -- `toDate` -- `now` - ### Subjectless Functions - `nextInt` @@ -1820,3 +1820,82 @@ consider the following examples: | `${allDelineatedValues(${number_list}, ","):count()}` | `5` | | `${allAttributes("abc", "non-existent-attr", "xyz"):count()}` | `2` | | `${allMatchingAttributes(".*"):length():gt(10):count()}` | `2` | + +### format + +**Description**: Formats a number as a date/time according to the format +specified by the argument. The argument must be a String that is a valid +strftime format. The Subject is expected to be a Number that represents the +number of milliseconds since Midnight GMT on January 1, 1970. The number will +be evaluated using the local time zone unless specified in the second optional +argument. + +**Subject Type**: Number + +**Arguments**: + +| Argument | Description | +| - | - | +| format | The format to use in the strftime syntax | +| time zone | Optional argument that specifies the time zone to use from the IANA Time Zone Database (e.g. 'America/New_York') | + +**Return Type**: String + +**Examples**: + +If the attribute "time" has the value "1420058163264", then the following +Expressions will yield the following results: + +| Expression | Value | +| - | - | +| `${time:format("%Y/%m/%d %H:%M:%S", "GMT")}` | `2014/12/31 20:36:03` | +| `${time:format("%Y", "America/Los_Angeles")}` | `2014` | + +### toDate + +**Description**: Converts a String into a date represented by the number of +milliseconds since the UNIX epoch, based on the format specified by the +argument. The argument must be a String that is a valid strftime syntax. The +Subject is expected to be a String that is formatted according the argument. +The date will be evaluated using the local time zone unless specified in the +second optional argument. + +**Subject Type**: String + +| format | The format to use in the strftime syntax | +| time zone | Optional argument that specifies the time zone to use when parsing the subject, from the IANA Time Zone Database (e.g. 'America/New_York') | + +**Return Type**: Number + +**Examples**: + +If the attribute "year" has the value "2014" and the attribute "time" has the +value "2014/12/31 15:36:03.264Z", then the Expression `${year:toDate('%Y', +'GMT')}` will return a date with a value representing Midnight GMT on January +1, 2014. The Expression `${time:toDate("%Y/%m/%d %H:%M:%S", "GMT")} will result +in a date for 15:36:03 GMT on December 31, 2014. + +Often, this function is used in conjunction with the format function to change +the format of a date/time. For example, if the attribute "date" has the value +"12-24-2014" and we want to change the format to "2014/12/24", we can do so by +chaining together the two functions: +`${date:toDate('%m-%d-%Y'):format('%Y/%m/%d')}`. + +### now + +**Description**: Returns the current date and time as a Date data type object. + +**Subject Type**: String + +**Arguments**: No arguments + +**Return Type**: Number + +**Examples**: + +| Expression | Value | +| - | - | +| `${now()}` | `Count of milliseconds since the UNIX epoch` | +| `${now():minus(86400000)` | `A number presenting the time 24 hours ago` | +| `${now():format('Y')}` | `The current year` | +| `${now():minus(86400000):format('%a')}` | `The day of the week that was yesterday, as a 3-letter abbreviation (For example, Wed)` | http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/LICENSE ---------------------------------------------------------------------- diff --git a/LICENSE b/LICENSE index 3374acd..dfa1e2b 100644 --- a/LICENSE +++ b/LICENSE @@ -1284,6 +1284,40 @@ Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. +This product bundles date which is available under a MIT license: + +The source code in this project is released using the MIT License. There is no +global license for the project because each file is licensed individually with +different author names and/or dates. + +If you contribute to this project, please add your name to the license of each +file you modify. If you have already contributed to this project and forgot to +add your name to the license, please feel free to submit a new P/R to add your +name to the license in each file you modified. + +For convenience, here is a copy of the MIT license found in each file except +without author names or dates: + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + This product bundles RapidJSON: Tencent is pleased to support the open source community by making RapidJSON available. http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/extensions/expression-language/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/extensions/expression-language/CMakeLists.txt b/extensions/expression-language/CMakeLists.txt index d16b7d2..1b44302 100644 --- a/extensions/expression-language/CMakeLists.txt +++ b/extensions/expression-language/CMakeLists.txt @@ -41,6 +41,9 @@ add_flex_bison_dependency(el-scanner el-parser) include_directories(../../libminifi/include ../../libminifi/include/core ../../thirdparty/spdlog-20170710/include ../../thirdparty/concurrentqueue ../../thirdparty/yaml-cpp-yaml-cpp-0.5.3/include ${CIVET_THIRDPARTY_ROOT}/include ../../thirdparty/) include_directories(common) include_directories(impl) +include_directories(../../thirdparty/date/include) + +add_subdirectory(../../thirdparty/date ${CMAKE_CURRENT_BINARY_DIR}/date) file(GLOB SOURCES "*.cpp") @@ -53,6 +56,8 @@ if(CMAKE_THREAD_LIBS_INIT) target_link_libraries(minifi-expression-language-extensions "${CMAKE_THREAD_LIBS_INIT}") endif() +target_link_libraries(minifi-expression-language-extensions ${LIBMINIFI} tz) + find_package(UUID REQUIRED) target_link_libraries(minifi-expression-language-extensions ${LIBMINIFI} ${UUID_LIBRARIES}) find_package(CURL REQUIRED) http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/extensions/expression-language/Expression.cpp ---------------------------------------------------------------------- diff --git a/extensions/expression-language/Expression.cpp b/extensions/expression-language/Expression.cpp index 6c5b5b0..80c9440 100644 --- a/extensions/expression-language/Expression.cpp +++ b/extensions/expression-language/Expression.cpp @@ -34,6 +34,10 @@ #include "base64.h" #include "Driver.h" +#ifdef EXPRESSION_LANGUAGE_USE_DATE +#include "date/tz.h" +#endif // EXPRESSION_LANGUAGE_USE_DATE + namespace org { namespace apache { namespace nifi { @@ -1274,6 +1278,42 @@ Value expr_escapeCsv(const std::vector<Value> &args) { return Value(result); } +#ifdef EXPRESSION_LANGUAGE_USE_DATE + +Value expr_format(const std::vector<Value> &args) { + std::chrono::milliseconds dur(args[0].asUnsignedLong()); + std::chrono::time_point<std::chrono::system_clock> dt(dur); + auto zone = date::current_zone(); + if (args.size() > 2) { + zone = date::locate_zone(args[2].asString()); + } + auto t = date::make_zoned(zone, dt); + std::stringstream result_s; + result_s << date::format(args[1].asString(), t); + return Value(result_s.str()); +} + +Value expr_toDate(const std::vector<Value> &args) { + auto arg_0 = args[0].asString(); + std::istringstream arg_s{arg_0}; + date::sys_time<std::chrono::milliseconds> t; + arg_s >> date::parse(args[1].asString(), t); + auto zone = date::current_zone(); + if (args.size() > 2) { + zone = date::locate_zone(args[2].asString()); + } + auto utc = date::locate_zone("UTC"); + auto utct = date::make_zoned(utc, t); + auto zt = date::make_zoned(zone, utct.get_local_time()); + return Value(std::chrono::duration_cast<std::chrono::milliseconds>(zt.get_sys_time().time_since_epoch()).count()); +} + +#endif // EXPRESSION_LANGUAGE_USE_DATE + +Value expr_now(const std::vector<Value> &args) { + return Value(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()); +} + Value expr_unescapeCsv(const std::vector<Value> &args) { auto result = args[0].asString(); @@ -2209,6 +2249,14 @@ Expression make_dynamic_function(const std::string &function_name, return make_count(function_name, args); } else if (function_name == "join") { return make_join(function_name, args); +#ifdef EXPRESSION_LANGUAGE_USE_DATE + } else if (function_name == "format") { + return make_dynamic_function_incomplete<expr_format>(function_name, args, 1); + } else if (function_name == "toDate") { + return make_dynamic_function_incomplete<expr_toDate>(function_name, args, 1); +#endif // EXPRESSION_LANGUAGE_USE_DATE + } else if (function_name == "now") { + return make_dynamic_function_incomplete<expr_now>(function_name, args, 0); } else { std::string msg("Unknown expression function: "); msg.append(function_name); http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/extensions/expression-language/common/Value.h ---------------------------------------------------------------------- diff --git a/extensions/expression-language/common/Value.h b/extensions/expression-language/common/Value.h index 1c4ec43..d71517b 100644 --- a/extensions/expression-language/common/Value.h +++ b/extensions/expression-language/common/Value.h @@ -183,6 +183,10 @@ class Value { return unsigned_long_val_; } else if (is_string_) { return std::stoul(string_val_); + } else if (is_signed_long_) { + return signed_long_val_; + } else if (is_long_double_) { + return long_double_val_; } else { return 0.0; } http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/extensions/expression-language/impl/expression/Expression.h ---------------------------------------------------------------------- diff --git a/extensions/expression-language/impl/expression/Expression.h b/extensions/expression-language/impl/expression/Expression.h index b7bf676..15f7558 100644 --- a/extensions/expression-language/impl/expression/Expression.h +++ b/extensions/expression-language/impl/expression/Expression.h @@ -25,6 +25,13 @@ #undef EXPRESSION_LANGUAGE_USE_REGEX #endif +#define EXPRESSION_LANGUAGE_USE_DATE + +// Disable date in EL for incompatible compilers +#if __GNUC__ < 5 +#undef EXPRESSION_LANGUAGE_USE_DATE +#endif + #include <Value.h> #include <core/FlowFile.h> http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp ---------------------------------------------------------------------- diff --git a/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp b/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp index 232deb4..f6e143e 100644 --- a/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp +++ b/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp @@ -16,6 +16,8 @@ * limitations under the License. */ +#include <time.h> + #include <memory> #include <string> @@ -1209,6 +1211,46 @@ TEST_CASE("Encode Decode URL", "[expressionEncodeDecodeURL]") { // NOLINT REQUIRE("some value with spaces" == expr({flow_file_a}).asString()); } +#ifdef EXPRESSION_LANGUAGE_USE_DATE + +TEST_CASE("Parse Date", "[expressionParseDate]") { // NOLINT + auto expr = expression::compile("${message:toDate('%Y/%m/%d', 'America/Los_Angeles')}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", "2014/04/30"); + REQUIRE("1398841200000" == expr({flow_file_a}).asString()); +} + +TEST_CASE("Format Date", "[expressionFormatDate]") { // NOLINT + auto expr = expression::compile("${message:format('%m-%d-%Y', 'GMT')}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", "1394755200000"); + REQUIRE("03-14-2014" == expr({flow_file_a}).asString()); +} + +TEST_CASE("Reformat Date", "[expressionReformatDate]") { // NOLINT + auto expr = expression::compile("${message:toDate('%Y/%m/%d', 'GMT'):format('%m-%d-%Y', 'America/New_York')}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", "2014/03/14"); + REQUIRE("03-13-2014" == expr({flow_file_a}).asString()); +} + +TEST_CASE("Now Date", "[expressionNowDate]") { // NOLINT + auto expr = expression::compile("${now():format('%Y')}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", "2014/03/14"); + time_t t = time(nullptr); + struct tm lt; + localtime_r(&t, <); + + REQUIRE((lt.tm_year + 1900) == expr({flow_file_a}).asUnsignedLong()); +} + +#endif // EXPRESSION_LANGUAGE_USE_DATE + TEST_CASE("IP", "[expressionIP]") { // NOLINT auto expr = expression::compile("${ip()}"); http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/.gitignore ---------------------------------------------------------------------- diff --git a/thirdparty/date/.gitignore b/thirdparty/date/.gitignore new file mode 100644 index 0000000..e88e3be --- /dev/null +++ b/thirdparty/date/.gitignore @@ -0,0 +1,194 @@ +#ignore thumbnails created by windows +Thumbs.db +#Ignore files build by Visual Studio +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +[Dd]ebug*/ +*.lib +*.sbr +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* +.idea/ +*.opensdf +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +# User-specific folders +*.sln.ide/ +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +# Roslyn cache directories +*.ide/ +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* +#NUNIT +*.VisualState.xml +TestResult.xml +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc +# Chutzpah Test files +_Chutzpah* +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile +# Visual Studio profiler +*.psess +*.vsp +*.vspx +# TFS 2012 Local Workspace +$tf/ +# Guidance Automation Toolkit +*.gpState +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user +# JustCode is a .NET coding addin-in +.JustCode +# TeamCity is a build add-in +_TeamCity* +# DotCover is a Code Coverage Tool +*.dotCover +# NCrunch +_NCrunch_* +.*crunch*.local.xml +# MightyMoose +*.mm.* +AutoTest.Net/ +# Web workbench (sass) +.sass-cache/ +# Installshield output folder +[Ee]xpress/ +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html +# Click-Once directory +publish/ +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# If using the old MSBuild-Integrated Package Restore, uncomment this: +#!**/packages/repositories.config +# Windows Azure Build Output +csx/ +*.build.csdef +# Windows Store app package directory +AppPackages/ +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +bower_components/ +# RIA/Silverlight projects +Generated_Code/ +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +# SQL Server files +*.mdf +*.ldf +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +# Microsoft Fakes +FakesAssemblies/ +*.suo +*.vcxproj.filters +*.npp +CMakeFiles/* +nbproject/* +*.cd +*.cd +a.out +cmake-build-debug/* http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/thirdparty/date/CMakeLists.txt b/thirdparty/date/CMakeLists.txt new file mode 100644 index 0000000..683ddce --- /dev/null +++ b/thirdparty/date/CMakeLists.txt @@ -0,0 +1,164 @@ +cmake_minimum_required( VERSION 3.1.0 ) + +project( date_prj ) + +include( GNUInstallDirs ) + +find_package( Threads REQUIRED ) + +# Override by setting on CMake command line. +set( CMAKE_CXX_STANDARD 14 CACHE STRING "The C++ standard whose features are requested.") + +option( USE_SYSTEM_TZ_DB "Use the operating system's timezone database" OFF ) +option( USE_TZ_DB_IN_DOT "Save the timezone database in the current folder" OFF ) +option( BUILD_SHARED_LIBS "Build a shared version of library" OFF ) +option( ENABLE_DATE_TESTING "Enable unit tests" ON ) + +function( print_option OPT ) + if ( NOT DEFINED PRINT_OPTION_CURR_${OPT} OR ( NOT PRINT_OPTION_CURR_${OPT} STREQUAL ${OPT} ) ) + set( PRINT_OPTION_CURR_${OPT} ${${OPT}} CACHE BOOL "" ) + mark_as_advanced(PRINT_OPTION_CURR_${OPT}) + message( "# date: ${OPT} ${${OPT}}" ) + endif( ) +endfunction( ) + +print_option( USE_SYSTEM_TZ_DB ) +print_option( USE_TZ_DB_IN_DOT ) +print_option( BUILD_SHARED_LIBS ) +print_option( ENABLE_DATE_TESTING ) + +set( HEADER_FOLDER "include" ) +set( SOURCE_FOLDER "src" ) +set( TEST_FOLDER "test" ) + +# This is needed so IDE's live MSVC show header files +set( HEADER_FILES + ${HEADER_FOLDER}/date/chrono_io.h + ${HEADER_FOLDER}/date/date.h + ${HEADER_FOLDER}/date/ios.h + ${HEADER_FOLDER}/date/islamic.h + ${HEADER_FOLDER}/date/iso_week.h + ${HEADER_FOLDER}/date/julian.h + ${HEADER_FOLDER}/date/tz.h + ${HEADER_FOLDER}/date/tz_private.h +) + +add_library( tz ${HEADER_FILES} ${SOURCE_FOLDER}/tz.cpp ) + +if( USE_SYSTEM_TZ_DB ) + target_compile_definitions( tz PRIVATE -DUSE_AUTOLOAD=0 ) + target_compile_definitions( tz PRIVATE -DHAS_REMOTE_API=0 ) + # cannot set USE_OS_TZDB to 1 on Windows + if( NOT WIN32 ) + target_compile_definitions( tz PUBLIC -DUSE_OS_TZDB=1 ) + endif( ) +else( ) + target_compile_definitions( tz PRIVATE -DUSE_AUTOLOAD=1 ) + target_compile_definitions( tz PRIVATE -DHAS_REMOTE_API=1 ) + target_compile_definitions( tz PUBLIC -DUSE_OS_TZDB=0 ) + find_package( CURL REQUIRED ) + include_directories( SYSTEM ${CURL_INCLUDE_DIRS} ) + set( OPTIONAL_LIBRARIES ${CURL_LIBRARIES} ) +endif( ) + +if( USE_TZ_DB_IN_DOT ) + target_compile_definitions( tz PRIVATE -DINSTALL=. ) +endif( ) + +target_link_libraries( tz ${CMAKE_THREAD_LIBS_INIT} ${OPTIONAL_LIBRARIES} ) + +# add include folders to the library and targets that consume it +target_include_directories(tz PUBLIC + $<BUILD_INTERFACE: + ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FOLDER} + > + $<INSTALL_INTERFACE: + include + > +) + +add_library(date_interface INTERFACE) # an interface (not a library), to enable automatic include_directory (for when just date.h, but not "tz.h and its lib" are needed) + +# add include folders to the INTERFACE and targets that consume it +target_include_directories(date_interface INTERFACE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" + $<INSTALL_INTERFACE:include> +) + +if(WIN32 AND NOT CYGWIN) + set(DEF_INSTALL_CMAKE_DIR CMake) +else() + set(DEF_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/date) +endif() + +install( TARGETS date_interface EXPORT dateConfig ) +install( EXPORT dateConfig DESTINATION ${DEF_INSTALL_CMAKE_DIR} ) +install( TARGETS tz + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # This is for Windows +install( DIRECTORY ${HEADER_FOLDER}/ DESTINATION include/ ) + +if ( ENABLE_DATE_TESTING ) + + enable_testing( ) + + add_custom_target( testit COMMAND ${CMAKE_CTEST_COMMAND} ) + + add_dependencies( testit tz ) + function( add_pass_tests TEST_GLOB TEST_PREFIX ) + file( GLOB_RECURSE FILENAMES ${TEST_GLOB} ) + include_directories( "${HEADER_FOLDER}/date" ) + + foreach( TEST_FILE ${FILENAMES} ) + get_filename_component( TEST_NAME ${TEST_FILE} NAME_WE ) + get_filename_component( TEST_EXT ${TEST_FILE} EXT ) + if( NOT ${TEST_EXT} STREQUAL ".fail.cpp" ) + set( PREFIX "${TEST_PREFIX}_pass_${TEST_NAME}" ) + set( BIN_NAME ${PREFIX}_bin ) + set( TST_NAME ${PREFIX}_test ) + add_executable( ${BIN_NAME} EXCLUDE_FROM_ALL ${TEST_FILE} ) + add_test( ${TST_NAME} ${BIN_NAME} ) + target_link_libraries( ${BIN_NAME} tz ) + add_dependencies( testit ${BIN_NAME} ) + endif( ) + endforeach( ) + endfunction( ) + + function( add_fail_tests TEST_GLOB TEST_PREFIX ) + file( GLOB_RECURSE FILENAMES ${TEST_GLOB} ) + + foreach( TEST_FILE ${FILENAMES} ) + get_filename_component( TEST_NAME ${TEST_FILE} NAME_WE ) + get_filename_component( TEST_EXT ${TEST_FILE} EXT ) + + set( TEST_TYPE "_fail" ) + + set( PREFIX "${TEST_PREFIX}_fail_${TEST_NAME}" ) + set( BIN_NAME ${PREFIX}_bin ) + set( TST_NAME ${PREFIX}_test ) + + #target_compile_definitions( ${BIN_NAME} PRIVATE ${TST_NAME} ) + set( TEST_BIN_NAME ${CMAKE_BINARY_DIR}/${BIN_NAME} ) + add_custom_target( ${BIN_NAME} + COMMAND ${PROJECT_SOURCE_DIR}/compile_fail.sh ${TEST_BIN_NAME} ${CMAKE_CXX_COMPILER} -std=c++14 -L${CMAKE_BINARY_DIR}/ -ltz -I${PROJECT_SOURCE_DIR}/${HEADER_FOLDER}/date -o ${BIN_NAME} ${TEST_FILE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT ${TST_NAME} + ) + add_test( ${TST_NAME} "${PROJECT_SOURCE_DIR}/test_fail.sh" ${CMAKE_BINARY_DIR}/${BIN_NAME} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/" ) + #set_tests_properties( ${TST_NAME} PROPERTIES WILL_FAIL TRUE) + add_dependencies( testit ${BIN_NAME} ) + endforeach( ) + endfunction( ) + + file( GLOB children RELATIVE "${PROJECT_SOURCE_DIR}/${TEST_FOLDER}" "${PROJECT_SOURCE_DIR}/${TEST_FOLDER}/*" ) + foreach( child ${children} ) + if( IS_DIRECTORY "${PROJECT_SOURCE_DIR}/${TEST_FOLDER}/${child}" ) + set( CUR_FOLDER "${PROJECT_SOURCE_DIR}/${TEST_FOLDER}/${child}" ) + add_pass_tests( "${CUR_FOLDER}/*.cpp" ${child} ) + if( NOT WIN32 ) + add_fail_tests( "${CUR_FOLDER}/*.fail.cpp" ${child} ) + endif( ) + endif( ) + endforeach( ) +endif( ) http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/LICENSE.txt ---------------------------------------------------------------------- diff --git a/thirdparty/date/LICENSE.txt b/thirdparty/date/LICENSE.txt new file mode 100644 index 0000000..79ea069 --- /dev/null +++ b/thirdparty/date/LICENSE.txt @@ -0,0 +1,31 @@ +The source code in this project is released using the MIT License. There is no +global license for the project because each file is licensed individually with +different author names and/or dates. + +If you contribute to this project, please add your name to the license of each +file you modify. If you have already contributed to this project and forgot to +add your name to the license, please feel free to submit a new P/R to add your +name to the license in each file you modified. + +For convenience, here is a copy of the MIT license found in each file except +without author names or dates: + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/README.md ---------------------------------------------------------------------- diff --git a/thirdparty/date/README.md b/thirdparty/date/README.md new file mode 100644 index 0000000..580d20d --- /dev/null +++ b/thirdparty/date/README.md @@ -0,0 +1,58 @@ +# Date + +[](https://gitter.im/HowardHinnant/date?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +--- + +**[Try it out on wandbox!](https://wandbox.org/permlink/vqwMyTphHJv5iXX7)** + +## Summary + +This is actually several separate C++11/C++14/C++17 libraries: + +1. `"date.h"` is a header-only library which builds upon `<chrono>`. It adds some new `duration` types, and new `time_point` types. It also adds "field" types such as `year_month_day` which is a struct `{year, month, day}`. And it provides convenient means to convert between the "field" types and the `time_point` types. + + * Documentation: http://howardhinnant.github.io/date/date.html + * Video: https://www.youtube.com/watch?v=tzyGjOm8AKo + * Slides: http://schd.ws/hosted_files/cppcon2015/43/hinnant_dates.pdf + +1. `"tz.h"` / `"tz.cpp"` are a timezone library built on top of the `"date.h"` library. This timezone library is a complete parser of the IANA timezone database. It provides for an easy way to access all of the data in this database, using the types from `"date.h"` and `<chrono>`. The IANA database also includes data on leap seconds, and this library provides utilities to compute with that information as well. + + * Documentation: http://howardhinnant.github.io/date/tz.html + * Video: https://www.youtube.com/watch?v=Vwd3pduVGKY + * Slides: http://schd.ws/hosted_files/cppcon2016/0f/Welcome%20To%20The%20Time%20Zone%20-%20Howard%20Hinnant%20-%20CppCon%202016.pdf + +1. `"iso_week.h"` is a header-only library built on top of the `"date.h"` library which implements the ISO week date calendar. + + * Documentation: http://howardhinnant.github.io/date/iso_week.html + +1. `"julian.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Julian calendar which is fully interoperable with everything above. + + * Documentation: http://howardhinnant.github.io/date/julian.html + +1. `"islamic.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Islamic calendar which is fully interoperable with everything above. + + * Documentation: http://howardhinnant.github.io/date/islamic.html + +## Standardization + +Slightly modified versions of `"date.h"` and `"tz.h"` were voted into the C++20 working draft at the Jacksonville FL meeting on 2018-03-17: + +* http://howardhinnant.github.io/date/d0355r7.html + +## Build & Test + +You will need [CMake](https://cmake.org/) and a recent C++ compiler. Here follows a guide of how to build and test using the CMake Makefile generator. + +```bash +mkdir build +cd build +cmake ../ +cmake --build . --target testit #Â Consider '-- -j4' for multithreading +``` +## Projects using this library + +* www.safe.com +* www.webtoolkit.eu/wt + +If you would like your project (or product) on this list, just let me know. http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/compile_fail.sh ---------------------------------------------------------------------- diff --git a/thirdparty/date/compile_fail.sh b/thirdparty/date/compile_fail.sh new file mode 100755 index 0000000..60cf6b9 --- /dev/null +++ b/thirdparty/date/compile_fail.sh @@ -0,0 +1,16 @@ +#!/bin/bash +export TEST_BIN_NAME=$1 +#echo "Building ${TEST_BIN_NAME}" +shift 1 +export BUILD_COMMAND=$@ +#echo "Build command: ${BUILD_COMMAND}" +eval ${BUILD_COMMAND} >/dev/null 2>/dev/null + +if [ $? -eq 0 ]; then + echo -ne "#!/bin/bash\nexit 1;" > ${TEST_BIN_NAME} +else + echo -ne "#!/bin/bash\nexit 0;" > ${TEST_BIN_NAME} +fi +chmod u+x ${TEST_BIN_NAME} +exit 0; + http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/include/date/chrono_io.h ---------------------------------------------------------------------- diff --git a/thirdparty/date/include/date/chrono_io.h b/thirdparty/date/include/date/chrono_io.h new file mode 100644 index 0000000..21be404 --- /dev/null +++ b/thirdparty/date/include/date/chrono_io.h @@ -0,0 +1,34 @@ +#ifndef CHRONO_IO_H +#define CHRONO_IO_H + +// The MIT License (MIT) +// +// Copyright (c) 2016, 2017 Howard Hinnant +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// Our apologies. When the previous paragraph was written, lowercase had not yet +// been invented (that would involve another several millennia of evolution). +// We did not mean to shout. + +// This functionality has moved to "date.h" + +#include "date.h" + +#endif // CHRONO_IO_H
