diff --git a/parser/mpFuncCommon.cpp b/parser/mpFuncCommon.cpp index e342f12..2f28f58 100644 --- a/parser/mpFuncCommon.cpp +++ b/parser/mpFuncCommon.cpp @@ -703,11 +703,6 @@ MUP_NAMESPACE_START return new FunAddDays(*this); } - //------------------------------------------------------------------------------ - // - // class FunTimeDiff - // - //------------------------------------------------------------------------------ //FunTimeDiff::FunTimeDiff() // :ICallback(cmFUNC, _T("timediff"), -1) @@ -808,6 +803,30 @@ MUP_NAMESPACE_START // | //------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ + // | + // Time auxiliar functions! | + // | + //------------------------------------------------------------------------------ + + int calculate_hour_offset(int original_hour, int gmt_offset) { + return ((original_hour + gmt_offset) % 24 + 24) % 24; + } + + string_type format_time (struct tm time, int gmt_offset) { + char buffer[9]; + int hours = calculate_hour_offset(time.tm_hour, gmt_offset); + snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d", hours, time.tm_min, time.tm_sec); + + return std::string(buffer); + } + + //------------------------------------------------------------------------------ + // + // class FunTimeDiff + // + //------------------------------------------------------------------------------ + FunTimeDiff::FunTimeDiff() :ICallback(cmFUNC, _T("timediff"), -1) {} @@ -856,6 +875,58 @@ MUP_NAMESPACE_START return new FunTimeDiff(*this); } + //------------------------------------------------------------------------------ + // | + // class FunCurrentTime | + // Usage: current_time() | + // Optional offset: current_time(-2) | + // | + //------------------------------------------------------------------------------ + + FunCurrentTime::FunCurrentTime() + :ICallback(cmFUNC, _T("current_time"), -1) + {} + + void FunCurrentTime::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc) + { + int gmt_offset = 0; + if (a_iArgc > 1) { + throw ParserError(ErrorContext(ecTOO_MANY_PARAMS, GetExprPos(), GetIdent())); + } else if (a_iArgc == 1) { + switch(a_pArg[0]->GetType()) + { + case 'i': gmt_offset = a_pArg[0]->GetInteger(); break; + default: + { + ErrorContext err; + err.Errc = ecTYPE_CONFLICT_FUN; + err.Arg = 1; + err.Type1 = a_pArg[0]->GetType(); + err.Type2 = 'i'; + err.Ident = GetIdent(); + throw ParserError(err); + } + } + } + + std::time_t t = std::time(0); + std::tm now = *std::gmtime(&t); + + *ret = format_time(now, gmt_offset); + } + + ////--------------------------------------------------------------------------------------------------------- + const char_type* FunCurrentTime::GetDesc() const + { + return _T("current_time(offset) - Returns the current time in the HH:MM:SS format, applying the offset."); + } + + ////--------------------------------------------------------------------------------------------------------- + IToken* FunCurrentTime::Clone() const + { + return new FunCurrentTime(*this); + } + //------------------------------------------------------------------------------ // | // Functions for regex matching | diff --git a/parser/mpFuncCommon.h b/parser/mpFuncCommon.h index 7f8406a..e2c4226 100644 --- a/parser/mpFuncCommon.h +++ b/parser/mpFuncCommon.h @@ -198,6 +198,19 @@ MUP_NAMESPACE_START virtual IToken* Clone() const override; }; // class FunTimeDiff + //------------------------------------------------------------------------------ + /** \brief Returns the current time in the HH:MM:SS format. + \ingroup functions + */ + class FunCurrentTime : public ICallback + { + public: + FunCurrentTime(); + virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc) override; + virtual const char_type* GetDesc() const override; + virtual IToken* Clone() const override; + }; // class FunCurrentTime + //------------------------------------------------------------------------------ /** \brief Return the capture group of a regular expression. \ingroup functions diff --git a/parser/mpPackageCommon.cpp b/parser/mpPackageCommon.cpp index d3cb474..1add84c 100644 --- a/parser/mpPackageCommon.cpp +++ b/parser/mpPackageCommon.cpp @@ -107,6 +107,7 @@ void PackageCommon::AddToParser(ParserXBase *pParser) // Time functions pParser->DefineFun(new FunTimeDiff()); + pParser->DefineFun(new FunCurrentTime()); // misc pParser->DefineFun(new FunParserID); diff --git a/tests.sh b/tests.sh index c7c03f0..8fdf8e3 100755 --- a/tests.sh +++ b/tests.sh @@ -32,6 +32,21 @@ exit" | ./example | grep -E "(ans =|Can't evaluate function/operator \".*\":)") esac } +function match_regex() { + input="$1" + regex="$2" + + output=$(echo "$input +exit" | ./example | grep -E "(ans =|Can't evaluate function/operator \".*\":)") + + if echo "$output" | egrep -q "$regex"; then + printf "\e[32mTest passed for input $input\e[0m\n" + else + printf "\e[31mTest failed for input $input: regex did not match\e[0m\n" + exit 1 + fi +} + # Arithmetic tests test_eval "2 + 2" "4" test_eval "55 * 33" "1815" @@ -184,6 +199,8 @@ test_eval 'timediff("02:00:00", "03:30:00")' '1.5' test_eval 'timediff("03:30:00", "02:00:00")' '22.5' test_eval 'timediff("02:00:00", "02:00:30")' '0.01' +test_eval 'current_time("2")' "Argument 1 of function/operator \"current_time\" is of type 's' whereas type 'i' was expected." + # Mask tests test_eval 'mask("000-000", 123456)' '"123-456"' test_eval 'mask("00000", 14)' '"00014"' @@ -326,5 +343,12 @@ test_eval 'weekday("2019-03-21", "invalidlocale")' 'The chosen locale is not sup test_eval 'weekday("2024-32-21")' 'Invalid format on the parameter(s). Please use two "yyyy-mm-dd" for dates OR two "yyyy-mm-ddTHH:MM" for date_times.' test_eval 'weekday("2024-09-17", "en", "one too many params")' 'Too many parameters passed to function "weekday".' +# Regex match test +match_regex 'current_time(5)' '\b([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\b' +match_regex 'current_time()' '\b([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\b' +match_regex 'current_time(-3)' '\b([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\b' +match_regex 'current_time(-200)' '\b([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\b' + + echo "All tests passed!"