zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #16622
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/bug-1053113 into lp:zorba.
Commit message:
Moved dateTime module into the core and added parse-date(), parse-time(), parse-dateTime(), and utc-offset().
Requested reviews:
Paul J. Lucas (paul-lucas)
Related bugs:
Bug #1053113 in Zorba: "parse-date and parse-dateTime functionality"
https://bugs.launchpad.net/zorba/+bug/1053113
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-1053113/+merge/141618
Moved dateTime module into the core and added parse-date(), parse-time(), parse-dateTime(), and utc-offset().
--
https://code.launchpad.net/~zorba-coders/zorba/bug-1053113/+merge/141618
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2012-10-08 12:09:36 +0000
+++ CMakeLists.txt 2013-01-02 14:49:24 +0000
@@ -76,25 +76,28 @@
###############################################################################
# Check for system include files, features, etc.
###############################################################################
+INCLUDE(CheckCXXSourceCompiles)
+INCLUDE(CheckFunctionExists)
+INCLUDE(CheckIncludeFileCXX)
INCLUDE(CheckIncludeFiles)
+INCLUDE(CheckLibraryExists)
+INCLUDE(CheckStructHasMember)
INCLUDE(CheckSymbolExists)
-INCLUDE(CheckFunctionExists)
-INCLUDE(CheckLibraryExists)
+INCLUDE(CheckTypeSize)
INCLUDE(CheckVariableExists)
-INCLUDE(CheckIncludeFileCXX)
-INCLUDE(CheckTypeSize)
-INCLUDE(CheckCXXSourceCompiles)
-CHECK_INCLUDE_FILES ("sys/param.h;sys/mount.h" ZORBA_HAVE_SYS_MOUNT_H)
-CHECK_INCLUDE_FILES ("unicode/utypes.h" ZORBA_HAVE_UTYPES_H)
CHECK_INCLUDE_FILES ("unicode/coll.h" ZORBA_HAVE_COLL_H)
-CHECK_INCLUDE_FILES ("unicode/ustring.h" ZORBA_HAVE_USTRING_H)
+CHECK_INCLUDE_FILES ("iconv.h" ZORBA_HAVE_ICONV_H)
CHECK_INCLUDE_FILES ("inttypes.h" ZORBA_HAVE_INTTYPES_H)
+CHECK_INCLUDE_FILES ("limits.h" ZORBA_HAVE_LIMITS_H)
CHECK_INCLUDE_FILES ("stdint.h" ZORBA_HAVE_STDINT_H)
CHECK_INCLUDE_FILES ("stdlib.h" ZORBA_HAVE_STDLIB_H)
-CHECK_INCLUDE_FILES ("limits.h" ZORBA_HAVE_LIMITS_H)
+CHECK_INCLUDE_FILES ("sys/param.h;sys/mount.h" ZORBA_HAVE_SYS_MOUNT_H)
CHECK_INCLUDE_FILES ("sys/types.h" ZORBA_HAVE_SYS_TYPES_H)
-CHECK_INCLUDE_FILES ("iconv.h" ZORBA_HAVE_ICONV_H)
+CHECK_INCLUDE_FILES ("tzfile.h" ZORBA_HAVE_TZFILE_H)
+CHECK_INCLUDE_FILES ("unicode/ustring.h" ZORBA_HAVE_USTRING_H)
+CHECK_INCLUDE_FILES ("unicode/utypes.h" ZORBA_HAVE_UTYPES_H)
+
IF (NOT APPLE OR ${CMAKE_SYSTEM_VERSION} VERSION_GREATER "10.4")
# execinfo is found by this macro when cross compiling for Mac OS X 10.4
# although it shouldn't be found for this platform
@@ -124,6 +127,9 @@
CHECK_TYPE_SIZE("__int32" ZORBA_HAVE_MS_INT32)
CHECK_TYPE_SIZE("int64_t" ZORBA_HAVE_INT64_T)
+CHECK_STRUCT_HAS_MEMBER("struct tm" tm_gmtoff time.h ZORBA_HAVE_STRUCT_TM_TM_GMTOFF)
+CHECK_STRUCT_HAS_MEMBER("struct tm" __tm_gmtoff time.h ZORBA_HAVE_STRUCT_TM___TM_GMTOFF)
+
# C++ built-in type sizes
CHECK_TYPE_SIZE("double" ZORBA_SIZEOF_DOUBLE BUILTIN_TYPES_ONLY)
CHECK_TYPE_SIZE("float" ZORBA_SIZEOF_FLOAT BUILTIN_TYPES_ONLY)
=== modified file 'ChangeLog'
--- ChangeLog 2013-01-02 02:33:53 +0000
+++ ChangeLog 2013-01-02 14:49:24 +0000
@@ -9,8 +9,13 @@
when resolving URIs.
* Can now specify jsoniq-strip-top-level-array option to parse-json() to
strip the top-level array from JSON streams.
+<<<<<<< TREE
* New info-extraction module for querying concepts and entities in
natural language text.
+=======
+ * In the datetime module, added parse-date(), parse-dateTime(), parse-time(),
+ and utc-offset().
+>>>>>>> MERGE-SOURCE
* Extended cast and castable expression to allow any simple target type
(as specified by XQuery 3.0)
=== modified file 'include/zorba/config.h.cmake'
--- include/zorba/config.h.cmake 2012-12-12 19:34:45 +0000
+++ include/zorba/config.h.cmake 2013-01-02 14:49:24 +0000
@@ -50,6 +50,7 @@
#cmakedefine ZORBA_HAVE_STDLIB_H
#cmakedefine ZORBA_HAVE_SYS_MOUNT_H
#cmakedefine ZORBA_HAVE_SYS_TYPES_H
+#cmakedefine ZORBA_HAVE_TZFILE_H
#cmakedefine ZORBA_HAVE_USTRING_H
#cmakedefine ZORBA_HAVE_UTYPES_H
#cmakedefine ZORBA_HAVE_UUID_H
@@ -69,6 +70,10 @@
#cmakedefine ZORBA_HAVE_MS_INT32
#cmakedefine ZORBA_HAVE_MS_UINT32
#cmakedefine ZORBA_HAVE_UINT32_T
+#cmakedefine ZORBA_HAVE_STRUCT_TM_TM_GMTOFF
+#cmakedefine ZORBA_HAVE_STRUCT_TM___TM_GMTOFF
+
+// Platform type sizes
#cmakedefine ZORBA_SIZEOF_DOUBLE @ZORBA_SIZEOF_DOUBLE@
#cmakedefine ZORBA_SIZEOF_FLOAT @ZORBA_SIZEOF_FLOAT@
#cmakedefine ZORBA_SIZEOF_INT @ZORBA_SIZEOF_INT@
=== modified file 'include/zorba/diagnostic.h'
--- include/zorba/diagnostic.h 2012-09-19 21:16:15 +0000
+++ include/zorba/diagnostic.h 2013-01-02 14:49:24 +0000
@@ -246,8 +246,10 @@
# ifdef ZORBA_WITH_JSON
JSONIQ_CORE,
- JSONIQ_UPDATE
-# endif
+ JSONIQ_UPDATE,
+# endif /* ZORBA_WITH_JSON */
+
+ ZORBA_CORE_MODULE // Zorba Core Module
};
/**
=== modified file 'include/zorba/pregenerated/diagnostic_list.h'
--- include/zorba/pregenerated/diagnostic_list.h 2012-12-21 22:05:39 +0000
+++ include/zorba/pregenerated/diagnostic_list.h 2013-01-02 14:49:24 +0000
@@ -796,6 +796,16 @@
extern ZORBA_DLL_PUBLIC ZorbaErrorCode XSST0010;
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDTP0001_INVALID_SPECIFICATION;
+
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDTP0002_INSUFFICIENT_BUFFER;
+
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDTP0003_INVALID_VALUE;
+
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDTP0004_LITERAL_MISMATCH;
+
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDTP0005_INCOMPLETE_DATE_OR_TIME;
+
extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0001_ILLEGAL_CHARACTER;
extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0002_ILLEGAL_CODEPOINT;
=== modified file 'modules/com/zorba-xquery/www/modules/datetime.xq'
--- modules/com/zorba-xquery/www/modules/datetime.xq 2012-09-19 21:16:15 +0000
+++ modules/com/zorba-xquery/www/modules/datetime.xq 2013-01-02 14:49:24 +0000
@@ -17,51 +17,155 @@
:)
(:~
- : This module provides functions to retrieve the current dateTime.
+ : This module provides functions to retrieve the current dateTime and to
+ : parse dates and times.
+ :
: In contrast to the current-dateTime functions specified in
- : "XQuery Functions and Operators" the functions in this module are nondeterministic.
- : That is, they do not return the current-dateTime from the dynamic context but return the actual value.
+ : <a href="http://www.w3.org/TR/xpath-functions-30/";>XQuery Functions and
+ : Operators</a>, the functions in this module are nondeterministic, that is,
+ : they do not return the current dateTime from the dynamic context, but return
+ : the actual value.
+ :
+ : Dates and times are parsed according to the format given by
+ : <a href="http://pubs.opengroup.org/onlinepubs/007904975/functions/strptime.html";>strptime</a>.
+ : However, date and time values must be "complete."
+ : For a date, the year and either month and day or day of the year must have
+ : been parsed.
+ : For a time, the hour must have been parsed.
+ : (If either the minute, second, or timezone has not been parsed, they default
+ : to 0.)
+ : For a dateTime, the parsing requirements of both date and time must be met.
:
: @author Matthias Brantner
+ : @author Paul J. Lucas
: @see http://www.w3.org/TR/xpath-functions/#context
: @project XDM/atomic
:
:)
module namespace datetime = "http://www.zorba-xquery.com/modules/datetime";;
+
declare namespace an = "http://www.zorba-xquery.com/annotations";;
+declare namespace zerr = "http://www.zorba-xquery.com/errors";;
+
declare namespace ver = "http://www.zorba-xquery.com/options/versioning";;
declare option ver:module-version "2.0";
(:~
- : Return the current dateTime value.
- : Please note, that this function is not stable. It returns the
- : dateTime value of the date and time the function has actually been invoked.
+ : Gets the current date value in Universal time.
+ : Note that this function is not stable: it returns the value of the date when
+ : the function is invoked.
+ :
+ : @return the non-stable date value
+ :)
+declare %an:nondeterministic function datetime:current-date()
+ as xs:date external;
+
+(:~
+ : Gets the current dateTime value in Universal time.
+ : Note that this function is not stable: it returns the value of the date and
+ : time when the function is invoked.
:
: @return the non-stable datetime value
:)
-declare %an:nondeterministic function datetime:current-dateTime ( ) as xs:dateTime external;
+declare %an:nondeterministic function datetime:current-dateTime()
+ as xs:dateTime external;
(:~
- : Return the current time value.
- : Please note, that this function is not stable. It returns the
- : time value of the date and time the function has actually been invoked.
+ : Return the current time value in Universal time.
+ : Note that this function is not stable: it returns the value of the time when
+ : the function is invoked.
:
: @return the non-stable time value
:)
-declare %an:nondeterministic function datetime:current-time ( ) as xs:time external;
-
-(:~
- : Return the current date value.
- : Please note, that this function is not stable. It returns the
- : dat value of the date the function has been actually invoked.
- :
- : @return the non-stable date value
- :)
-declare %an:nondeterministic function datetime:current-date ( ) as xs:date external;
-
-(:~
- : Return the the number of milliseconds since the Epoch.
+declare %an:nondeterministic function datetime:current-time()
+ as xs:time external;
+
+(:~
+ : Parses a date from a string.
+ :
+ : @param $input The string to parse.
+ : @param $format The format string containing zero or more conversion
+ : specifications and ordinary characters. All ordinary characters are matched
+ : exactly with the buffer; all whitespace characters match any amount of
+ : whitespace in the buffer.
+ : @return Returns an xs:date.
+ : @error zerr:ZDTP0001 if $format contains an invalid conversion specification.
+ : @error zerr:ZDTP0002 if $input is insufficient for $format.
+ : @error zerr:ZDTP0003 if $input contains an invalid value for a conversion
+ : specification.
+ : @error zerr:ZDTP0004 if there is a literal characer mismatch between $input
+ : and $format.
+ : @error zerr:ZDTP0005 if the date is incomplete.
+ : @example test/rbkt/Queries/zorba/datetime/datetime-parse-date-uD-1.xq
+ : @example test/rbkt/Queries/zorba/datetime/datetime-parse-date-uF-1.xq
+ :)
+declare function datetime:parse-date(
+ $input as xs:string,
+ $format as xs:string
+) as xs:date external;
+
+(:~
+ : Parses a dateTime from a string.
+ :
+ : @param $input The string to parse.
+ : @param $format The format string containing zero or more conversion
+ : specifications and ordinary characters. All ordinary characters are matched
+ : exactly with the buffer; all whitespace characters match any amount of
+ : whitespace in the buffer.
+ : @return Returns an xs:dateTime.
+ : @error zerr:ZDTP0001 if $format contains an invalid conversion specification.
+ : @error zerr:ZDTP0002 if $input is insufficient for $format.
+ : @error zerr:ZDTP0003 if $input contains an invalid value for a conversion
+ : specification.
+ : @error zerr:ZDTP0004 if there is a literal characer mismatch between $input
+ : and $format.
+ : @error zerr:ZDTP0005 if either the date or time is incomplete.
+ : @example test/rbkt/Queries/zorba/datetime/datetime-parse-dateTime-uFTZ-1.xq
+ :)
+declare function datetime:parse-dateTime(
+ $input as xs:string,
+ $format as xs:string
+) as xs:dateTime external;
+
+(:~
+ : Parses a time from a string.
+ :
+ : @param $input The string to parse.
+ : @param $format The format string containing zero or more conversion
+ : specifications and ordinary characters. All ordinary characters are matched
+ : exactly with the buffer; all whitespace characters match any amount of
+ : whitespace in the buffer.
+ : @return Returns an xs:time.
+ : @error zerr:ZDTP0001 if $format contains an invalid conversion specification.
+ : @error zerr:ZDTP0002 if $input is insufficient for $format.
+ : @error zerr:ZDTP0003 if $input contains an invalid value for a conversion
+ : specification.
+ : @error zerr:ZDTP0004 if there is a literal characer mismatch between $input
+ : and $format.
+ : @error zerr:ZDTP0005 if the hour has not been parsed.
+ : @example test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-1.xq
+ : @example test/rbkt/Queries/zorba/datetime/datetime-parse-time-uIMS-1.xq
+ :)
+declare function datetime:parse-time(
+ $input as xs:string,
+ $format as xs:string
+) as xs:time external;
+
+(:~
+ : Gets the the number of milliseconds since epoch.
:
: @return the said number of milliseconds.
:)
-declare %an:nondeterministic function datetime:timestamp ( ) as xs:long external;
+declare %an:nondeterministic function datetime:timestamp()
+ as xs:long external;
+
+(:~
+ : Gets the offset of the current timezone from Universal time.
+ :
+ : @return the offset in seconds with positive values being east of the prime
+ : meridian.
+ :)
+declare %an:nondeterministic function datetime:utc-offset()
+ as xs:long external;
+
+(: vim:set et sw=2 ts=2: :)
=== removed directory 'modules/com/zorba-xquery/www/modules/datetime.xq.src'
=== removed file 'modules/com/zorba-xquery/www/modules/datetime.xq.src/datetime.cpp'
--- modules/com/zorba-xquery/www/modules/datetime.xq.src/datetime.cpp 2012-09-19 21:16:15 +0000
+++ modules/com/zorba-xquery/www/modules/datetime.xq.src/datetime.cpp 1970-01-01 00:00:00 +0000
@@ -1,209 +0,0 @@
-/*
- * Copyright 2006-2010 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "datetime.h"
-
-#include <zorba/item_factory.h>
-#include <zorba/singleton_item_sequence.h>
-
-#include <time.h>
-#include <sys/timeb.h>
-#ifdef UNIX
-#include <sys/time.h>
-#endif
-
-namespace zorba { namespace datetimemodule {
-
-void
-compute_date_time(
- struct ::tm& gmtm,
- long& timezone,
- unsigned short& millitm)
-{
- int lSummerTimeShift = 0;
-#if defined (WIN32)
- struct _timeb timebuffer;
- _ftime_s( &timebuffer );
- localtime_s(&gmtm, &timebuffer.time); //thread safe localtime on Windows
- lSummerTimeShift = -timebuffer.timezone * 60;
- if (gmtm.tm_isdst != 0)
- lSummerTimeShift += 3600;
-#else
- struct timeb timebuffer;
- ftime( &timebuffer );
- localtime_r(&timebuffer.time, &gmtm); //thread safe localtime on Linux
- localtime_r(&timebuffer.time, &gmtm); //thread safe localtime on Linux
- lSummerTimeShift = gmtm.tm_gmtoff;
-#endif
-
- timezone = lSummerTimeShift; // in seconds
- millitm = timebuffer.millitm;
-}
-
-/******************************************************************************
- *****************************************************************************/
-zorba::ItemSequence_t
-CurrentDateTimeFunction::evaluate(
- const Arguments_t& aArgs,
- const zorba::StaticContext* aSctx,
- const zorba::DynamicContext* aDctx) const
-{
- struct ::tm gmtm;
- long lTimezone;
- unsigned short lMilliTm;
-
- compute_date_time(gmtm, lTimezone, lMilliTm);
-
- zorba::Item lDateTime =
- Zorba::getInstance(0)->getItemFactory()->createDateTime(
- static_cast<short>(gmtm.tm_year + 1900),
- static_cast<short>(gmtm.tm_mon + 1),
- static_cast<short>(gmtm.tm_mday),
- static_cast<short>(gmtm.tm_hour),
- static_cast<short>(gmtm.tm_min),
- gmtm.tm_sec + lMilliTm/1000.0,
- static_cast<short>(lTimezone/3600)
- );
-
- return zorba::ItemSequence_t(new zorba::SingletonItemSequence(lDateTime));
-}
-
-/******************************************************************************
- *****************************************************************************/
-zorba::ItemSequence_t
-CurrentDateFunction::evaluate(
- const Arguments_t& aArgs,
- const zorba::StaticContext* aSctx,
- const zorba::DynamicContext* aDctx) const
-{
- struct ::tm gmtm;
- long lTimezone;
- unsigned short lMilliTm;
-
- compute_date_time(gmtm, lTimezone, lMilliTm);
-
- zorba::Item lDateTime =
- Zorba::getInstance(0)->getItemFactory()->createDate(
- static_cast<short>(gmtm.tm_year + 1900),
- static_cast<short>(gmtm.tm_mon + 1),
- static_cast<short>(gmtm.tm_mday)
- );
-
- return zorba::ItemSequence_t(new zorba::SingletonItemSequence(lDateTime));
-}
-
-/******************************************************************************
- *****************************************************************************/
-zorba::ItemSequence_t
-CurrentTimeFunction::evaluate(
- const Arguments_t& aArgs,
- const zorba::StaticContext* aSctx,
- const zorba::DynamicContext* aDctx) const
-{
- struct ::tm gmtm;
- long lTimezone;
- unsigned short lMilliTm;
-
- compute_date_time(gmtm, lTimezone, lMilliTm);
-
- zorba::Item lDateTime =
- Zorba::getInstance(0)->getItemFactory()->createTime(
- static_cast<short>(gmtm.tm_hour),
- static_cast<short>(gmtm.tm_min),
- gmtm.tm_sec + lMilliTm/1000.0,
- static_cast<short>(lTimezone/3600)
- );
-
- return zorba::ItemSequence_t(new zorba::SingletonItemSequence(lDateTime));
-}
-
-/******************************************************************************
- *****************************************************************************/
-
-zorba::ItemSequence_t
-TimestampFunction::evaluate(
- const Arguments_t& aArgs,
- const zorba::StaticContext* aSctx,
- const zorba::DynamicContext* aDctx) const
-{
- zorba::Item lMillis;
-#if WIN32
- time_t t0;
- time(&t0);
- lMillis = Zorba::getInstance(0)->getItemFactory()->createLong(t0*1000);
-#else
- timeval tv;
- gettimeofday(&tv, 0);
- long long millis = tv.tv_sec;
- millis = millis * 1000 + tv.tv_usec/1000;
- lMillis = Zorba::getInstance(0)->getItemFactory()->createLong(millis);
-#endif
-
- return zorba::ItemSequence_t(new zorba::SingletonItemSequence(lMillis));
-}
-
-/******************************************************************************
- *****************************************************************************/
-zorba::ExternalFunction*
-DateTimeModule::getExternalFunction(const zorba::String& aLocalname)
-{
- zorba::ExternalFunction*& lFunc = theFunctions[aLocalname];
- if (!lFunc) {
- if (aLocalname == "current-dateTime") {
- lFunc = new CurrentDateTimeFunction(this);
- } else if (aLocalname == "current-date") {
- lFunc = new CurrentDateFunction(this);
- } else if (aLocalname == "current-time") {
- lFunc = new CurrentTimeFunction(this);
- } else if (aLocalname == "timestamp") {
- lFunc = new TimestampFunction(this);
- }
- }
- return lFunc;
-}
-
-/******************************************************************************
- *****************************************************************************/
-DateTimeModule::~DateTimeModule()
-{
- for (FuncMap_t::const_iterator lIter = theFunctions.begin();
- lIter != theFunctions.end(); ++lIter) {
- delete lIter->second;
- }
- theFunctions.clear();
-}
-
-/******************************************************************************
- *****************************************************************************/
-void
-DateTimeModule::destroy()
-{
- if (!dynamic_cast<DateTimeModule*>(this)) {
- return;
- }
- delete this;
-}
-
-} /* namespace datetimemodule */ } /* namespace zorba */
-
-#ifdef WIN32
-# define DLL_EXPORT __declspec(dllexport)
-#else
-# define DLL_EXPORT __attribute__ ((visibility("default")))
-#endif
-
-extern "C" DLL_EXPORT zorba::ExternalModule* createModule() {
- return new zorba::datetimemodule::DateTimeModule();
-}
=== removed file 'modules/com/zorba-xquery/www/modules/datetime.xq.src/datetime.h'
--- modules/com/zorba-xquery/www/modules/datetime.xq.src/datetime.h 2012-09-19 21:16:15 +0000
+++ modules/com/zorba-xquery/www/modules/datetime.xq.src/datetime.h 1970-01-01 00:00:00 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright 2006-2010 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ZORBA_FILEMODULE_FILE_H
-#define ZORBA_FILEMODULE_FILE_H
-
-#include <map>
-#include <zorba/zorba.h>
-#include <zorba/external_module.h>
-#include <zorba/function.h>
-
-namespace zorba { namespace datetimemodule {
-
-/******************************************************************************
- *****************************************************************************/
-class DateTimeModule : public ExternalModule
-{
-protected:
- class ltstr
- {
- public:
- bool operator()(const String& s1, const String& s2) const
- {
- return s1.compare(s2) < 0;
- }
- };
-
- typedef std::map<String, ExternalFunction*, ltstr> FuncMap_t;
-
- FuncMap_t theFunctions;
-
-public:
- virtual zorba::String
- getURI() const { return "http://www.zorba-xquery.com/modules/datetime";; }
-
- virtual zorba::ExternalFunction*
- getExternalFunction(const zorba::String& aLocalname);
-
- virtual void
- destroy();
-
- virtual
- ~DateTimeModule();
-};
-
-
-/******************************************************************************
- *****************************************************************************/
-class CurrentDateTimeFunction : public ContextualExternalFunction
-{
-public:
- CurrentDateTimeFunction(const DateTimeModule* aModule)
- : theModule(aModule) {}
-
- virtual ~CurrentDateTimeFunction() {}
-
- virtual zorba::String
- getLocalName() const { return "current-dateTime"; }
-
- virtual zorba::ItemSequence_t
- evaluate(const Arguments_t&,
- const zorba::StaticContext*,
- const zorba::DynamicContext*) const;
-
- virtual String
- getURI() const { return theModule->getURI(); }
-
-protected:
- const DateTimeModule* theModule;
-};
-
-/******************************************************************************
- *****************************************************************************/
-class CurrentDateFunction : public ContextualExternalFunction
-{
-public:
- CurrentDateFunction(const DateTimeModule* aModule)
- : theModule(aModule) {}
-
- virtual ~CurrentDateFunction() {}
-
- virtual zorba::String
- getLocalName() const { return "current-date"; }
-
- virtual zorba::ItemSequence_t
- evaluate(const Arguments_t&,
- const zorba::StaticContext*,
- const zorba::DynamicContext*) const;
-
- virtual String
- getURI() const { return theModule->getURI(); }
-
-protected:
- const DateTimeModule* theModule;
-};
-
-/******************************************************************************
- *****************************************************************************/
-class CurrentTimeFunction : public ContextualExternalFunction
-{
-public:
- CurrentTimeFunction(const DateTimeModule* aModule)
- : theModule(aModule) {}
-
- virtual ~CurrentTimeFunction() {}
-
- virtual zorba::String
- getLocalName() const { return "current-time"; }
-
- virtual zorba::ItemSequence_t
- evaluate(const Arguments_t&,
- const zorba::StaticContext*,
- const zorba::DynamicContext*) const;
-
- virtual String
- getURI() const { return theModule->getURI(); }
-
-protected:
- const DateTimeModule* theModule;
-};
-
-/******************************************************************************
- *****************************************************************************/
-class TimestampFunction : public ContextualExternalFunction
-{
-public:
- TimestampFunction(const DateTimeModule* aModule)
- : theModule(aModule) {}
-
- virtual ~TimestampFunction() {}
-
- virtual zorba::String
- getLocalName() const { return "timestamp"; }
-
- virtual zorba::ItemSequence_t
- evaluate(const Arguments_t&,
- const zorba::StaticContext*,
- const zorba::DynamicContext*) const;
-
- virtual String
- getURI() const { return theModule->getURI(); }
-
-protected:
- const DateTimeModule* theModule;
-};
-
-} /* namespace datetimemodule */ } /* namespace zorba */
-
-#endif
=== modified file 'modules/com/zorba-xquery/www/modules/pregenerated/errors.xq'
--- modules/com/zorba-xquery/www/modules/pregenerated/errors.xq 2012-12-10 15:12:58 +0000
+++ modules/com/zorba-xquery/www/modules/pregenerated/errors.xq 2013-01-02 14:49:24 +0000
@@ -865,6 +865,26 @@
(:~
:)
+declare variable $zerr:ZDTP0001 as xs:QName := fn:QName($zerr:NS, "zerr:ZDTP0001");
+
+(:~
+:)
+declare variable $zerr:ZDTP0002 as xs:QName := fn:QName($zerr:NS, "zerr:ZDTP0002");
+
+(:~
+:)
+declare variable $zerr:ZDTP0003 as xs:QName := fn:QName($zerr:NS, "zerr:ZDTP0003");
+
+(:~
+:)
+declare variable $zerr:ZDTP0004 as xs:QName := fn:QName($zerr:NS, "zerr:ZDTP0004");
+
+(:~
+:)
+declare variable $zerr:ZDTP0005 as xs:QName := fn:QName($zerr:NS, "zerr:ZDTP0005");
+
+(:~
+:)
declare variable $zerr:ZJPE0001 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0001");
(:~
=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp 2012-12-11 20:27:40 +0000
+++ src/context/static_context.cpp 2013-01-02 14:49:24 +0000
@@ -461,6 +461,10 @@
#endif /* ZORBA_NO_FULL_TEXT */
const char*
+static_context::ZORBA_DATETIME_FN_NS =
+"http://www.zorba-xquery.com/modules/datetime";;
+
+const char*
static_context::ZORBA_XML_FN_OPTIONS_NS =
"http://www.zorba-xquery.com/modules/xml-options";;
@@ -542,6 +546,7 @@
#ifndef ZORBA_NO_FULL_TEXT
ns == ZORBA_FULL_TEXT_FN_NS ||
#endif /* ZORBA_NO_FULL_TEXT */
+ ns == ZORBA_DATETIME_FN_NS ||
#ifdef ZORBA_WITH_JSON
ns == JSONIQ_FN_NS ||
#endif /* ZORBA_WITH_JSON */
=== modified file 'src/context/static_context.h'
--- src/context/static_context.h 2012-12-06 01:17:18 +0000
+++ src/context/static_context.h 2013-01-02 14:49:24 +0000
@@ -546,6 +546,7 @@
#ifndef ZORBA_NO_FULL_TEXT
static const char* ZORBA_FULL_TEXT_FN_NS;
#endif /* ZORBA_NO_FULL_TEXT */
+ static const char* ZORBA_DATETIME_FN_NS;
static const char* ZORBA_XML_FN_OPTIONS_NS;
// Namespaces of virtual modules declaring zorba builtin functions
=== modified file 'src/diagnostics/diagnostic.cpp'
--- src/diagnostics/diagnostic.cpp 2012-09-19 21:16:15 +0000
+++ src/diagnostics/diagnostic.cpp 2013-01-02 14:49:24 +0000
@@ -127,6 +127,7 @@
case XQUERY_USER_DEFINED : o << "user-defined" ; break;
case ZORBA_API : o << "Zorba API" ; break;
+ case ZORBA_CORE_MODULE : o << "Zorba core module" ; break;
case ZORBA_DDF : o << "Zorba data-definition" ; break;
case ZORBA_DEBUGGER : o << "Zorba debugger" ; break;
case ZORBA_OS : o << "operating system" ; break;
=== modified file 'src/diagnostics/diagnostic_en.xml'
--- src/diagnostics/diagnostic_en.xml 2012-12-29 06:48:09 +0000
+++ src/diagnostics/diagnostic_en.xml 2013-01-02 14:49:24 +0000
@@ -2609,6 +2609,28 @@
<value>"continue loop" statement not inside while statement</value>
</diagnostic>
+ <!--////////// dateTime ParseErrors /////////////////////////////////////-->
+
+ <diagnostic code="ZDTP0001" name="INVALID_SPECIFICATION">
+ <value>'$1': invalid % conversion specification</value>
+ </diagnostic>
+
+ <diagnostic code="ZDTP0002" name="INSUFFICIENT_BUFFER">
+ <value>"$1": insufficient value to parse for "$2"</value>
+ </diagnostic>
+
+ <diagnostic code="ZDTP0003" name="INVALID_VALUE">
+ <value>"$1": invalid value for conversion specification(s) %$2</value>
+ </diagnostic>
+
+ <diagnostic code="ZDTP0004" name="LITERAL_MISMATCH">
+ <value>'$1': literal character mismatched '$2'</value>
+ </diagnostic>
+
+ <diagnostic code="ZDTP0005" name="INCOMPLETE_DATE_OR_TIME">
+ <value>'$1': incomplete date, time, or dateTime format</value>
+ </diagnostic>
+
<!--////////// JSON Parse Errors ////////////////////////////////////////-->
<diagnostic code="ZJPE0001" name="ILLEGAL_CHARACTER">
@@ -3834,6 +3856,10 @@
<value>Zorba API error</value>
</entry>
+ <entry key="Zorba core module error">
+ <value>Zorba core module error</value>
+ </entry>
+
<entry key="Zorba data-definition error">
<value>Zorba data-definition error</value>
</entry>
=== modified file 'src/diagnostics/pregenerated/diagnostic_list.cpp'
--- src/diagnostics/pregenerated/diagnostic_list.cpp 2012-12-21 22:05:39 +0000
+++ src/diagnostics/pregenerated/diagnostic_list.cpp 2013-01-02 14:49:24 +0000
@@ -1172,6 +1172,21 @@
ZorbaErrorCode XSST0010( "XSST0010" );
+ZorbaErrorCode ZDTP0001_INVALID_SPECIFICATION( "ZDTP0001" );
+
+
+ZorbaErrorCode ZDTP0002_INSUFFICIENT_BUFFER( "ZDTP0002" );
+
+
+ZorbaErrorCode ZDTP0003_INVALID_VALUE( "ZDTP0003" );
+
+
+ZorbaErrorCode ZDTP0004_LITERAL_MISMATCH( "ZDTP0004" );
+
+
+ZorbaErrorCode ZDTP0005_INCOMPLETE_DATE_OR_TIME( "ZDTP0005" );
+
+
ZorbaErrorCode ZJPE0001_ILLEGAL_CHARACTER( "ZJPE0001" );
=== modified file 'src/diagnostics/pregenerated/dict_en.cpp'
--- src/diagnostics/pregenerated/dict_en.cpp 2012-12-29 06:48:09 +0000
+++ src/diagnostics/pregenerated/dict_en.cpp 2013-01-02 14:49:24 +0000
@@ -410,6 +410,11 @@
{ "ZDST0044", "\"$1\": integrity constraint declaration not allowed in main module" },
{ "ZDST0048", "\"$1\": integrity constraint declaration in foreign module" },
{ "ZDST0060", "\"$1\": feature not supported; $2" },
+ { "ZDTP0001", "'$1': invalid % conversion specification" },
+ { "ZDTP0002", "\"$1\": insufficient value to parse for \"$2\"" },
+ { "ZDTP0003", "\"$1\": invalid value for conversion specification(s) %$2" },
+ { "ZDTP0004", "'$1': literal character mismatched '$2'" },
+ { "ZDTP0005", "'$1': incomplete date, time, or dateTime format" },
{ "ZDTY0001", "\"$1\": invalid item type in collection \"$2\"" },
{ "ZDTY0010", "non-node item in domain expression of index $1" },
{ "ZDTY0011", "item type \"$1\" does not match declared type \"$2\" for key expression of index $3" },
@@ -923,6 +928,7 @@
{ "~ZXQP0025_RESOURCE_NOT_FOUND", "resource not found" },
{ "~ZeroLenURI", "zero-length URI (and no base URI given)" },
{ "~Zorba API error", "Zorba API error" },
+ { "~Zorba core module error", "Zorba core module error" },
{ "~Zorba data-definition error", "Zorba data-definition error" },
{ "~Zorba dynamic error", "Zorba dynamic error" },
{ "~Zorba dynamic warning", "Zorba dynamic warning" },
=== modified file 'src/diagnostics/qname.cpp'
--- src/diagnostics/qname.cpp 2012-09-19 21:16:15 +0000
+++ src/diagnostics/qname.cpp 2013-01-02 14:49:24 +0000
@@ -112,7 +112,10 @@
switch ( name[1] ) {
case 'A': return ZORBA_API;
case 'C': return ZORBA_SERIALIZATION;
- case 'D': return ZORBA_DDF;
+ case 'D': switch ( name[3] ) {
+ case 'P': return ZORBA_CORE_MODULE;
+ default : return ZORBA_DDF;
+ }
case 'G': return ZORBA_DEBUGGER;
case 'J': switch ( name[2] ) {
case 'P': return JSON_PARSER;
=== modified file 'src/functions/library.cpp'
--- src/functions/library.cpp 2012-09-19 21:16:15 +0000
+++ src/functions/library.cpp 2013-01-02 14:49:24 +0000
@@ -27,33 +27,41 @@
#include "functions/func_accessors.h"
#include "functions/func_accessors_impl.h"
#include "functions/func_any_uri.h"
+#include "functions/func_apply.h"
#include "functions/func_arithmetic.h"
#include "functions/func_base64.h"
#include "functions/func_booleans.h"
#include "functions/func_booleans_impl.h"
#include "functions/func_collections.h"
#include "functions/func_context.h"
-#include "functions/func_other_diagnostics.h"
+#include "functions/func_datetime.h"
+#include "functions/func_documents.h"
#include "functions/func_durations_dates_times.h"
#include "functions/func_durations_dates_times_impl.h"
#include "functions/func_enclosed.h"
#include "functions/func_errors_and_diagnostics.h"
+#include "functions/func_eval.h"
+#include "functions/func_fetch.h"
#include "functions/func_fnput.h"
#include "functions/func_hoist.h"
+#include "functions/func_ic_ddl.h"
#include "functions/func_index_ddl.h"
#include "functions/func_index_func.h"
-#include "functions/func_ic_ddl.h"
+#include "functions/func_json.h"
+#include "functions/func_maps.h"
#include "functions/func_maths.h"
-#include "functions/func_nodes.h"
#include "functions/func_node_position.h"
#include "functions/func_node_sort_distinct.h"
+#include "functions/func_nodes.h"
#include "functions/func_numerics.h"
#include "functions/func_numerics_impl.h"
-#include "functions/func_parsing_and_serializing.h"
+#include "functions/func_other_diagnostics.h"
#include "functions/func_parse_fragment.h"
#include "functions/func_parse_fragment_impl.h"
+#include "functions/func_parsing_and_serializing.h"
#include "functions/func_qnames.h"
#include "functions/func_random.h"
+#include "functions/func_reflection.h"
#include "functions/func_schema.h"
#include "functions/func_sctx.h"
#include "functions/func_sequences.h"
@@ -61,15 +69,8 @@
#include "functions/func_strings.h"
#include "functions/func_strings_impl.h"
#include "functions/func_uris.h"
-#include "functions/func_json.h"
#include "functions/func_var_decl.h"
#include "functions/func_xqdoc.h"
-#include "functions/func_documents.h"
-#include "functions/func_maps.h"
-#include "functions/func_eval.h"
-#include "functions/func_reflection.h"
-#include "functions/func_apply.h"
-#include "functions/func_fetch.h"
#ifndef ZORBA_NO_FULL_TEXT
#include "functions/func_ft_module.h"
#include "runtime/full_text/ft_module_impl.h"
@@ -118,6 +119,7 @@
populate_context_booleans_impl(sctx);
populate_context_collections(sctx);
populate_context_context(sctx);
+ populate_context_datetime(sctx);
populate_context_durations_dates_times(sctx);
populate_context_durations_dates_times_impl(sctx);
populate_context_errors_and_diagnostics(sctx);
=== added file 'src/functions/pregenerated/func_datetime.cpp'
--- src/functions/pregenerated/func_datetime.cpp 1970-01-01 00:00:00 +0000
+++ src/functions/pregenerated/func_datetime.cpp 2013-01-02 14:49:24 +0000
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2006-2012 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ******************************************
+// * *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME *
+// * *
+// ******************************************
+
+
+#include "stdafx.h"
+#include "runtime/datetime/datetime.h"
+#include "functions/func_datetime.h"
+
+
+namespace zorba{
+
+
+
+PlanIter_t fn_zorba_dateTime_current_date::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new CurrentDate(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_dateTime_current_dateTime::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new CurrentDateTime(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_dateTime_current_time::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new CurrentTime(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_dateTime_parse_date::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new ParseDate(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_dateTime_parse_dateTime::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new ParseDateTime(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_dateTime_parse_time::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new ParseTime(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_dateTime_timestamp::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new Timestamp(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_dateTime_utc_offset::codegen(
+ CompilerCB*,
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& argv,
+ expr& ann) const
+{
+ return new UTCOffset(sctx, loc, argv);
+}
+
+void populate_context_datetime(static_context* sctx)
+{
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_current_date,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","current-date";),
+ GENV_TYPESYSTEM.DATE_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_CURRENT_DATE_0);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_current_dateTime,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","current-dateTime";),
+ GENV_TYPESYSTEM.DATETIME_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_CURRENT_DATETIME_0);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_current_time,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","current-time";),
+ GENV_TYPESYSTEM.TIME_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_CURRENT_TIME_0);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_parse_date,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","parse-date";),
+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
+ GENV_TYPESYSTEM.DATE_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_PARSE_DATE_2);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_parse_dateTime,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","parse-dateTime";),
+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
+ GENV_TYPESYSTEM.DATETIME_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_PARSE_DATETIME_2);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_parse_time,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","parse-time";),
+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
+ GENV_TYPESYSTEM.TIME_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_PARSE_TIME_2);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_timestamp,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","timestamp";),
+ GENV_TYPESYSTEM.LONG_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_TIMESTAMP_0);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, fn_zorba_dateTime_utc_offset,
+ (createQName("http://www.zorba-xquery.com/modules/datetime","","utc-offset";),
+ GENV_TYPESYSTEM.LONG_TYPE_ONE),
+ FunctionConsts::FN_ZORBA_DATETIME_UTC_OFFSET_0);
+
+ }
+
+}
+
+
+}
+
+
+
=== added file 'src/functions/pregenerated/func_datetime.h'
--- src/functions/pregenerated/func_datetime.h 1970-01-01 00:00:00 +0000
+++ src/functions/pregenerated/func_datetime.h 2013-01-02 14:49:24 +0000
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2006-2012 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ******************************************
+// * *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME *
+// * *
+// ******************************************
+
+
+#ifndef ZORBA_FUNCTIONS_DATETIME_H
+#define ZORBA_FUNCTIONS_DATETIME_H
+
+
+#include "common/shared_types.h"
+#include "functions/function_impl.h"
+
+
+namespace zorba {
+
+
+void populate_context_datetime(static_context* sctx);
+
+
+
+
+//fn-zorba-dateTime:current-date
+class fn_zorba_dateTime_current_date : public function
+{
+public:
+ fn_zorba_dateTime_current_date(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+//fn-zorba-dateTime:current-dateTime
+class fn_zorba_dateTime_current_dateTime : public function
+{
+public:
+ fn_zorba_dateTime_current_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+//fn-zorba-dateTime:current-time
+class fn_zorba_dateTime_current_time : public function
+{
+public:
+ fn_zorba_dateTime_current_time(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+//fn-zorba-dateTime:parse-date
+class fn_zorba_dateTime_parse_date : public function
+{
+public:
+ fn_zorba_dateTime_parse_date(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+//fn-zorba-dateTime:parse-dateTime
+class fn_zorba_dateTime_parse_dateTime : public function
+{
+public:
+ fn_zorba_dateTime_parse_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+//fn-zorba-dateTime:parse-time
+class fn_zorba_dateTime_parse_time : public function
+{
+public:
+ fn_zorba_dateTime_parse_time(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+//fn-zorba-dateTime:timestamp
+class fn_zorba_dateTime_timestamp : public function
+{
+public:
+ fn_zorba_dateTime_timestamp(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+//fn-zorba-dateTime:utc-offset
+class fn_zorba_dateTime_utc_offset : public function
+{
+public:
+ fn_zorba_dateTime_utc_offset(const signature& sig, FunctionConsts::FunctionKind kind)
+ :
+ function(sig, kind)
+ {
+
+ }
+
+ CODEGEN_DECL();
+};
+
+
+} //namespace zorba
+
+
+#endif
+/*
+ * Local variables:
+ * mode: c++
+ * End:
+ */
=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h 2012-12-10 16:02:05 +0000
+++ src/functions/pregenerated/function_enum.h 2013-01-02 14:49:24 +0000
@@ -143,6 +143,14 @@
FN_POSITION_0,
FN_LAST_0,
FN_STATIC_BASE_URI_0,
+ FN_ZORBA_DATETIME_CURRENT_DATE_0,
+ FN_ZORBA_DATETIME_CURRENT_DATETIME_0,
+ FN_ZORBA_DATETIME_CURRENT_TIME_0,
+ FN_ZORBA_DATETIME_PARSE_DATE_2,
+ FN_ZORBA_DATETIME_PARSE_DATETIME_2,
+ FN_ZORBA_DATETIME_PARSE_TIME_2,
+ FN_ZORBA_DATETIME_TIMESTAMP_0,
+ FN_ZORBA_DATETIME_UTC_OFFSET_0,
FN_YEARS_FROM_DURATION_1,
FN_MONTHS_FROM_DURATION_1,
FN_DAYS_FROM_DURATION_1,
=== added directory 'src/runtime/datetime'
=== added file 'src/runtime/datetime/datetime_impl.cpp'
--- src/runtime/datetime/datetime_impl.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/datetime/datetime_impl.cpp 2013-01-02 14:49:24 +0000
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2006-2011 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "stdafx.h"
+
+#include <cstring>
+
+#include <zorba/diagnostic_list.h>
+
+#include "diagnostics/xquery_exception.h"
+#include "runtime/datetime/datetime.h"
+#include "store/api/item_factory.h"
+#include "system/globalenv.h"
+#include "util/ascii_util.h"
+#include "util/strptime.h"
+#include "util/time_util.h"
+
+using namespace std;
+
+namespace zorba {
+
+enum parse_type {
+ parse_date,
+ parse_time,
+ parse_dateTime
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void strptime( zstring const &buf, zstring const &fmt,
+ parse_type parse_what, time::ztm *tm,
+ QueryLoc const &loc ) {
+ try {
+ unsigned set_fields;
+ ::memset( tm, 0, sizeof( *tm ) );
+ time::strptime( buf, fmt, tm, &set_fields );
+
+ bool set_mday = set_fields & time::set_mday;
+ bool set_mon = set_fields & time::set_mon;
+ bool const set_yday = set_fields & time::set_yday;
+ bool const set_year = set_fields & time::set_year;
+
+ if ( set_yday && set_year && (!set_mday || !set_mon) ) {
+ //
+ // Given yday and year, "back fill" mday and/or mon.
+ //
+ time::calc_mday_mon(
+ tm->tm_yday,
+ set_mday ? nullptr : reinterpret_cast<unsigned*>( &tm->tm_mday ),
+ set_mon ? nullptr : reinterpret_cast<unsigned*>( &tm->tm_mon ),
+ tm->tm_year
+ );
+ set_mday = set_mon = true;
+ }
+
+ switch ( parse_what ) {
+ case parse_date:
+ if ( set_mday && set_mon && set_year )
+ return;
+ break;
+ case parse_dateTime:
+ if ( !(set_mday && set_mon && set_year) )
+ break;
+ // no break;
+ case parse_time:
+ if ( !(set_fields & time::set_hour) )
+ break;
+ if ( !(set_fields & time::set_min) )
+ tm->tm_min = 0;
+ if ( !(set_fields & time::set_sec) )
+ tm->tm_sec = 0;
+ if ( !(set_fields & time::set_gmtoff) )
+ tm->ZTM_GMTOFF = 0;
+ return;
+ }
+
+ throw XQUERY_EXCEPTION(
+ zerr::ZDTP0005_INCOMPLETE_DATE_OR_TIME,
+ ERROR_PARAMS( fmt ),
+ ERROR_LOC( loc )
+ );
+ }
+ catch ( time::insufficient_buffer const& ) {
+ throw XQUERY_EXCEPTION(
+ zerr::ZDTP0002_INSUFFICIENT_BUFFER,
+ ERROR_PARAMS( buf, fmt ),
+ ERROR_LOC( loc )
+ );
+ }
+ catch ( time::invalid_specification const &e ) {
+ throw XQUERY_EXCEPTION(
+ zerr::ZDTP0001_INVALID_SPECIFICATION,
+ ERROR_PARAMS( ascii::printable_char( e.get_spec() ) ),
+ ERROR_LOC( loc )
+ );
+ }
+ catch ( time::invalid_value const &e ) {
+ throw XQUERY_EXCEPTION(
+ zerr::ZDTP0003_INVALID_VALUE,
+ ERROR_PARAMS( e.get_value(), e.get_specs() ),
+ ERROR_LOC( loc )
+ );
+ }
+ catch ( time::literal_mismatch const &e ) {
+ throw XQUERY_EXCEPTION(
+ zerr::ZDTP0004_LITERAL_MISMATCH,
+ ERROR_PARAMS(
+ ascii::printable_char( e.get_got() ),
+ ascii::printable_char( e.get_expected() )
+ ),
+ ERROR_LOC( loc )
+ );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool CurrentDate::nextImpl( store::Item_t& result,
+ PlanState &plan_state ) const {
+ time::ztm tm;
+ time::get_gmtime( &tm );
+
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+
+ GENV_ITEMFACTORY->createDate(
+ result,
+ static_cast<short>( tm.tm_year + TM_YEAR_BASE ),
+ static_cast<short>( tm.tm_mon + 1 ),
+ static_cast<short>( tm.tm_mday )
+ );
+
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+bool CurrentDateTime::nextImpl( store::Item_t& result,
+ PlanState &plan_state ) const {
+ time_t sec;
+ time::usec_type usec;
+ time::get_epoch( &sec, &usec );
+ time::ztm tm;
+ time::get_gmtime( &tm, sec );
+
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+
+ GENV_ITEMFACTORY->createDateTime(
+ result,
+ static_cast<short>( tm.tm_year + TM_YEAR_BASE ),
+ static_cast<short>( tm.tm_mon + 1 ),
+ static_cast<short>( tm.tm_mday ),
+ static_cast<short>( tm.tm_hour ),
+ static_cast<short>( tm.tm_min ),
+ tm.tm_sec + usec / 1000000.0,
+ static_cast<short>( tm.ZTM_GMTOFF / 3600 )
+ );
+
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+bool CurrentTime::nextImpl( store::Item_t& result,
+ PlanState &plan_state ) const {
+ time_t sec;
+ time::usec_type usec;
+ time::get_epoch( &sec, &usec );
+ time::ztm tm;
+ time::get_gmtime( &tm, sec );
+
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+
+ GENV_ITEMFACTORY->createTime(
+ result,
+ static_cast<short>( tm.tm_hour ),
+ static_cast<short>( tm.tm_min ),
+ tm.tm_sec + usec / 1000000.0,
+ static_cast<short>( tm.ZTM_GMTOFF / 3600 )
+ );
+
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+bool ParseDate::nextImpl( store::Item_t& result, PlanState &plan_state ) const {
+ store::Item_t item;
+ time::ztm tm;
+ zstring buf, fmt;
+
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+
+ consumeNext( item, theChildren[0], plan_state );
+ item->getStringValue2( buf );
+ consumeNext( item, theChildren[1], plan_state );
+ item->getStringValue2( fmt );
+
+ strptime( buf, fmt, parse_date, &tm, loc );
+ GENV_ITEMFACTORY->createDate(
+ result,
+ static_cast<short>( tm.tm_year + TM_YEAR_BASE ),
+ static_cast<short>( tm.tm_mon + 1 ),
+ static_cast<short>( tm.tm_mday )
+ );
+
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+bool ParseDateTime::nextImpl( store::Item_t& result,
+ PlanState &plan_state ) const {
+ store::Item_t item;
+ zstring buf, fmt;
+ time::ztm tm;
+
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+
+ consumeNext( item, theChildren[0], plan_state );
+ item->getStringValue2( buf );
+ consumeNext( item, theChildren[1], plan_state );
+ item->getStringValue2( fmt );
+
+ strptime( buf, fmt, parse_dateTime, &tm, loc );
+ GENV_ITEMFACTORY->createDateTime(
+ result,
+ static_cast<short>( tm.tm_year + TM_YEAR_BASE ),
+ static_cast<short>( tm.tm_mon + 1 ),
+ static_cast<short>( tm.tm_mday ),
+ static_cast<short>( tm.tm_hour ),
+ static_cast<short>( tm.tm_min ),
+ tm.tm_sec,
+ static_cast<short>( tm.ZTM_GMTOFF / 3600 )
+ );
+
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+bool ParseTime::nextImpl( store::Item_t& result, PlanState &plan_state ) const {
+ store::Item_t item;
+ time::ztm tm;
+ zstring buf, fmt;
+
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+
+ consumeNext( item, theChildren[0], plan_state );
+ item->getStringValue2( buf );
+ consumeNext( item, theChildren[1], plan_state );
+ item->getStringValue2( fmt );
+
+ strptime( buf, fmt, parse_time, &tm, loc );
+ GENV_ITEMFACTORY->createTime(
+ result,
+ static_cast<short>( tm.tm_hour ),
+ static_cast<short>( tm.tm_min ),
+ tm.tm_sec,
+ static_cast<short>( tm.ZTM_GMTOFF / 3600 )
+ );
+
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+bool Timestamp::nextImpl( store::Item_t& result,
+ PlanState &plan_state ) const {
+ time_t sec;
+ time::get_epoch( &sec );
+
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+ GENV_ITEMFACTORY->createLong( result, sec );
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+bool UTCOffset::nextImpl( store::Item_t& result,
+ PlanState &plan_state ) const {
+ PlanIteratorState *state;
+ DEFAULT_STACK_INIT( PlanIteratorState, state, plan_state );
+ GENV_ITEMFACTORY->createLong( result, time::get_gmt_offset() );
+ STACK_PUSH( true, state );
+ STACK_END( state );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */
=== added directory 'src/runtime/datetime/pregenerated'
=== added file 'src/runtime/datetime/pregenerated/datetime.cpp'
--- src/runtime/datetime/pregenerated/datetime.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/datetime/pregenerated/datetime.cpp 2013-01-02 14:49:24 +0000
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2006-2012 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ******************************************
+// * *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME *
+// * *
+// ******************************************
+
+#include "stdafx.h"
+#include "zorbatypes/rchandle.h"
+#include "zorbatypes/zstring.h"
+#include "runtime/visitors/planiter_visitor.h"
+#include "runtime/datetime/datetime.h"
+#include "system/globalenv.h"
+
+
+
+namespace zorba {
+
+// <CurrentDate>
+SERIALIZABLE_CLASS_VERSIONS(CurrentDate)
+
+void CurrentDate::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<CurrentDate, PlanIteratorState>*)this);
+}
+
+
+void CurrentDate::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+CurrentDate::~CurrentDate() {}
+
+// </CurrentDate>
+
+
+// <CurrentDateTime>
+SERIALIZABLE_CLASS_VERSIONS(CurrentDateTime)
+
+void CurrentDateTime::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<CurrentDateTime, PlanIteratorState>*)this);
+}
+
+
+void CurrentDateTime::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+CurrentDateTime::~CurrentDateTime() {}
+
+// </CurrentDateTime>
+
+
+// <CurrentTime>
+SERIALIZABLE_CLASS_VERSIONS(CurrentTime)
+
+void CurrentTime::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<CurrentTime, PlanIteratorState>*)this);
+}
+
+
+void CurrentTime::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+CurrentTime::~CurrentTime() {}
+
+// </CurrentTime>
+
+
+// <ParseDate>
+SERIALIZABLE_CLASS_VERSIONS(ParseDate)
+
+void ParseDate::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<ParseDate, PlanIteratorState>*)this);
+}
+
+
+void ParseDate::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+ParseDate::~ParseDate() {}
+
+// </ParseDate>
+
+
+// <ParseDateTime>
+SERIALIZABLE_CLASS_VERSIONS(ParseDateTime)
+
+void ParseDateTime::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<ParseDateTime, PlanIteratorState>*)this);
+}
+
+
+void ParseDateTime::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+ParseDateTime::~ParseDateTime() {}
+
+// </ParseDateTime>
+
+
+// <ParseTime>
+SERIALIZABLE_CLASS_VERSIONS(ParseTime)
+
+void ParseTime::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<ParseTime, PlanIteratorState>*)this);
+}
+
+
+void ParseTime::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+ParseTime::~ParseTime() {}
+
+// </ParseTime>
+
+
+// <Timestamp>
+SERIALIZABLE_CLASS_VERSIONS(Timestamp)
+
+void Timestamp::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<Timestamp, PlanIteratorState>*)this);
+}
+
+
+void Timestamp::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+Timestamp::~Timestamp() {}
+
+// </Timestamp>
+
+
+// <UTCOffset>
+SERIALIZABLE_CLASS_VERSIONS(UTCOffset)
+
+void UTCOffset::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<UTCOffset, PlanIteratorState>*)this);
+}
+
+
+void UTCOffset::accept(PlanIterVisitor& v) const
+{
+ v.beginVisit(*this);
+
+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter ){
+ (*lIter)->accept(v);
+ }
+
+ v.endVisit(*this);
+}
+
+UTCOffset::~UTCOffset() {}
+
+// </UTCOffset>
+
+
+
+}
+
+
=== added file 'src/runtime/datetime/pregenerated/datetime.h'
--- src/runtime/datetime/pregenerated/datetime.h 1970-01-01 00:00:00 +0000
+++ src/runtime/datetime/pregenerated/datetime.h 2013-01-02 14:49:24 +0000
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2006-2012 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ******************************************
+// * *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME *
+// * *
+// ******************************************
+#ifndef ZORBA_RUNTIME_DATETIME_DATETIME_H
+#define ZORBA_RUNTIME_DATETIME_DATETIME_H
+
+
+#include "common/shared_types.h"
+
+
+
+#include "runtime/base/narybase.h"
+#include "runtime/base/narybase.h"
+
+
+namespace zorba {
+
+/**
+ *
+ * function for getting the current date
+ *
+ * Author: Zorba Team
+ */
+class CurrentDate : public NaryBaseIterator<CurrentDate, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(CurrentDate);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(CurrentDate,
+ NaryBaseIterator<CurrentDate, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ CurrentDate(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<CurrentDate, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~CurrentDate();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ *
+ * function for getting the current date and time
+ *
+ * Author: Zorba Team
+ */
+class CurrentDateTime : public NaryBaseIterator<CurrentDateTime, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(CurrentDateTime);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(CurrentDateTime,
+ NaryBaseIterator<CurrentDateTime, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ CurrentDateTime(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<CurrentDateTime, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~CurrentDateTime();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ *
+ * function for getting the current time
+ *
+ * Author: Zorba Team
+ */
+class CurrentTime : public NaryBaseIterator<CurrentTime, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(CurrentTime);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(CurrentTime,
+ NaryBaseIterator<CurrentTime, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ CurrentTime(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<CurrentTime, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~CurrentTime();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ *
+ * function for parsing strings into a date
+ *
+ * Author: Zorba Team
+ */
+class ParseDate : public NaryBaseIterator<ParseDate, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(ParseDate);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(ParseDate,
+ NaryBaseIterator<ParseDate, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ ParseDate(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<ParseDate, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~ParseDate();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ *
+ * function for parsing strings into a dateTime
+ *
+ * Author: Zorba Team
+ */
+class ParseDateTime : public NaryBaseIterator<ParseDateTime, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(ParseDateTime);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(ParseDateTime,
+ NaryBaseIterator<ParseDateTime, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ ParseDateTime(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<ParseDateTime, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~ParseDateTime();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ *
+ * function for parsing strings into a time
+ *
+ * Author: Zorba Team
+ */
+class ParseTime : public NaryBaseIterator<ParseTime, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(ParseTime);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(ParseTime,
+ NaryBaseIterator<ParseTime, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ ParseTime(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<ParseTime, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~ParseTime();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ *
+ * function for getting the current number of seconds since epoch
+ *
+ * Author: Zorba Team
+ */
+class Timestamp : public NaryBaseIterator<Timestamp, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(Timestamp);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(Timestamp,
+ NaryBaseIterator<Timestamp, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ Timestamp(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<Timestamp, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~Timestamp();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ *
+ * function for getting the current offset from UTC
+ *
+ * Author: Zorba Team
+ */
+class UTCOffset : public NaryBaseIterator<UTCOffset, PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(UTCOffset);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(UTCOffset,
+ NaryBaseIterator<UTCOffset, PlanIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+ UTCOffset(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& children)
+ :
+ NaryBaseIterator<UTCOffset, PlanIteratorState>(sctx, loc, children)
+ {}
+
+ virtual ~UTCOffset();
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+}
+#endif
+/*
+ * Local variables:
+ * mode: c++
+ * End:
+ */
=== modified file 'src/runtime/pregenerated/iterator_enum.h'
--- src/runtime/pregenerated/iterator_enum.h 2012-12-10 16:02:05 +0000
+++ src/runtime/pregenerated/iterator_enum.h 2013-01-02 14:49:24 +0000
@@ -72,6 +72,14 @@
TYPE_CurrentTimeIterator,
TYPE_ImplicitTimezoneIterator,
TYPE_DefaultCollationIterator,
+ TYPE_CurrentDate,
+ TYPE_CurrentDateTime,
+ TYPE_CurrentTime,
+ TYPE_ParseDate,
+ TYPE_ParseDateTime,
+ TYPE_ParseTime,
+ TYPE_Timestamp,
+ TYPE_UTCOffset,
TYPE_DebugIterator,
TYPE_YearsFromDurationIterator,
TYPE_MonthsFromDurationIterator,
=== added directory 'src/runtime/spec/datetime'
=== added file 'src/runtime/spec/datetime/datetime.xml'
--- src/runtime/spec/datetime/datetime.xml 1970-01-01 00:00:00 +0000
+++ src/runtime/spec/datetime/datetime.xml 2013-01-02 14:49:24 +0000
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<zorba:iterators
+ xmlns:zorba="http://www.zorba-xquery.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.zorba-xquery.com ../runtime.xsd">
+
+<!-- ////////////////////////////////////////////////////////////////////// -->
+
+<zorba:header>
+ <zorba:include form="Quoted">runtime/base/narybase.h</zorba:include>
+</zorba:header>
+
+<zorba:iterator name="CurrentDate">
+ <zorba:description author="Zorba Team">
+ function for getting the current date
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="current-date" prefix="fn-zorba-dateTime">
+ <zorba:output>xs:date</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<zorba:iterator name="CurrentDateTime">
+ <zorba:description author="Zorba Team">
+ function for getting the current date and time
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="current-dateTime" prefix="fn-zorba-dateTime">
+ <zorba:output>xs:dateTime</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<zorba:iterator name="CurrentTime">
+ <zorba:description author="Zorba Team">
+ function for getting the current time
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="current-time" prefix="fn-zorba-dateTime">
+ <zorba:output>xs:time</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<zorba:iterator name="ParseDate">
+ <zorba:description author="Zorba Team">
+ function for parsing strings into a date
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="parse-date" prefix="fn-zorba-dateTime">
+ <zorba:param>xs:string</zorba:param>
+ <zorba:param>xs:string</zorba:param>
+ <zorba:output>xs:date</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<zorba:iterator name="ParseDateTime">
+ <zorba:description author="Zorba Team">
+ function for parsing strings into a dateTime
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="parse-dateTime" prefix="fn-zorba-dateTime">
+ <zorba:param>xs:string</zorba:param>
+ <zorba:param>xs:string</zorba:param>
+ <zorba:output>xs:dateTime</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<zorba:iterator name="ParseTime">
+ <zorba:description author="Zorba Team">
+ function for parsing strings into a time
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="parse-time" prefix="fn-zorba-dateTime">
+ <zorba:param>xs:string</zorba:param>
+ <zorba:param>xs:string</zorba:param>
+ <zorba:output>xs:time</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<zorba:iterator name="Timestamp">
+ <zorba:description author="Zorba Team">
+ function for getting the current number of seconds since epoch
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="timestamp" prefix="fn-zorba-dateTime">
+ <zorba:output>xs:long</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<zorba:iterator name="UTCOffset">
+ <zorba:description author="Zorba Team">
+ function for getting the current offset from UTC
+ </zorba:description>
+ <zorba:function>
+ <zorba:signature localname="utc-offset" prefix="fn-zorba-dateTime">
+ <zorba:output>xs:long</zorba:output>
+ </zorba:signature>
+ </zorba:function>
+</zorba:iterator>
+
+<!-- ////////////////////////////////////////////////////////////////////// -->
+
+</zorba:iterators>
+
+<!-- vim:set et sw=2 ts=2: -->
=== modified file 'src/runtime/spec/mappings.xml'
--- src/runtime/spec/mappings.xml 2012-10-08 12:09:36 +0000
+++ src/runtime/spec/mappings.xml 2013-01-02 14:49:24 +0000
@@ -81,6 +81,11 @@
define="ZORBA_FULL_TEXT_FN_NS"
prefix="full-text"/>
+ <zorba:namespace
+ uri="http://www.zorba-xquery.com/modules/datetime";
+ define="ZORBA_DATETIME_FN_NS"
+ prefix="fn-zorba-dateTime"/>
+
<zorba:namespace uri="http://www.zorba-xquery.com/modules/xqdoc";
define="ZORBA_XQDOC_FN_NS"
prefix="fn-zorba-xqdoc"/>
=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
--- src/runtime/visitors/pregenerated/planiter_visitor.h 2012-12-14 21:50:53 +0000
+++ src/runtime/visitors/pregenerated/planiter_visitor.h 2013-01-02 14:49:24 +0000
@@ -134,6 +134,22 @@
class DefaultCollationIterator;
+ class CurrentDate;
+
+ class CurrentDateTime;
+
+ class CurrentTime;
+
+ class ParseDate;
+
+ class ParseDateTime;
+
+ class ParseTime;
+
+ class Timestamp;
+
+ class UTCOffset;
+
#ifdef ZORBA_WITH_DEBUGGER
class DebugIterator;
#endif
@@ -900,6 +916,30 @@
virtual void beginVisit ( const DefaultCollationIterator& ) = 0;
virtual void endVisit ( const DefaultCollationIterator& ) = 0;
+ virtual void beginVisit ( const CurrentDate& ) = 0;
+ virtual void endVisit ( const CurrentDate& ) = 0;
+
+ virtual void beginVisit ( const CurrentDateTime& ) = 0;
+ virtual void endVisit ( const CurrentDateTime& ) = 0;
+
+ virtual void beginVisit ( const CurrentTime& ) = 0;
+ virtual void endVisit ( const CurrentTime& ) = 0;
+
+ virtual void beginVisit ( const ParseDate& ) = 0;
+ virtual void endVisit ( const ParseDate& ) = 0;
+
+ virtual void beginVisit ( const ParseDateTime& ) = 0;
+ virtual void endVisit ( const ParseDateTime& ) = 0;
+
+ virtual void beginVisit ( const ParseTime& ) = 0;
+ virtual void endVisit ( const ParseTime& ) = 0;
+
+ virtual void beginVisit ( const Timestamp& ) = 0;
+ virtual void endVisit ( const Timestamp& ) = 0;
+
+ virtual void beginVisit ( const UTCOffset& ) = 0;
+ virtual void endVisit ( const UTCOffset& ) = 0;
+
#ifdef ZORBA_WITH_DEBUGGER
virtual void beginVisit ( const DebugIterator& ) = 0;
virtual void endVisit ( const DebugIterator& ) = 0;
=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
--- src/runtime/visitors/pregenerated/printer_visitor.cpp 2012-12-14 21:50:53 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.cpp 2013-01-02 14:49:24 +0000
@@ -41,6 +41,7 @@
#include "runtime/booleans/booleans.h"
#include "runtime/collections/collections.h"
#include "runtime/context/context.h"
+#include "runtime/datetime/datetime.h"
#include "runtime/debug/debug_iterator.h"
#include "runtime/durations_dates_times/durations_dates_times.h"
#include "runtime/errors_and_diagnostics/errors_and_diagnostics.h"
@@ -701,6 +702,118 @@
}
// </DefaultCollationIterator>
+
+// <CurrentDate>
+void PrinterVisitor::beginVisit ( const CurrentDate& a) {
+ thePrinter.startBeginVisit("CurrentDate", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const CurrentDate& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </CurrentDate>
+
+
+// <CurrentDateTime>
+void PrinterVisitor::beginVisit ( const CurrentDateTime& a) {
+ thePrinter.startBeginVisit("CurrentDateTime", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const CurrentDateTime& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </CurrentDateTime>
+
+
+// <CurrentTime>
+void PrinterVisitor::beginVisit ( const CurrentTime& a) {
+ thePrinter.startBeginVisit("CurrentTime", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const CurrentTime& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </CurrentTime>
+
+
+// <ParseDate>
+void PrinterVisitor::beginVisit ( const ParseDate& a) {
+ thePrinter.startBeginVisit("ParseDate", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const ParseDate& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </ParseDate>
+
+
+// <ParseDateTime>
+void PrinterVisitor::beginVisit ( const ParseDateTime& a) {
+ thePrinter.startBeginVisit("ParseDateTime", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const ParseDateTime& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </ParseDateTime>
+
+
+// <ParseTime>
+void PrinterVisitor::beginVisit ( const ParseTime& a) {
+ thePrinter.startBeginVisit("ParseTime", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const ParseTime& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </ParseTime>
+
+
+// <Timestamp>
+void PrinterVisitor::beginVisit ( const Timestamp& a) {
+ thePrinter.startBeginVisit("Timestamp", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const Timestamp& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </Timestamp>
+
+
+// <UTCOffset>
+void PrinterVisitor::beginVisit ( const UTCOffset& a) {
+ thePrinter.startBeginVisit("UTCOffset", ++theId);
+ printCommons( &a, theId );
+ thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const UTCOffset& ) {
+ thePrinter.startEndVisit();
+ thePrinter.endEndVisit();
+}
+// </UTCOffset>
+
#ifdef ZORBA_WITH_DEBUGGER
// <DebugIterator>
void PrinterVisitor::beginVisit ( const DebugIterator& a) {
=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
--- src/runtime/visitors/pregenerated/printer_visitor.h 2012-12-14 21:50:53 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.h 2013-01-02 14:49:24 +0000
@@ -203,6 +203,30 @@
void beginVisit( const DefaultCollationIterator& );
void endVisit ( const DefaultCollationIterator& );
+ void beginVisit( const CurrentDate& );
+ void endVisit ( const CurrentDate& );
+
+ void beginVisit( const CurrentDateTime& );
+ void endVisit ( const CurrentDateTime& );
+
+ void beginVisit( const CurrentTime& );
+ void endVisit ( const CurrentTime& );
+
+ void beginVisit( const ParseDate& );
+ void endVisit ( const ParseDate& );
+
+ void beginVisit( const ParseDateTime& );
+ void endVisit ( const ParseDateTime& );
+
+ void beginVisit( const ParseTime& );
+ void endVisit ( const ParseTime& );
+
+ void beginVisit( const Timestamp& );
+ void endVisit ( const Timestamp& );
+
+ void beginVisit( const UTCOffset& );
+ void endVisit ( const UTCOffset& );
+
#ifdef ZORBA_WITH_DEBUGGER
void beginVisit( const DebugIterator& );
void endVisit ( const DebugIterator& );
=== modified file 'src/unit_tests/CMakeLists.txt'
--- src/unit_tests/CMakeLists.txt 2012-11-12 21:17:32 +0000
+++ src/unit_tests/CMakeLists.txt 2013-01-02 14:49:24 +0000
@@ -17,15 +17,13 @@
test_base64.cpp
test_base64_streambuf.cpp
test_fs_iterator.cpp
+ test_hashmaps.cpp
test_json_parser.cpp
test_string.cpp
+ test_strptime.cpp
test_uri.cpp
test_uuid.cpp
unit_tests.cpp
- test_uri.cpp
- test_json_parser.cpp
- test_fs_iterator.cpp
- test_hashmaps.cpp
)
IF (NOT ZORBA_NO_FULL_TEXT)
=== modified file 'src/unit_tests/memory_manager.cpp'
--- src/unit_tests/memory_manager.cpp 2012-09-19 21:16:15 +0000
+++ src/unit_tests/memory_manager.cpp 2013-01-02 14:49:24 +0000
@@ -30,7 +30,7 @@
}
static void print_exception( char const *expr, char const *testName,
- std::exception const &e ) {
+ std::exception const &e ) {
std::cout << "FAILED " << testName << ": exception: " << e.what() <<
std::endl;
++failures;
@@ -40,19 +40,19 @@
#define ASSERT_EXCEPTION( EXPR, EXCEPTION ) \
try { EXPR; assert_true( #EXPR, testName, false); } \
- catch (EXCEPTION const& ) { } \
- catch ( std::exception const &e ){ print_exception( #EXPR, testName, e ); } \
+ catch ( EXCEPTION const& ) { } \
+ catch ( std::exception const &e ) { print_exception( #EXPR, testName, e ); } \
catch ( ... ) { assert_true ( #EXPR, testName, false ); }
#define ASSERT_NO_EXCEPTION( EXPR ) \
- try {EXPR; } \
- catch ( std::exception const &e ){ print_exception( #EXPR, testName, e ); } \
+ try { EXPR; } \
+ catch ( std::exception const &e ) { print_exception( #EXPR, testName, e ); } \
catch ( ... ) { assert_true (#EXPR, testName, false ); }
#define ASSERT_TRUE_AND_NO_EXCEPTION( EXPR ) \
try { ASSERT_TRUE ( EXPR ); } \
catch ( std::exception const &e ) { print_exception( #EXPR, testName, e ); } \
- catch ( ... ) {assert_true( #EXPR, testName, false ); }
+ catch ( ... ) { assert_true( #EXPR, testName, false ); }
#define TEST( TESTNAME ) \
static void TESTNAME () { \
@@ -177,9 +177,11 @@
ASSERT_TRUE(hugePage == mem);
END_TEST
-namespace zorba { namespace UnitTests{
-
///////////////////////////////////////////////////////////////////////////////
+
+namespace zorba {
+namespace UnitTests {
+
int test_mem_manager( int, char*[] )
{
PageCreationAllocatesMemoryDeletionFreesIt();
@@ -201,4 +203,7 @@
return failures ? 1 : 0;
}
-}} //namespace zorba::UnitTests
+} // namespace UnitTests
+} // namespace zorba
+
+/* vim:set et sw=2 ts=2: */
=== modified file 'src/unit_tests/test_base64.cpp'
--- src/unit_tests/test_base64.cpp 2012-09-19 21:16:15 +0000
+++ src/unit_tests/test_base64.cpp 2013-01-02 14:49:24 +0000
@@ -53,11 +53,13 @@
#define ASSERT_NO_EXCEPTION( NO, EXPR ) \
try { EXPR; } \
- catch ( std::exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); }
+ catch ( exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); } \
+ catch ( ... ) { assert_true( NO, #EXPR, __LINE__, false ); }
#define ASSERT_EXCEPTION( NO, EXPR, EXCEPTION ) \
try { EXPR; assert_true( NO, #EXPR, __LINE__, false ); } \
- catch ( EXCEPTION const& ) { }
+ catch ( EXCEPTION const& ) { } \
+ catch ( ... ) { assert_true( NO, #EXPR, __LINE__, false ); }
///////////////////////////////////////////////////////////////////////////////}
=== modified file 'src/unit_tests/test_base64_streambuf.cpp'
--- src/unit_tests/test_base64_streambuf.cpp 2012-06-15 17:01:01 +0000
+++ src/unit_tests/test_base64_streambuf.cpp 2013-01-02 14:49:24 +0000
@@ -51,7 +51,8 @@
#define ASSERT_TRUE_AND_NO_EXCEPTION( NO, EXPR ) \
try { ASSERT_TRUE( NO, EXPR ); } \
- catch ( std::exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); }
+ catch ( exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); } \
+ catch ( ... ) { assert_true( NO, #EXPR, __LINE__, false ); }
///////////////////////////////////////////////////////////////////////////////
=== modified file 'src/unit_tests/test_icu_streambuf.cpp'
--- src/unit_tests/test_icu_streambuf.cpp 2012-09-19 21:16:15 +0000
+++ src/unit_tests/test_icu_streambuf.cpp 2013-01-02 14:49:24 +0000
@@ -71,7 +71,8 @@
#define ASSERT_TRUE_AND_NO_EXCEPTION( NO, EXPR ) \
try { ASSERT_TRUE( NO, EXPR ); } \
- catch ( std::exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); }
+ catch ( exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); } \
+ catch ( ... ) { assert_true( NO, #EXPR, __LINE__, false ); }
///////////////////////////////////////////////////////////////////////////////
=== modified file 'src/unit_tests/test_json_parser.cpp'
--- src/unit_tests/test_json_parser.cpp 2012-09-19 21:16:15 +0000
+++ src/unit_tests/test_json_parser.cpp 2013-01-02 14:49:24 +0000
@@ -55,7 +55,8 @@
#define ASSERT_EXCEPTION( EXPR, EXCEPTION ) \
try { EXPR; assert_true( #EXPR, __LINE__, false ); } \
- catch ( EXCEPTION const& ) { }
+ catch ( EXCEPTION const& ) { } \
+ catch ( ... ) { assert_true( #EXPR, __LINE__, false ); }
#define ASSERT_NO_EXCEPTION( EXPR ) \
try { EXPR; } \
=== modified file 'src/unit_tests/test_string.cpp'
--- src/unit_tests/test_string.cpp 2012-09-19 21:16:15 +0000
+++ src/unit_tests/test_string.cpp 2013-01-02 14:49:24 +0000
@@ -82,7 +82,8 @@
#define ASSERT_EXCEPTION( EXPR, EXCEPTION ) \
try { EXPR; assert_true( #EXPR, __LINE__, false ); } \
- catch ( EXCEPTION const& ) { }
+ catch ( EXCEPTION const& ) { } \
+ catch ( ... ) { assert_true( #EXPR, __LINE__, false ); }
#define ASSERT_NO_EXCEPTION( EXPR ) \
try { EXPR; } \
=== added file 'src/unit_tests/test_strptime.cpp'
--- src/unit_tests/test_strptime.cpp 1970-01-01 00:00:00 +0000
+++ src/unit_tests/test_strptime.cpp 2013-01-02 14:49:24 +0000
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdafx.h"
+
+#include <cstring>
+#include <functional>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+#include "util/stl_util.h"
+#include "util/strptime.h"
+#include "zorbautils/locale.h"
+
+using namespace std;
+using namespace zorba;
+using namespace zorba::time;
+
+namespace zloc = zorba::locale;
+
+///////////////////////////////////////////////////////////////////////////////
+
+static int failures;
+
+static bool assert_true( char const *expr, int line, bool result ) {
+ if ( !result ) {
+ cout << "FAILED, line " << line << ": " << expr << endl;
+ ++failures;
+ }
+ return result;
+}
+
+static void print_exception( char const *expr, int line,
+ std::exception const &e ) {
+ assert_true( expr, line, false );
+ cout << "+ exception: " << e.what() << endl;
+}
+
+#define ASSERT_TRUE( EXPR ) assert_true( #EXPR, __LINE__, !!(EXPR) )
+
+#define ASSERT_EXCEPTION( EXPR, EXCEPTION ) \
+ try { EXPR; assert_true( #EXPR, __LINE__, false ); } \
+ catch ( EXCEPTION const& ) { } \
+ catch ( ... ) { assert_true( #EXPR, __LINE__, false ); }
+
+#define ASSERT_NO_EXCEPTION( EXPR ) \
+ try { EXPR; } \
+ catch ( std::exception const &e ) { print_exception( #EXPR, __LINE__, e ); } \
+ catch ( ... ) { assert_true( #EXPR, __LINE__, false ); }
+
+#define ASSERT_TRUE_AND_NO_EXCEPTION( EXPR ) \
+ try { ASSERT_TRUE( EXPR ); } \
+ catch ( std::exception const &e ) { print_exception( #EXPR, __LINE__, e ); } \
+ catch ( ... ) { assert_true( #EXPR, __LINE__, false ); }
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void test_ampm() {
+ char const fmt[] = "%l%M %p";
+ char const *bp;
+ ztm tm;
+
+ {
+ string buf = "0123 ";
+ buf += zloc::get_time_ampm( false );
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, fmt, &tm ) );
+ ASSERT_TRUE( bp = buf.c_str() + buf.length() );
+ ASSERT_TRUE( tm.tm_hour == 1 );
+ ASSERT_TRUE( tm.tm_min == 23 );
+ }
+ {
+ string buf = "0123 ";
+ buf += zloc::get_time_ampm( true );
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, fmt, &tm ) );
+ ASSERT_TRUE( bp = buf.c_str() + buf.length() );
+ ASSERT_TRUE( tm.tm_hour == 13 ); // note 1300 hours
+ ASSERT_TRUE( tm.tm_min == 23 );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void test_literals() {
+ char const fmt[] = "JUNK %k %% JUNK %t JUNK %n %M";
+ char const buf[] = "JUNK 14 % JUNK JUNK 15";
+ size_t const len = ::strlen( buf );
+ char const *bp;
+ ztm tm;
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, fmt, &tm ) );
+ ASSERT_TRUE( bp == buf + len );
+ ASSERT_TRUE( tm.tm_hour == 14 );
+ ASSERT_TRUE( tm.tm_min == 15 );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef char const* (*locale_fn_type)(unsigned);
+typedef int ztm::*ztm_int_ptr;
+
+static void test_locale( char const *conv, locale_fn_type locale_fn, int limit,
+ ztm_int_ptr ztm_mbr ) {
+ ztm tm;
+ for ( int i = 0; i < limit; ++i ) {
+ char const *bp;
+ {
+ char const *const buf = (*locale_fn)( i );
+ size_t const len = ::strlen( buf );
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, conv, &tm ) )
+ ASSERT_TRUE( bp == buf + len );
+ ASSERT_TRUE( tm.*ztm_mbr == i );
+ }
+ {
+ string buf = (*locale_fn)( i );
+ string::size_type const len = buf.length();
+ buf += "JUNK";
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, conv, &tm ) )
+ ASSERT_TRUE( bp == buf.c_str() + len );
+ ASSERT_TRUE( tm.*ztm_mbr == i );
+ }
+ }
+ ASSERT_EXCEPTION( time::strptime( "JUNK", conv, &tm ), invalid_value );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef int (*unary_fn_type)(int);
+
+int identity( int i ) {
+ return i;
+}
+
+int minus_1( int i ) {
+ return i - 1;
+}
+
+int minus_1900( int i ) {
+ return i - 1900;
+}
+
+int mod_12( int i ) {
+ return i % 12;
+}
+
+int num_digits( int i ) {
+ int n = !i;
+ while ( i )
+ i /= 10, ++n;
+ return n;
+}
+
+static void test_range( char const *conv, int low, int high,
+ ztm_int_ptr ztm_mbr,
+ unary_fn_type unary_fn = &identity ) {
+ ztd::itoa_buf_type buf;
+ ztm tm;
+ for ( int i = low; i <= high; ++i ) {
+ ztd::itoa( i, buf );
+ size_t const len = ::strlen( buf );
+ char const *bp;
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, conv, &tm ) )
+ ASSERT_TRUE( bp == buf + len );
+ ASSERT_TRUE( tm.*ztm_mbr == (*unary_fn)(i) );
+ }
+ ASSERT_EXCEPTION( time::strptime( "JUNK", conv, &tm ), invalid_value );
+
+ ztd::itoa( --low, buf );
+ ASSERT_EXCEPTION( time::strptime( buf , conv, &tm ), invalid_value );
+
+ int const high2 = high + 1;
+ if ( num_digits( high2 ) == num_digits( high ) ) {
+ ztd::itoa( ++high, buf );
+ ASSERT_EXCEPTION( time::strptime( buf , conv, &tm ), invalid_value );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void test_bad_dates() {
+ struct bad_date {
+ char const *conv;
+ char const *date;
+ };
+ static bad_date bad_dates[] = {
+ { "%F", " 2011-02-29" }, // not a leap year
+ { "%F", " 2011-04-31" }, // Apr 31 is invalid
+ { "%F", " 2011-06-31" }, // Jun 31 is invalid
+ { "%F", " 2011-09-31" }, // Sep 31 is invalid
+ { "%F", " 2011-11-31" }, // Nov 31 is invalid
+ { "%w %F", " 1 2012-01-01" }, // date is a Sun (0)
+ { "%w %F", " 2 2012-01-01" }, // date is a Sun (0)
+ { "%w %F", " 3 2012-01-01" }, // date is a Sun (0)
+ { "%w %F", " 4 2012-01-01" }, // date is a Sun (0)
+ { "%w %F", " 5 2012-01-01" }, // date is a Sun (0)
+ { "%w %F", " 6 2012-01-01" }, // date is a Sun (0)
+ { "%w %F", " 0 2013-01-01" }, // date is a Tue (2)
+ { "%w %F", " 1 2013-01-01" }, // date is a Tue (2)
+ { "%w %F", " 3 2013-01-01" }, // date is a Tue (2)
+ { "%w %F", " 4 2013-01-01" }, // date is a Tue (2)
+ { "%w %F", " 5 2013-01-01" }, // date is a Tue (2)
+ { "%w %F", " 6 2013-01-01" }, // date is a Tue (2)
+ { "%j %F", " 1 2013-01-01" }, // day is 0
+ { "%j %F", "31 2013-02-01" }, // day is 32
+ { "%j %F", "33 2013-02-01" }, // day is 32
+ { "%j %F", "60 2012-03-01" }, // day is 61
+ { "%j %F", "62 2012-03-01" }, // day is 61
+ 0
+ };
+ ztm tm;
+ for ( bad_date const *p = bad_dates; p->date; ++p ) {
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_EXCEPTION( time::strptime( p->date, p->conv, &tm ), invalid_value );
+ }
+}
+
+static void test_D() { // %m/%d/%y
+ ztm tm;
+ char const *const buf = "1/2/12";
+ size_t const len = ::strlen( buf );
+ char const *bp;
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, "%D", &tm ) )
+ ASSERT_TRUE( bp == buf + len );
+ ASSERT_TRUE( tm.tm_mon == 0 );
+ ASSERT_TRUE( tm.tm_mday == 2 );
+ ASSERT_TRUE( tm.tm_year == 112 ); // years since 1900
+}
+
+static void test_F() { // %Y-%m-%d
+ ztm tm;
+ char const *const buf = "2012-1-2";
+ size_t const len = ::strlen( buf );
+ char const *bp;
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, "%F", &tm ) )
+ ASSERT_TRUE( bp == buf + len );
+ ASSERT_TRUE( tm.tm_mon == 0 );
+ ASSERT_TRUE( tm.tm_mday == 2 );
+ ASSERT_TRUE( tm.tm_year == 112 ); // years since 1900
+}
+
+static void test_invalid_specification() {
+ static char const bad_specs[] = "fgGiJKLNoPqQ";
+ ztm tm;
+ char spec[3];
+ spec[0] = '%';
+ spec[2] = '\0';
+ for ( char const *s = bad_specs; *s; ++s ) {
+ spec[1] = *s;
+ ASSERT_EXCEPTION(
+ time::strptime( "JUNK", spec, &tm ), invalid_specification
+ );
+ }
+}
+
+static void test_j() { // dat of year: 001-366
+ ztm tm;
+ char const *const buf = "2012-1-2";
+ size_t const len = ::strlen( buf );
+ char const *bp;
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( buf, "%F", &tm ) )
+ ASSERT_TRUE( bp == buf + len );
+ ASSERT_TRUE( tm.tm_yday == 0 );
+}
+
+static void test_zZ() {
+ struct gmt_test {
+ char const* s_off;
+ long l_off;
+ };
+ static gmt_test const gmt_tests[] = {
+ "0000", 0,
+ "0030", 30 * 60,
+ "0100", 1 * 60 * 60 + 0 * 60,
+ "2300", 23 * 60 * 60 + 0 * 60,
+ "2400", 24 * 60 * 60 + 0 * 60,
+ "+0000", 0,
+ "+0030", 30 * 60,
+ "+0100", 1 * 60 * 60 + 0 * 60,
+ "+2300", 23 * 60 * 60 + 0 * 60,
+ "+2400", 24 * 60 * 60 + 0 * 60,
+ "-0000", 0,
+ "-0030", -30 * 60,
+ "-0100", -1 * 60 * 60 + 0 * 60,
+ "-2300", -23 * 60 * 60 + 0 * 60,
+ "GMT" , 0,
+ "UTC" , 0,
+ "UT" , 0,
+ "EDT" , -4 * 60 * 60 + 0 * 60,
+ "EST" , -5 * 60 * 60 + 0 * 60,
+ "CDT" , -5 * 60 * 60 + 0 * 60,
+ "CST" , -6 * 60 * 60 + 0 * 60,
+ "MDT" , -6 * 60 * 60 + 0 * 60,
+ "MST" , -7 * 60 * 60 + 0 * 60,
+ "PDT" , -7 * 60 * 60 + 0 * 60,
+ "PST" , -8 * 60 * 60 + 0 * 60,
+ 0
+ };
+
+ ztm tm;
+ for ( gmt_test const *p = gmt_tests; p->s_off; ++p ) {
+ size_t const len = ::strlen( p->s_off );
+ char const *bp;
+ ::memset( &tm, 0, sizeof( tm ) );
+ ASSERT_NO_EXCEPTION( bp = time::strptime( p->s_off, "%z", &tm ) );
+ ASSERT_TRUE( bp == p->s_off + len );
+ ASSERT_TRUE( tm.ZTM_GMTOFF == p->l_off );
+ ASSERT_TRUE( tm.tm_isdst == (p->s_off[1] == 'D') );
+ }
+
+ static char const *const bad_gmts[] = {
+ "*0000",
+ "00A0",
+ "9960",
+ "XXX",
+ 0
+ };
+ for ( char const *const *p = bad_gmts; *p; ++p )
+ ASSERT_EXCEPTION( time::strptime( *p, "%z", &tm ), invalid_value );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace zorba {
+namespace UnitTests {
+
+int test_strptime( int, char*[] ) {
+
+ test_locale( "%A", &zloc::get_weekday_abbr, 7, &ztm::tm_wday );
+ test_locale( "%A", &zloc::get_weekday_name, 7, &ztm::tm_wday );
+ test_locale( "%a", &zloc::get_weekday_abbr, 7, &ztm::tm_wday );
+ test_locale( "%a", &zloc::get_weekday_name, 7, &ztm::tm_wday );
+ test_locale( "%b", &zloc::get_month_abbr , 12, &ztm::tm_mon );
+ test_locale( "%B", &zloc::get_month_name , 12, &ztm::tm_mon );
+
+ test_range( "%d", 1, 31, &ztm::tm_mday );
+ test_range( "%j", 1, 366, &ztm::tm_yday, &minus_1 );
+ test_range( "%k", 0, 23, &ztm::tm_hour );
+ test_range( "%H", 0, 23, &ztm::tm_hour );
+ test_range( "%l", 1, 12, &ztm::tm_hour, &mod_12 );
+ test_range( "%I", 1, 12, &ztm::tm_hour, &mod_12 );
+ test_range( "%m", 1, 12, &ztm::tm_mon , &minus_1 );
+ test_range( "%M", 0, 59, &ztm::tm_min );
+ test_range( "%u", 1, 7, &ztm::tm_wday, &minus_1 );
+ test_range( "%w", 0, 6, &ztm::tm_wday );
+ test_range( "%Y", 0, 9999, &ztm::tm_year, &minus_1900 );
+
+ test_ampm();
+ test_bad_dates();
+ test_D();
+ test_F();
+ test_invalid_specification();
+ test_literals();
+ test_zZ();
+
+ cout << failures << " test(s) failed\n";
+ return failures ? 1 : 0;
+}
+
+} // namespace UnitTests
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */
=== modified file 'src/unit_tests/unit_test_list.h'
--- src/unit_tests/unit_test_list.h 2012-09-19 21:16:15 +0000
+++ src/unit_tests/unit_test_list.h 2013-01-02 14:49:24 +0000
@@ -41,6 +41,7 @@
int test_json_parser( int, char*[] );
int test_string( int, char*[] );
+ int test_strptime( int, char*[] );
int test_unique_ptr( int, char*[] );
=== modified file 'src/unit_tests/unit_tests.cpp'
--- src/unit_tests/unit_tests.cpp 2012-11-12 21:17:32 +0000
+++ src/unit_tests/unit_tests.cpp 2013-01-02 14:49:24 +0000
@@ -50,6 +50,7 @@
libunittests["json_parser"] = test_json_parser;
libunittests["string"] = test_string;
+ libunittests["strptime"] = test_strptime;
#ifndef ZORBA_NO_FULL_TEXT
libunittests["stemmer"] = test_stemmer;
=== modified file 'src/util/CMakeLists.txt'
--- src/util/CMakeLists.txt 2012-12-12 01:04:54 +0000
+++ src/util/CMakeLists.txt 2013-01-02 14:49:24 +0000
@@ -25,6 +25,8 @@
mem_streambuf.cpp
regex.cpp
string_util.cpp
+ time_util.cpp
+ strptime.cpp
unicode_util.cpp
unicode_categories.cpp
uri_util.cpp
=== modified file 'src/util/ascii_util.h'
--- src/util/ascii_util.h 2012-11-29 15:27:35 +0000
+++ src/util/ascii_util.h 2013-01-02 14:49:24 +0000
@@ -922,7 +922,7 @@
* @param s The string.
*/
template<class StringType> inline
-void trim_end_whitespace( StringType &s, char const *chars ) {
+void trim_end_whitespace( StringType &s ) {
trim_end( s, whitespace );
}
=== modified file 'src/util/string_util.cpp'
--- src/util/string_util.cpp 2012-09-19 21:16:15 +0000
+++ src/util/string_util.cpp 2013-01-02 14:49:24 +0000
@@ -58,7 +58,8 @@
#define ENABLE_CLIPPING 0
template<typename T>
-static void check_parse_number( char const *s, char *end, T *result ) {
+static void check_parse_number( char const *s, char const *end,
+ bool check_trailing_chars, T *result ) {
if ( errno == ERANGE ) {
if ( result ) {
#if ENABLE_CLIPPING
@@ -74,48 +75,59 @@
}
if ( end == s )
throw std::invalid_argument( BUILD_STRING( '"', s, "\": no digits" ) );
- for ( ; *end; ++end ) // remaining characters, if any, ...
- if ( !ascii::is_space( *end ) ) // ... may only be whitespace
- throw std::invalid_argument(
- BUILD_STRING( '"', *end, "\": invalid character" )
- );
-}
-
-double atod( char const *s ) {
- char *end;
- errno = 0;
- double result = std::strtod( s, &end );
- check_parse_number( s, end, &result );
- return result;
-}
-
-float atof( char const *s ) {
- char *end;
- errno = 0;
- float result = std::strtof( s, &end );
- check_parse_number( s, end, &result );
- return result;
-}
-
-long long atoll( char const *s ) {
- char *end;
- errno = 0;
- long long const result = std::strtoll( s, &end, 10 );
- check_parse_number( s, end, static_cast<long long*>( nullptr ) );
- return result;
-}
-
-unsigned long long atoull( char const *s ) {
+ if ( check_trailing_chars )
+ for ( ; *end; ++end ) // remaining characters, if any, ...
+ if ( !ascii::is_space( *end ) ) // ... may only be whitespace
+ throw std::invalid_argument(
+ BUILD_STRING( '"', *end, "\": invalid character" )
+ );
+ }
+
+#define ATON_PREAMBLE() \
+ bool check_trailing_chars; \
+ char const *pc; \
+ if ( !end ) { \
+ end = &pc; \
+ check_trailing_chars = false; \
+ } else \
+ check_trailing_chars = true; \
+ errno = 0
+
+double atod( char const *s, char const **end ) {
+ ATON_PREAMBLE();
+ double result = std::strtod( s, (char**)end );
+ check_parse_number( s, *end, check_trailing_chars, &result );
+ return result;
+}
+
+float atof( char const *s, char const **end ) {
+ ATON_PREAMBLE();
+ float result = std::strtof( s, (char**)end );
+ check_parse_number( s, *end, check_trailing_chars, &result );
+ return result;
+}
+
+long long atoll( char const *s, char const **end ) {
+ ATON_PREAMBLE();
+ long long const result = std::strtoll( s, (char**)end, 10 );
+ check_parse_number(
+ s, *end, check_trailing_chars, static_cast<long long*>( nullptr )
+ );
+ return result;
+}
+
+unsigned long long atoull( char const *s, char const **end ) {
+ ATON_PREAMBLE();
//
// We have to check for '-' ourselves since strtoull(3) allows it (oddly).
//
s = ascii::trim_start_whitespace( s );
bool const minus = *s == '-';
- char *end;
- errno = 0;
- unsigned long long const result = std::strtoull( s, &end, 10 );
- check_parse_number( s, end, static_cast<unsigned long long*>( nullptr ) );
+ unsigned long long const result = std::strtoull( s, (char**)end, 10 );
+ check_parse_number(
+ s, *end, check_trailing_chars, static_cast<unsigned long long*>( nullptr )
+ );
if ( minus && result ) {
//
@@ -123,7 +135,7 @@
// Hence, this allows "-0" and treats it as "0".
//
throw std::invalid_argument(
- "\"-\": invalid character for unsigned integer"
+ "'-': invalid character for unsigned integer"
);
}
return result;
=== modified file 'src/util/string_util.h'
--- src/util/string_util.h 2012-10-19 13:17:28 +0000
+++ src/util/string_util.h 2013-01-02 14:49:24 +0000
@@ -410,48 +410,56 @@
*
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the \c double value.
* @throws invalid_argument if \a s contains characters other than digits or
* leading/trailing whitespace, or contains no digits at all.
* @throws range_error if the number overflows/underflows.
*/
-double atod( char const *s );
+double atod( char const *s, char const **end = nullptr );
/**
* Parses the given string for a \c float.
*
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the \c float value.
* @throws invalid_argument if \a s contains characters other than digits or
* leading/trailing whitespace, or contains no digits at all.
* @throws range_error if the number overflows/underflows.
*/
-float atof( char const *s );
+float atof( char const *s, char const **end = nullptr );
/**
* Parses the given string for a <code>long lomg</code>.
*
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the <code>long long</code> value.
* @throws invalid_argument if \a s contains characters other than digits or
* leading/trailing whitespace, or contains no digits at all.
* @throws range_error if the number overflows/underflows.
*/
-long long atoll( char const *s );
+long long atoll( char const *s, char const **end = nullptr );
/**
* Parses the given string for an <code>unsigned long lomg</code>.
*
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the <code>unsigned long long</code> value.
* @throws invalid_argument if \a s contains characters other than digits or
* leading/trailing whitespace, or contains no digits at all.
* @throws range_error if the number overflows/underflows.
*/
-unsigned long long atoull( char const *s );
+unsigned long long atoull( char const *s, char const **end = nullptr );
/**
* Parses the given string for a C++ signed integral type.
@@ -459,10 +467,12 @@
* @tparam IntegralType The C++ signed integral type to parse for.
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the \c IntegralType value.
- * @throws invalid_argument if \a s contains characters other than digits or
- * leading/trailing whitespace, or contains no digits at all.
- * @throws range_error if the number overflows/underflows.
+ * @throws invalid_argument if \a s contains characters other than digits, a
+ * sign, or leading/trailing whitespace, or contains no digits at all.
+ * @throws range_error if the number is either too small or too big.
*/
template<typename IntegralType> inline
//
@@ -473,8 +483,8 @@
typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value
&& ZORBA_TR1_NS::is_signed<IntegralType>::value,
IntegralType>::type
-aton( char const *s ) {
- long long const result = atoll( s );
+aton( char const *s, char const **end = nullptr ) {
+ long long const result = atoll( s, end );
if ( result < std::numeric_limits<IntegralType>::min() ||
result > std::numeric_limits<IntegralType>::max() )
throw std::range_error(
@@ -484,31 +494,101 @@
}
/**
+ * Parses the given string for a C++ signed integral type.
+ *
+ * @tparam IntegralType The C++ signed integral type to parse for.
+ * @param s The null-terminated C string to parse. Leading and trailing
+ * whitespace is ignored.
+ * @param low The lower acceptable bound.
+ * @param high the higher acceptable bound.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
+ * @return Returns the \c IntegralType value.
+ * @throws invalid_argument if \a s contains characters other than digits, a
+ * sign, or leading/trailing whitespace, or contains no digits at all.
+ * @throws range_error if the number is either too small or too big.
+ */
+template<typename IntegralType> inline
+//
+// Note that the is_integral shouldn't be needed since is_signed means "is a
+// signed integral type", but Microsoft's implementation is broken and returns
+// true for floating point types as well.
+//
+typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value
+ && ZORBA_TR1_NS::is_signed<IntegralType>::value,
+ IntegralType>::type
+aton( char const *s, IntegralType low, IntegralType high,
+ char const **end = nullptr ) {
+ long long const result = atoll( s, end );
+ if ( result < low || result > high )
+ throw std::range_error(
+ BUILD_STRING(
+ '"', result, "\": number not in range ", low, '-', high
+ )
+ );
+ return static_cast<IntegralType>( result );
+}
+
+/**
* Parses the given string for a C++ unsigned integral types.
*
* @tparam IntegralType The C++ unsigned integral type to parse for.
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the \c IntegralType value.
- * @throws invalid_argument if \a s contains characters other than digits or
- * leading/trailing whitespace, or contains no digits at all.
- * @throws range_error if the number overflows/underflows.
+ * @throws invalid_argument if \a s contains characters other than digits, a
+ * sign, or leading/trailing whitespace, or contains no digits at all.
+ * @throws range_error if the number is either too small or too big.
*/
template<typename IntegralType> inline
typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value,
IntegralType>::type
-aton( char const *s ) {
- unsigned long long const result = atoull( s );
+aton( char const *s, char const **end = nullptr ) {
+ unsigned long long const result = atoull( s, end );
if ( result > std::numeric_limits<IntegralType>::max() )
throw std::range_error( BUILD_STRING( '"', result, "\": number too big" ) );
return static_cast<IntegralType>( result );
}
/**
+ * Parses the given string for a C++ unsigned integral types.
+ *
+ * @tparam IntegralType The C++ unsigned integral type to parse for.
+ * @param s The null-terminated C string to parse. Leading and trailing
+ * whitespace is ignored.
+ * @param low The lower acceptable bound.
+ * @param high the higher acceptable bound.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
+ * @return Returns the \c IntegralType value.
+ * @throws invalid_argument if \a s contains characters other than digits or
+ * leading/trailing whitespace, or contains no digits at all.
+ * @throws range_error if the number is either too small or too big.
+ */
+template<typename IntegralType> inline
+typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value,
+ IntegralType>::type
+aton( char const *s, IntegralType low, IntegralType high,
+ char const **end = nullptr ) {
+ unsigned long long const result = atoull( s, end );
+ if ( result < low || result > high )
+ throw std::range_error(
+ BUILD_STRING(
+ '"', result, "\": number not in range ", low, '-', high
+ )
+ );
+ return static_cast<IntegralType>( result );
+}
+
+/**
* Parses the given string for a C++ \c double type.
*
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the \c double value.
* @throws invalid_argument if \a s contains characters other than those for a
* valid \c double value or leading/trailing whitespace, or contains no digits
@@ -518,8 +598,8 @@
template<typename NumericType> inline
typename std::enable_if<ZORBA_TR1_NS::is_same<NumericType,double>::value,
NumericType>::type
-aton( char const *s ) {
- return atod( s );
+aton( char const *s, char const **end = nullptr ) {
+ return atod( s, end );
}
/**
@@ -527,6 +607,8 @@
*
* @param s The null-terminated C string to parse. Leading and trailing
* whitespace is ignored.
+ * @param end If not \c null, this is set to point to the character after the
+ * last character parsed.
* @return Returns the \c float value.
* @throws invalid_argument if \a s contains characters other than those for a
* valid \c float value or leading/trailing whitespace, or contains no digits
@@ -536,8 +618,8 @@
template<typename NumericType> inline
typename std::enable_if<ZORBA_TR1_NS::is_same<NumericType,float>::value,
NumericType>::type
-aton( char const *s ) {
- return atof( s );
+aton( char const *s, char const **end = nullptr ) {
+ return atof( s, end );
}
////////// To-string conversion ////////////////////////////////////////////////
=== added file 'src/util/strptime.cpp'
--- src/util/strptime.cpp 1970-01-01 00:00:00 +0000
+++ src/util/strptime.cpp 2013-01-02 14:49:24 +0000
@@ -0,0 +1,620 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// standard
+#include <cstring>
+#include <string>
+
+// Zorba
+#include "ascii_util.h"
+#include "cxx_util.h"
+#include "string_util.h"
+#include "zorbautils/locale.h"
+
+// local
+#include "strptime.h"
+#include "time_util.h"
+
+using namespace std;
+
+namespace zorba {
+namespace time {
+
+///////////////////////////////////////////////////////////////////////////////
+
+exception::exception( string const &msg ) :
+ runtime_error( msg )
+{
+}
+
+exception::~exception() throw() {
+ // out-of-line since it's virtual
+}
+
+insufficient_buffer::insufficient_buffer() :
+ exception( "insufficient buffer" )
+{
+}
+
+invalid_specification::invalid_specification( char spec ) :
+ invalid_argument(
+ BUILD_STRING( '\'', ascii::printable_char( spec ), "': invalid %" )
+ ),
+ spec_( spec )
+{
+}
+
+invalid_specification::~invalid_specification() throw() {
+ // out-of-line since it's virtual
+}
+
+invalid_value_specs::invalid_value_specs( char spec ) :
+ specs_( 1, spec )
+{
+}
+
+invalid_value_specs::invalid_value_specs( char const *specs ) :
+ specs_( specs )
+{
+}
+
+invalid_value_value::invalid_value_value( char c ) :
+ value_( 1, c )
+{
+}
+
+invalid_value_value::invalid_value_value( char const *buf, size_t len ) :
+ value_( buf, len )
+{
+ ascii::trim_end_whitespace( value_ );
+}
+
+template<typename ValueType>
+invalid_value_value::invalid_value_value( ValueType const &value ) :
+ value_( BUILD_STRING( value ) )
+{
+}
+
+std::string invalid_value::build_msg( string const &value,
+ string const &specs ) {
+ return BUILD_STRING( '"', value, "\": invalid value for %", specs );
+}
+
+invalid_value::invalid_value( char const *buf, size_t len, char spec ) :
+ invalid_value_value( buf, len ),
+ invalid_value_specs( spec ),
+ exception( build_msg( value_, specs_ ) )
+{
+}
+
+invalid_value::invalid_value( char const *buf, size_t len, char const *specs ) :
+ invalid_value_value( buf, len ),
+ invalid_value_specs( specs ),
+ exception( build_msg( value_, specs_ ) )
+{
+}
+
+template<typename ValueType>
+invalid_value::invalid_value( ValueType const &value, char spec ) :
+ invalid_value_value( value ),
+ invalid_value_specs( spec ),
+ exception( build_msg( value_, specs_ ) )
+{
+}
+
+template<typename ValueType>
+invalid_value::invalid_value( ValueType const &value, char const *specs ) :
+ invalid_value_value( value ),
+ invalid_value_specs( specs ),
+ exception( build_msg( value_, specs_ ) )
+{
+}
+
+invalid_value::~invalid_value() throw() {
+ // out-of-line since it's virtual
+}
+
+literal_mismatch::literal_mismatch( char expected, char got ) :
+ exception(
+ BUILD_STRING(
+ '\'', ascii::printable_char( got ), "': literal character mismatched '",
+ expected, '\''
+ )
+ ),
+ expected_( expected ),
+ got_( got )
+{
+}
+
+literal_mismatch::~literal_mismatch() throw() {
+ // out-of-line since it's virtual
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+struct rfc2822_obs_zone {
+ char const *name;
+ long gmtoff;
+ bool isdst;
+};
+
+//
+// See RFC 2822: "Internet Message Format," section 4.3, "Obsolete Date and
+// Time."
+//
+static rfc2822_obs_zone const rfc2822_obs_zones[] = {
+ { "GMT", 0 },
+ { "UTC", 0 }, // non-RFC: be liberal in what you accept....
+ { "UT" , 0 }, // must go after "UTC"
+ { "EDT", -4 * 60 * 60, true },
+ { "EST", -5 * 60 * 60 },
+ { "CDT", -5 * 60 * 60, true },
+ { "CST", -6 * 60 * 60 },
+ { "MDT", -6 * 60 * 60, true },
+ { "MST", -7 * 60 * 60 },
+ { "PDT", -7 * 60 * 60, true },
+ { "PST", -8 * 60 * 60 },
+ { 0, 0, 0 }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef char const* (*locale_fn_type)(unsigned);
+
+template<typename IntType> inline
+bool bits_set( IntType flags, IntType bits ) {
+ return (flags & bits) == bits;
+}
+
+//
+// This is an adapter function to adapt locale::get_time_ampm(bool) to a
+// function that takes an unsigned parameter so that locale_find() can be used
+// for it.
+//
+static char const* get_time_ampm( unsigned pm ) {
+ return locale::get_time_ampm( pm );
+}
+
+static void locale_find( char conv, char const **bpp, locale_fn_type locale_fn,
+ int limit, int *result, bool *found = nullptr ) {
+ char const *&bp = *bpp;
+ size_t len_sum = 0;
+
+ for ( int i = 0; i < limit; ++i ) {
+ char const *const s = (*locale_fn)( i );
+ size_t const len = ::strlen( s );
+ len_sum += len;
+ if ( ::strncmp( bp, s, len ) == 0 ) {
+ *result = i;
+ if ( found )
+ *found = true;
+ bp += len;
+ return;
+ }
+ }
+ if ( !found ) {
+ //
+ // Since we don't know the extent of the value in the buffer, extract a
+ // representative chunk whose length is the average length of all the legal
+ // values.
+ //
+ throw invalid_value( bp, len_sum / limit, conv );
+ }
+ *found = false;
+}
+
+static void parse_num( char conv, char const **bpp, unsigned low,
+ unsigned high, int *result ) {
+ char const *&bp = *bpp;
+ char c = *bp;
+ if ( !ascii::is_digit( c ) )
+ throw invalid_value( c, conv );
+
+ unsigned limit = high; // "high" also determines the number of digits
+ unsigned n = 0;
+
+ do {
+ n = n * 10 + c - '0';
+ limit /= 10;
+ c = *++bp;
+ } while ( limit && ascii::is_digit( c ) );
+
+ if ( n < low || n > high )
+ throw invalid_value( n, conv );
+ *result = n;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*-
+ * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Klaus Klein.
+ * Heavily optimised by David Laight
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//
+// We do not implement alternate representations. However, we always check
+// whether a given modifier is allowed for a certain conversion.
+//
+int const ALT_E = 0x01;
+int const ALT_O = 0x02;
+#define CHECK_ALT(x) \
+ do { if ( alt_format & ~(x) ) throw invalid_specification( c ); } while (0)
+
+static char const* strptime_impl( char const *buf, char const *fmt, ztm *tm,
+ unsigned *set_fields ) {
+ char const *bp = buf;
+ char c;
+ bool found;
+ char const *recurse_fmt;
+ bool split_year = false;
+
+ while ( (c = *fmt++) ) {
+ if ( !*bp )
+ throw insufficient_buffer();
+
+ if ( ascii::is_space( c ) ) {
+ bp = ascii::trim_start_whitespace( bp );
+ continue;
+ }
+
+ int alt_format = 0;
+ int n;
+
+ if ( c != '%' ) { // literal
+literal:
+ CHECK_ALT(0);
+ if ( *bp != c )
+ throw literal_mismatch( c, *bp );
+ ++bp;
+ continue;
+ }
+
+again:
+ switch ( c = *fmt++ ) {
+ case '%':
+ goto literal;
+
+ case 'a': // abbreviated weekday name
+ case 'A': // full weekday name
+ CHECK_ALT(0);
+ locale_find(
+ c, &bp, &locale::get_weekday_name, 7, &tm->tm_wday, &found
+ );
+ if ( !found )
+ locale_find( c, &bp, &locale::get_weekday_abbr, 7, &tm->tm_wday );
+ *set_fields |= set_wday;
+ break;
+
+ case 'b': // abbreviated month name
+ case 'B': // full month name
+ case 'h': // same as %b
+ CHECK_ALT(0);
+ locale_find( c, &bp, &locale::get_month_name, 12, &tm->tm_mon, &found );
+ if ( !found )
+ locale_find( c, &bp, &locale::get_month_abbr, 12, &tm->tm_mon );
+ *set_fields |= set_mon;
+ break;
+
+ case 'c': // date and time
+ CHECK_ALT(ALT_E);
+ recurse_fmt = locale::get_date_time_format();
+ goto recurse;
+
+ case 'C': // century number
+ CHECK_ALT(ALT_E);
+ parse_num( c, &bp, 0, 99, &n );
+ n = n * 100 - TM_YEAR_BASE;
+ if ( split_year )
+ n += tm->tm_year % 100;
+ else
+ split_year = true;
+ tm->tm_year = n;
+ *set_fields |= set_year;
+ break;
+
+ case 'D':
+ CHECK_ALT(0);
+ recurse_fmt = "%m/%d/%y";
+ goto recurse;
+
+ case 'd': // day of month: 01-31
+ case 'e': // day of month: 1-31
+ CHECK_ALT(ALT_O);
+ parse_num( c, &bp, 1, 31, &tm->tm_mday );
+ *set_fields |= set_mday;
+ break;
+
+ case 'E': // "%E?" alternative conversion modifier
+ alt_format = ALT_E;
+ goto again;
+
+ case 'F':
+ CHECK_ALT(0);
+ recurse_fmt = "%Y-%m-%d";
+ goto recurse;
+
+ case 'H': // hour: 00-23
+ CHECK_ALT(ALT_O);
+case_H: parse_num( c, &bp, 0, 23, &tm->tm_hour );
+ *set_fields |= set_hour;
+ break;
+
+ case 'I': // hour: 01-12
+ CHECK_ALT(ALT_O);
+case_I: parse_num( c, &bp, 1, 12, &tm->tm_hour );
+ if ( tm->tm_hour == 12 )
+ tm->tm_hour = 0; // assume AM until %p
+ *set_fields |= set_hour;
+ break;
+
+ case 'j': // day of year: 001-366
+ CHECK_ALT(0);
+ parse_num( c, &bp, 1, 366, &n );
+ tm->tm_yday = n - 1;
+ *set_fields |= set_yday;
+ break;
+
+ case 'k': // hour: 0-23
+ CHECK_ALT(0);
+ goto case_H;
+
+ case 'l': // hour: 1-12
+ CHECK_ALT(0);
+ goto case_I;
+
+ case 'm': // month: 01-12
+ CHECK_ALT(ALT_O);
+ parse_num( c, &bp, 1, 12, &n );
+ tm->tm_mon = n - 1;
+ *set_fields |= set_mon;
+ break;
+
+ case 'M': // minute: 00-59
+ CHECK_ALT(ALT_O);
+ parse_num( c, &bp, 0, 59, &tm->tm_min );
+ *set_fields |= set_min;
+ break;
+
+ case 'n': // newline
+ case 't': // tab
+ CHECK_ALT(0);
+ bp = ascii::trim_start_whitespace( bp );
+ break;
+
+ case 'O': // "%O?" alternative conversion modifier
+ alt_format = ALT_O;
+ goto again;
+
+ case 'p': // AM/PM
+ CHECK_ALT(0);
+ locale_find( c, &bp, &get_time_ampm, 2, &n );
+ if ( tm->tm_hour > 11 )
+ throw invalid_value( tm->tm_hour, "Il" );
+ if ( n /* i.e., PM */ )
+ tm->tm_hour += 12;
+ break;
+
+ case 'r':
+ CHECK_ALT(0);
+ recurse_fmt = "%I:%M:%S %p";
+ goto recurse;
+
+ case 'R':
+ CHECK_ALT(0);
+ recurse_fmt = "%H:%M";
+ goto recurse;
+
+ case 'S': // seconds: 00-60 (60 for leap second)
+ CHECK_ALT(ALT_O);
+ parse_num( c, &bp, 0, 60, &tm->tm_sec );
+ *set_fields |= set_sec;
+ break;
+
+#if 0
+ case 's': // number of seconds since epoch
+ break;
+#endif
+
+ case 'T':
+ CHECK_ALT(0);
+ recurse_fmt = "%H:%M:%S";
+ goto recurse;
+
+ case 'u': // day of week, beginning on Monday: 1-7
+ CHECK_ALT(ALT_O);
+ parse_num( c, &bp, 1, 7, &n );
+ tm->tm_wday = n - 1;
+ *set_fields |= set_wday;
+ break;
+
+ case 'v':
+ CHECK_ALT(0);
+ recurse_fmt = "%e-%b-%Y";
+ goto recurse;
+
+ case 'V': // week of year, beginning on Monday: 01-53
+ CHECK_ALT(ALT_O);
+ //
+ // This is bogus since we can not assume any valid information present
+ // in the tm structure at this point to calculate a real value, so just
+ // check the range for now.
+ //
+ parse_num( c, &bp, 1, 53, &n );
+ break;
+
+ case 'U': // week of year, beginning on Sunday: 00-53
+ case 'W': // week of year, beginning on Monday: 00-53
+ CHECK_ALT(ALT_O);
+ //
+ // This is bogus since we can not assume any valid information present
+ // in the tm structure at this point to calculate a real value, so just
+ // check the range for now.
+ //
+ parse_num( c, &bp, 0, 53, &n );
+ break;
+
+ case 'w': // day of week, beginning on Sunday: 0-6
+ CHECK_ALT(ALT_O);
+ parse_num( c, &bp, 0, 6, &tm->tm_wday );
+ *set_fields |= set_wday;
+ break;
+
+ case 'x': // date
+ CHECK_ALT(ALT_E);
+ recurse_fmt = locale::get_date_format();
+ goto recurse;
+
+ case 'X': // time
+ CHECK_ALT(ALT_E);
+ recurse_fmt = locale::get_time_format();
+ goto recurse;
+
+ case 'y': // year within 100 years of the epoch
+ CHECK_ALT(ALT_E | ALT_O);
+ parse_num( c, &bp, 0, 99, &n );
+ if ( split_year ) // preserve century
+ n += (tm->tm_year / 100) * 100;
+ else {
+ n += (n <= 68 ? 2000 : 1900) - TM_YEAR_BASE;
+ split_year = true;
+ }
+ tm->tm_year = n;
+ *set_fields |= set_year;
+ break;
+
+ case 'Y': // year: 0-9999
+ CHECK_ALT(ALT_E);
+ parse_num( c, &bp, 0, 9999, &n );
+ tm->tm_year = n - TM_YEAR_BASE;
+ *set_fields |= set_year;
+ break;
+
+ case 'z': { // RFC 2822 timezone offset or name: [+|-]HHMM | ZZZ
+ CHECK_ALT(0);
+ char const *const bp0 = bp;
+ int sign;
+ switch ( *bp ) {
+ case '+': sign = 1; ++bp; break;
+ case '-': sign = -1; ++bp; break;
+ default : sign = 0;
+ }
+ if ( ascii::is_digit( *bp ) ) { // start of HHMM
+ int hour = (*bp - '0') * 10;
+ if ( !ascii::is_digit( *++bp ) )
+ goto bad_tz;
+ hour += *bp - '0';
+ //
+ // We don't need to check the hour because values [-99,99] are legal.
+ //
+ if ( !ascii::is_digit( *++bp ) )
+ goto bad_tz;
+ int minute = (*bp - '0') * 10;
+ if ( !ascii::is_digit( *++bp ) )
+ goto bad_tz;
+ minute += *bp++ - '0';
+ if ( minute > 59 )
+ goto bad_tz;
+ long gmtoff = hour * 60 * 60 + minute * 60;
+ if ( sign )
+ gmtoff *= sign;
+ tm->ZTM_GMTOFF = gmtoff;
+ tm->tm_isdst = 0;
+ *set_fields |= set_gmtoff;
+ break;
+ } else if ( sign ) // sign followed by non-digit
+bad_tz: throw invalid_value( bp0, 4 + !!sign, c );
+ // no break;
+ } // case 'z'
+
+ case 'Z': { // RFC 2822 timezone name only: ZZZ
+ CHECK_ALT(0);
+ for ( rfc2822_obs_zone const *z = rfc2822_obs_zones; z->name; ++z ) {
+ size_t const len = ::strlen( z->name );
+ if ( ::strncmp( bp, z->name, len ) == 0 ) {
+ tm->ZTM_GMTOFF = z->gmtoff;
+ tm->tm_isdst = z->isdst;
+ *set_fields |= set_gmtoff;
+ bp += len;
+ goto next_outer_loop;
+ }
+ }
+ throw invalid_value( bp, 3 /* assume */, c );
+ } // case 'Z'
+
+ default: // unknown/unsupported conversion
+ throw invalid_specification( c );
+ } // switch
+
+next_outer_loop:
+ continue;
+
+recurse:
+ bp = strptime_impl( bp, recurse_fmt, tm, set_fields );
+ } // while
+
+ if ( bits_set( *set_fields, set_mday | set_mon | set_year ) ) {
+ int const year = TM_YEAR_BASE + tm->tm_year;
+ if ( !is_mday_valid( tm->tm_mday, tm->tm_mon, year ) )
+ throw invalid_value( tm->tm_mday, "de" );
+ if ( (*set_fields & set_wday) &&
+ !is_wday_valid( tm->tm_wday, tm->tm_mday, tm->tm_mon, year ) )
+ throw invalid_value( tm->tm_wday, "uw" );
+ if ( (*set_fields & set_yday) &&
+ !is_yday_valid( tm->tm_yday, tm->tm_mday, tm->tm_mon, year ) )
+ throw invalid_value( tm->tm_yday, 'j' );
+ }
+
+ return bp;
+}
+
+char const* strptime( char const *buf, char const *fmt, ztm *tm,
+ unsigned *set_fields ) {
+ unsigned local_fields;
+ if ( !set_fields )
+ set_fields = &local_fields;
+ *set_fields = 0;
+ return strptime_impl( buf, fmt, tm, set_fields );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace time
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */
=== added file 'src/util/strptime.h'
--- src/util/strptime.h 1970-01-01 00:00:00 +0000
+++ src/util/strptime.h 2013-01-02 14:49:24 +0000
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZORBA_STRPTIME_H
+#define ZORBA_STRPTIME_H
+
+// standard
+#include <stdexcept>
+
+// Zorba
+#include <zorba/config.h>
+#include "cxx_util.h"
+#include "string_util.h"
+#include "time_util.h"
+
+namespace zorba {
+namespace time {
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * An %exception is the root of strptime %exception hierarchy.
+ */
+class exception : public std::runtime_error {
+public:
+ ~exception() throw();
+protected:
+ exception( std::string const &msg );
+};
+
+/**
+ * This exception is thrown when the buffer is exhausted before the format
+ * string.
+ */
+class insufficient_buffer : public exception {
+public:
+ insufficient_buffer();
+};
+
+/**
+ * This exception is thrown when an invalid conversion specification is given,
+ * i.e., an invalid character after a \c %.
+ */
+class invalid_specification : public std::invalid_argument {
+public:
+ invalid_specification( char spec );
+ ~invalid_specification() throw();
+
+ /**
+ * Gets the invalid specification.
+ *
+ * @return Returns said specification character.
+ */
+ char get_spec() const {
+ return spec_;
+ }
+
+private:
+ char spec_;
+};
+
+/**
+ * This is a helper class for invalid_value.
+ */
+class invalid_value_specs {
+protected:
+ invalid_value_specs( char spec );
+ invalid_value_specs( char const *specs );
+
+ std::string specs_;
+};
+
+/**
+ * This is a helper class for invalid_value.
+ */
+class invalid_value_value {
+protected:
+ invalid_value_value( char c );
+ invalid_value_value( char const *buf, size_t len );
+
+ template<typename ValueType>
+ invalid_value_value( ValueType const &value );
+
+ std::string value_;
+};
+
+/**
+ * This exception is thrown when an invalid value for a given specification was
+ * given.
+ */
+class invalid_value :
+ protected invalid_value_value,
+ protected invalid_value_specs,
+ public exception {
+public:
+ invalid_value( char const *buf, size_t len, char spec );
+ invalid_value( char const *buf, size_t len, char const *specs );
+
+ template<typename ValueType>
+ invalid_value( ValueType const &value, char spec );
+
+ template<typename ValueType>
+ invalid_value( ValueType const &value, char const *specs );
+
+ ~invalid_value() throw();
+
+ /**
+ * Gets the conversion specification character(s) the value is invalid for.
+ *
+ * @return Returns said character(s).
+ */
+ std::string const& get_specs() const {
+ return specs_;
+ }
+
+ /**
+ * Gets the invalid value.
+ *
+ * @return Returns said value.
+ */
+ std::string const& get_value() const {
+ return value_;
+ }
+
+private:
+ static std::string build_msg( std::string const &value,
+ std::string const &specs );
+};
+
+/**
+ * This exception is thrown when a literal character in the \a buf parameter of
+ * the strptime() function does not match is corresponding character in the
+ * \a fmt parameter.
+ */
+class literal_mismatch : public exception {
+public:
+ literal_mismatch( char expected, char got );
+ ~literal_mismatch() throw();
+
+ /**
+ * Gets the character that was expected.
+ *
+ * @return Returns said character.
+ */
+ char get_expected() const {
+ return expected_;
+ }
+
+ /**
+ * Gets the character that was actually gotten.
+ *
+ * @return Returns said character.
+ */
+ char get_got() const {
+ return got_;
+ }
+
+private:
+ char expected_;
+ char got_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+//
+// The bit-wise-or of these constants comprise the value returned by the
+// set_fields parameter of the strptime() function.
+//
+unsigned const set_gmtoff = 0x001; // minutes: 0-59
+unsigned const set_hour = 0x002; // hour: 0-23
+unsigned const set_mday = 0x004; // month day: 1-{28,29,30,31}
+unsigned const set_min = 0x008; // minutes: 0-59
+unsigned const set_mon = 0x010; // month: 0-11
+unsigned const set_sec = 0x020; // seconds: 0-60
+unsigned const set_wday = 0x040; // weekday: 0-6
+unsigned const set_yday = 0x080; // day of the year: 0-365
+unsigned const set_year = 0x100;
+
+/**
+ * Parses the string in the buffer according to the given format and fills in
+ * the given \c tm structure.
+ *
+ * @param buf The buffer to parse.
+ * @param fmt The format string containing zero or more directives. Each
+ * specification is of one of the following:
+ * - one or more white-space characters
+ * - an ordinary character (neither \c '%' nor a whitespace character)
+ * - a conversion specification
+ * All whitespace characters in \a fmt match one or more whitespace characters
+ * in \a buf.
+ * Every ordinary character in \a fmt must exactly match the same character in
+ * the same position in \a buf.
+ * A conversion specification is composed of a \c '%' character followed by a
+ * conversion character that specifies the replacement required. The following
+ * conversion specifications are supported:
+ * <table>
+ * <tr>
+ * <td>%a</td>
+ * <td>
+ * The day of the week using the locale's weekday names;
+ * either the abbreviated or full name may be specified.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%A</td>
+ * <td>Same as \c %a.</td>
+ * </tr>
+ * <tr>
+ * <td>%b</td>
+ * <td>
+ * The month using the locale's month names;
+ * either the abbreviated or full name may be specified.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%B</td>
+ * <td>Same as \c %a.</td>
+ * </tr>
+ * <tr>
+ * <td>%c</td>
+ * <td>
+ * The locale's appropriate date and time representation.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%C</td>
+ * <td>
+ * The century number [00,99]; leading zeros are permitted but not
+ * required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%d</td>
+ * <td>
+ * The day of the month [01,31]; leading zeros are permitted but not
+ * required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%D</td>
+ * <td>Same as <code>%m/%d/%y</code>.</td>
+ * </tr>
+ * <tr>
+ * <td>%e</td>
+ * <td>Same as \c %d.</td>
+ * </tr>
+ * <tr>
+ * <td>%h</td>
+ * <td>Same as \c %b.</td>
+ * </tr>
+ * <tr>
+ * <td>%H</td>
+ * <td>
+ * The hour (24-hour clock) [00,23]; leading zeros are permitted but not
+ * required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%I</td>
+ * <td>
+ * The hour (12-hour clock) [01,12]; leading zeros are permitted but not
+ * required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%j</td>
+ * <td>
+ * The day number of the year [001,366]; leading zeros are permitted but
+ * not required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%m</td>
+ * <td>
+ * The month number [01,12]; leading zeros are permitted but not
+ * required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%M</td>
+ * <td>
+ * The minute [00,59]; leading zeros are permitted but not required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%n</td>
+ * <td>Any whitespace.</td>
+ * </tr>
+ * <tr>
+ * <td>%p</td>
+ * <td>
+ * The locale's equivalent of \c AM or \c PM.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%r</td>
+ * <td>
+ * The 12-hour clock time using the AM/PM notation.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%R</td>
+ * <td>Same as <code>%H:%M</code>.</td>
+ * </tr>
+ * <tr>
+ * <td>%S</td>
+ * <td>
+ * The seconds [00,60]; leading zeros are permitted but not required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%t</td>
+ * <td>Any whitespace.</td>
+ * </tr>
+ * <tr>
+ * <td>%T</td>
+ * <td>Same as <code>%H:%M:%S</code>.</td>
+ * </tr>
+ * <tr>
+ * <td>%U</td>
+ * <td>
+ * The week number of the year (Sunday as the first day of the week)
+ * [00,53]; leading zeros are permitted but not required.
+ * </td>
+ * <tr>
+ * <td>%w</td>
+ * <td>
+ * The weekday [0,6] with 0 representing Sunday; leading zeros are
+ * permitted but not required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%W</td>
+ * <td>
+ * The week number of the year (Monday as the first day of the week)
+ * [00,53]; leading zeros are permitted but not required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%x</td>
+ * <td>
+ * The date using the locale's date format.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%X</td>
+ * <td>
+ * The time using the locale's time format.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%y</td>
+ * <td>
+ * The year within century. When a century is not otherwise specified
+ * (via \c %C), values in the range [69,99] shall refer to years 1969 to
+ * 1999 and values in the range [00,68] shall refer to years 2000 to
+ * 2068; leading zeros are permitted but not required.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%Y</td>
+ * <td>
+ * The year including the century (for example, 1988).
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>%%</td>
+ * <td>Literal \c %.</td>
+ * </tr>
+ * </table>
+ * @param tm The tm structure to fill in.
+ * @param set_fields If not null, this is set to the bit-wise-or of the tm
+ * structure fields that have been set.
+ * @return Returns a pointer to the first character in \a buf past the last
+ * character parsed.
+ * @throws insufficient_buffer if \a buf is insufficient for \a fmt.
+ * @throws invalid_specification if \a fmt contains an invalid character
+ * following \c %
+ * @throws invalid_value if \a buf contains an invalid value for a
+ * specification.
+ * @throws literal_mismatch if a literal character in \a buf does not match is
+ * corresponding character in \a fmt.
+ */
+char const* strptime( char const *buf, char const *fmt, ztm *tm,
+ unsigned *set_fields = nullptr );
+
+//
+// Template version of strptime().
+//
+template<class BufferType> inline
+typename std::enable_if<
+ ztd::has_c_str<BufferType,char const* (BufferType::*)() const>::value,
+ char const*
+>::type
+strptime( BufferType const &buf, char const *fmt, ztm *tm,
+ unsigned *set_fields = nullptr ) {
+ return time::strptime( buf.c_str(), fmt, tm, set_fields );
+}
+
+//
+// Template version of strptime().
+//
+template<class BufferType,class FormatType> inline
+typename std::enable_if<
+ ztd::has_c_str<BufferType,char const* (BufferType::*)() const>::value &&
+ ztd::has_c_str<FormatType,char const* (FormatType::*)() const>::value,
+ char const*
+>::type
+strptime( BufferType const &buf, FormatType const &fmt, ztm *tm,
+ unsigned *set_fields = nullptr ) {
+ return time::strptime( buf.c_str(), fmt.c_str(), tm, set_fields );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace time
+} // namespace zorba
+#endif /* ZORBA_STRPTIME_H */
+/* vim:set et sw=2 ts=2: */
=== added file 'src/util/time_util.cpp'
--- src/util/time_util.cpp 1970-01-01 00:00:00 +0000
+++ src/util/time_util.cpp 2013-01-02 14:49:24 +0000
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cassert>
+#ifdef WIN32
+# include <windows.h>
+# if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+# define DELTA_EPOCH_IN_USEC 11644473600000000Ui64
+# else
+# define DELTA_EPOCH_IN_USEC 11644473600000000ULL
+# endif
+#else
+# include <ctime>
+# include <sys/time.h>
+#endif /* WIN32 */
+
+// local
+#include "time_util.h"
+
+namespace zorba {
+namespace time {
+
+///////////////////////////////////////////////////////////////////////////////
+
+static unsigned const yday_mon[][13] = {
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, // non-leap
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } // leap
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool calc_mday_mon( unsigned yday, unsigned *mday, unsigned *mon,
+ unsigned year ) {
+ assert( yday < 365 + is_leap_year( year ) );
+
+ unsigned const *const ym = yday_mon[ is_leap_year( year ) ];
+ for ( unsigned m = 1; m <= 12; ++m )
+ if ( ym[ m ] > yday ) {
+ --m;
+ if ( mday )
+ *mday = yday - ym[ m ] + 1;
+ if ( mon )
+ *mon = m;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Tondering's algorithm for calculating the weekday given a date; see:
+ * http://www.tondering.dk/claus/calendar.html
+ *
+ * COPYRIGHT:
+ * These functions are Copyright (c) 2008 by Claus Tondering
+ * (claus@xxxxxxxxxxxx).
+ *
+ * LICENSE:
+ * The code is distributed under the Boost Software License, which
+ * says:
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or
+ * organization obtaining a copy of the software and accompanying
+ * documentation covered by this license (the "Software") to use,
+ * reproduce, display, distribute, execute, and transmit the
+ * Software, and to prepare derivative works of the Software, and
+ * to permit third-parties to whom the Software is furnished to do
+ * so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire
+ * statement, including the above license grant, this restriction
+ * and the following disclaimer, must be included in all copies of
+ * the Software, in whole or in part, and all derivative works of
+ * the Software, unless such copies or derivative works are solely
+ * in the form of machine-executable object code generated by a
+ * source language processor.
+ *
+ * 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, TITLE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @param mday Month day: 1-31.
+ * @param mon Month: 0-11.
+ * @param year Year.
+ * @return Returns the weekday where 0 = Sunday.
+ */
+unsigned calc_wday( unsigned mday, unsigned mon, unsigned year ) {
+ assert( mday >= 1 );
+ assert( mday <= days_in_month( mon, year ) );
+ assert( mon < 12 );
+
+ ++mon; // Tondering's algorithm assumes month value in range 1-12.
+ unsigned const a = (14 - mon) / 12;
+ unsigned const y = year - a;
+ unsigned const m = mon + 12 * a - 2;
+ return (mday + y + y/4 - y/100 + y/400 + (31 * m) / 12) % 7;
+}
+
+unsigned calc_yday( unsigned mday, unsigned mon, unsigned year ) {
+ assert( mday >= 1 );
+ assert( mday <= days_in_month( mon, year ) );
+ return yday_mon[ is_leap_year( year ) ][ mon ] + mday - 1;
+}
+
+unsigned days_in_month( unsigned mon, unsigned year ) {
+ static unsigned const days[] = {
+ 31, // 0: Jan
+ 28, // 1: Feb
+ 31, // 2: Mar
+ 30, // 3: Apr
+ 31, // 4: May
+ 30, // 5: Jun
+ 31, // 6: Jul
+ 31, // 7: Aug
+ 30, // 8: Sep
+ 31, // 9: Oct
+ 30, // 10: Nov
+ 31 // 11: Dec
+ };
+ assert( mon < 12 );
+ return days[ mon ] + (mon == 1 /* Feb */ && is_leap_year( year ));
+}
+
+void get_epoch( time_t *sec, usec_type *usec ) {
+#ifdef WIN32
+ FILETIME ft;
+ GetSystemTimeAsFileTime( &ft );
+ unsigned __int64 temp = (ft.dwHighDateTime << 32) | ft.dwLowDateTime;
+ temp /= 10; // nanosec -> usec
+ temp -= DELTA_EPOCH_IN_USEC; // 1601 -> 1970
+ *sec = (time_t)(temp / 1000000UL); // usec -> sec
+ if ( usec )
+ *usec = (usec_type)(temp % 1000000UL);
+#else
+ timeval tv;
+ ::gettimeofday( &tv, nullptr );
+ *sec = tv.tv_sec;
+ if ( usec )
+ *usec = tv.tv_usec;
+#endif /* WIN32 */
+}
+
+void get_gmtime( ztm *tm, time_t when ) {
+ if ( !when )
+ get_epoch( &when );
+#ifdef WIN32
+ ::_gmtime_s( tm, &when );
+ tm->ZTM_GMTOFF = 0;
+#else
+ ::gmtime_r( &when, tm );
+#endif /* WIN32 */
+}
+
+void get_localtime( ztm *tm, time_t when ) {
+ if ( !when )
+ get_epoch( &when );
+#ifdef WIN32
+ ::localtime_s( tm, &when );
+ tm->ZTM_GMTOFF = - _timezone; // seconds west -> east
+#else
+ ::localtime_r( &when, tm );
+#endif /* WIN32 */
+}
+
+long get_gmt_offset() {
+#ifdef WIN32
+ TIME_ZONE_INFORMATION tz;
+ GetTimeZoneInformation( &tz );
+ return tz.Bias * -60; // minutes west -> seconds east
+#else
+ time_t const now = ::time( nullptr );
+ ztm tm;
+ ::localtime_r( &now, &tm );
+ return ::timegm( &tm ) - now;
+#endif /* WIN32 */
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace time
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */
=== added file 'src/util/time_util.h'
--- src/util/time_util.h 1970-01-01 00:00:00 +0000
+++ src/util/time_util.h 2013-01-02 14:49:24 +0000
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZORBA_TIME_UTIL_H
+#define ZORBA_TIME_UTIL_H
+
+// standard
+#include <ctime> /* for struct tm */
+#ifdef ZORBA_HAVE_TZFILE_H
+# include <tzfile.h> /* for TM_YEAR_BASE */
+#endif /* ZORBA_HAVE_TZFILE_H */
+
+// Zorba
+#include <zorba/config.h>
+#include "cxx_util.h"
+
+#ifndef TM_YEAR_BASE
+# define TM_YEAR_BASE 1900
+#endif
+
+namespace zorba {
+namespace time {
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef WIN32
+typedef unsigned long usec_type;
+#else
+typedef suseconds_t usec_type;
+#endif /* WIN32 */
+
+//
+// If the OS's tm struct has a GMT-timezone offset field, simply typedef tm as
+// ztm; otherwise declare ztm as a struct derived from tm that adds a
+// GMT-timezone offset field.
+//
+#if defined(ZORBA_HAVE_STRUCT_TM_TM_GMTOFF) || \
+ defined(ZORBA_HAVE_STRUCT_TM___TM_GMTOFF)
+typedef struct tm ztm;
+#else
+struct ztm : tm {
+ long tm_gmtoff;
+};
+#endif
+
+//
+// Always use this macro to access the tm_gmtoff field of the tm struct since
+// its name varies across plattorms.
+//
+#ifdef ZORBA_HAVE_STRUCT_TM___TM_GMTOFF
+# define ZTM_GMTOFF __tm_gmtoff
+#else
+# define ZTM_GMTOFF tm_gmtoff
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Calculates the day of the month and month from the given day of the year.
+ *
+ * @param yday The year day (0-365) where 0 = January 1.
+ * @param mday A pointer to the result for the month day (1-31) or \c null if
+ * this is not desired.
+ * @param mon A pointer to the result for the month (0-11) or \c null if this
+ * is not desired.
+ * @param year The year.
+ * @return Returns \c true if \a yday and \a year are a valid combination and
+ * a result is yielded.
+ */
+bool calc_mday_mon( unsigned yday, unsigned *mday, unsigned *mon,
+ unsigned year );
+
+/**
+ * Calculates the weekday for the given date.
+ *
+ * @param mday The month day (1-31).
+ * @param mon The month (0-11).
+ * @param year The year.
+ * @return Returns the weekday (0-6) where 0 = Sunday.
+ */
+unsigned calc_wday( unsigned mday, unsigned mon, unsigned year );
+
+/**
+ * Calculates the day of the year for the given date.
+ *
+ * @param mday The month day (1-31).
+ * @param mon The month (0-11).
+ * @param year The year.
+ * @return Returns the day of the year (0-365) where 0 = January 1.
+ */
+unsigned calc_yday( unsigned mday, unsigned mon, unsigned year );
+
+/**
+ * Gets the number of days in the given month.
+ *
+ * @param mon The month (0-11).
+ * @param year The year.
+ * @return Returns said number of days (1-31).
+ */
+unsigned days_in_month( unsigned mon, unsigned year );
+
+/**
+ * Gets the number of seconds and microseconds since epoch.
+ *
+ * @param sec A pointer to the result in seconds.
+ * @param usec A pointer to the result in microseconds or \c null if this is
+ * not desired.
+ */
+void get_epoch( time_t *sec, usec_type *usec = nullptr );
+
+/**
+ * Gets the Greenwich time and populates the given ztm structure.
+ *
+ * @param tm A pointer to the ztm struct to populate.
+ * @param when If > 0, populates \a tm based on \a when number of seconds
+ * since \e epoch; if 0, populates \a when based on \e now.
+ */
+void get_gmtime( ztm *tm, time_t when = 0 );
+
+/**
+ * Gets the offset of the current timezone from Greenwich time.
+ *
+ * @return Returns the offset in seconds with positive values being east of the
+ * prime meridian.
+ */
+long get_gmt_offset();
+
+/**
+ * Gets the local time and populates the given ztm structure.
+ *
+ * @param tm A pointer to the ztm struct to populate.
+ * @param when If > 0, populates \a tm based on \a when number of seconds
+ * since \e epoch; if 0, populates \a when based on \e now.
+ */
+void get_localtime( ztm *tm, time_t when = 0 );
+
+/**
+ * Checks whether the given year is a leap year.
+ *
+ * @param year The year to check.
+ * @return Returns \c true only if \a year is a leap year.
+ */
+inline bool is_leap_year( unsigned year ) {
+ return !(year % 4) && ((year % 100) || !(year % 400));
+}
+
+/**
+ * Checks whether the given day of the month is valid.
+ *
+ * @param mday The month day (1-31).
+ * @param mon The month (0-11).
+ * @param year The year.
+ * @return Returns \a true only if the given day of the month is valid.
+ */
+inline bool is_mday_valid( unsigned mday, unsigned mon, unsigned year ) {
+ return mday >= 1 && mday <= days_in_month( mon, year );
+}
+
+/**
+ * Checks whether the given weekday is valid.
+ *
+ * @param wday The weekday (0-6) where 0 = Sunday.
+ * @param mday The month day (1-31).
+ * @param mon The month (0-11).
+ * @param year The year.
+ * @return Returns \a true only if the given weekday is valid.
+ */
+inline bool is_wday_valid( unsigned wday, unsigned mday, unsigned mon,
+ unsigned year ) {
+ return wday == calc_wday( mday, mon, year );
+}
+
+/**
+ * Checks whether the given day of the year is valid.
+ *
+ * @param yday The day of the year (0-365).
+ * @param mday The month day (1-31).
+ * @param mon The month (0-11).
+ * @param year The year.
+ * @return Returns \a true only if the given day of the year is valid.
+ */
+inline bool is_yday_valid( unsigned yday, unsigned mday, unsigned mon,
+ unsigned year ) {
+ return yday == calc_yday( mday, mon, year );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace time
+} // namespace zorba
+#endif /* ZORBA_TIME_UTIL_H */
+/* vim:set et sw=2 ts=2: */
=== modified file 'src/zorbautils/locale.cpp'
--- src/zorbautils/locale.cpp 2012-09-19 21:16:15 +0000
+++ src/zorbautils/locale.cpp 2013-01-02 14:49:24 +0000
@@ -21,17 +21,22 @@
#else
# include <clocale>
# include <cstdlib> /* for getenv(3) */
+# include <langinfo.h> /* for nl_langinfo(3) */
#endif /* WIN32 */
#include <algorithm>
#include <cstring>
+#include <stdexcept>
#include <zorba/internal/unique_ptr.h>
+// Zorba
#include "util/cxx_util.h"
#include "util/less.h"
#include "util/stl_util.h"
+#include "util/string_util.h"
+// local
#include "locale.h"
#define DEF_END(CHAR_ARRAY) \
@@ -46,6 +51,59 @@
namespace zorba {
namespace locale {
+#ifdef WIN32
+typedef LCTYPE locale_index;
+#else
+typedef nl_item locale_index;
+#endif /* WIN32 */
+
+///////////////////////////////////////////////////////////////////////////////
+
+static locale_index const month_abbr[] = {
+#ifdef WIN32
+ LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
+ LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
+ LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
+ LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
+ LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
+ LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12
+#else
+ ABMON_1, ABMON_2, ABMON_3, ABMON_4, ABMON_5, ABMON_6,
+ ABMON_7, ABMON_8, ABMON_9, ABMON_10, ABMON_11, ABMON_12
+#endif /* WIN32 */
+};
+
+static locale_index const month_name[] = {
+#ifdef WIN32
+ LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
+ LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
+ LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9,
+ LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12
+#else
+ MON_1, MON_2, MON_3, MON_4, MON_5, MON_6,
+ MON_7, MON_8, MON_9, MON_10, MON_11, MON_12
+#endif /* WIN32 */
+};
+
+static locale_index const weekday_abbr[] = {
+#ifdef WIN32
+ LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3,
+ LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6,
+ LOCALE_SABBREVDAYNAME7
+#else
+ ABDAY_1, ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7
+#endif /* WIN32 */
+};
+
+static locale_index const weekday_name[] = {
+#ifdef WIN32
+ LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, LOCALE_SDAYNAME4,
+ LOCALE_SDAYNAME5, LOCALE_SDAYNAME6, LOCALE_SDAYNAME7
+#else
+ DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7
+#endif /* WIN32 */
+};
+
///////////////////////////////////////////////////////////////////////////////
/**
@@ -849,6 +907,100 @@
return iso639_2_to_639_1[ iso639_2::find( lang ) ];
}
+char const* get_date_format() {
+#ifdef WIN32
+ static string format;
+ if ( format.empty() ) {
+ unique_ptr<char[]> const w32_format(
+ get_win32_locale_info( LOCALE_SSHORTDATE )
+ );
+ //
+ // Convert Windows' date format for that used by strptime(3); see:
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/dd317787(v=vs.85).aspx
+ //
+ for ( char const *buf = w32_format.get(); *buf; ++buf ) {
+ char const c = *buf;
+ switch ( c ) {
+
+ case 'd':
+ if ( buf[1] == c )
+ if ( buf[2] == c )
+ if ( buf[3] == c )
+ format += "%A", buf += 3; // dddd = full weekday name
+ else
+ format += "%a", buf += 2; // ddd = abbreviated weekday name
+ else
+ format += "%d", buf += 1; // dd = day of month: 01-31
+ else
+ format += "%e"; // d = day of month: 1-31
+ break;
+
+ case 'g': // period/era
+ //
+ // There's no equivalent strftime(3) conversion specification: just
+ // ignore it and hope for the best.
+ //
+ if ( buf[1] == c )
+ ++buf; // gg = same as g
+ break;
+
+ case 'M':
+ if ( buf[1] == c )
+ if ( buf[2] == c )
+ if ( buf[3] == c )
+ format += "%B", buf += 3; // MMMM = full month name
+ else
+ format += "%b", buf += 2; // MMM = abbreviated month name
+ else
+ format += "%m", buf += 1; // MM = month: 01-12
+ else
+ format += "%m"; // M = month: 1-12
+ break;
+
+ case 'y':
+ if ( buf[1] == c )
+ if ( buf[2] == c )
+ if ( buf[3] == c ) {
+ format += "%Y", buf += 3; // yyyy = 4-digit year
+ if ( buf[3] == c )
+ ++buf; // yyyyy = same as yyyy
+ } else
+ ;
+ else
+ format += "%y", buf += 1; // yy = 2-digit year
+ else
+ format += "%y"; // y = 1-digit year
+ break;
+
+ default:
+ format += c;
+ } // switch
+ } // for
+ } // if
+ return format.c_str();
+#else
+ return nl_langinfo( D_FMT );
+#endif /* WIN32 */
+}
+
+char const* get_date_time_format() {
+#ifdef WIN32
+ static string format;
+ if ( format.empty() ) {
+ //
+ // Windows have no equivalent for both date and time, so glue its date and
+ // time together and hope for the best.
+ //
+ format = get_date_format();
+ format += ' ';
+ format += get_time_format();
+ }
+ return format.c_str();
+#else
+ return nl_langinfo( D_T_FMT );
+#endif /* WIN32 */
+}
+
iso3166_1::type get_host_country() {
//
// ICU's Locale::getDefault().getLanguage() should be used here, but it
@@ -920,6 +1072,145 @@
return lang_code;
}
+char const* get_month_abbr( unsigned month_index ) {
+ if ( month_index > 11 )
+ throw invalid_argument(
+ BUILD_STRING( month_index, " not in range 0-11" )
+ );
+#ifdef WIN32
+ static unique_ptr<char[]> month[12];
+ if ( !month[ month_index ] )
+ month[ month_index ].reset(
+ get_win32_locale_info( month_abbr[ month_index ] )
+ );
+ return month[ month_index ].get();
+#else
+ return nl_langinfo( month_abbr[ month_index ] );
+#endif /* WIN32 */
+}
+
+char const* get_month_name( unsigned month_index ) {
+ if ( month_index > 11 )
+ throw invalid_argument(
+ BUILD_STRING( month_index, " not in range 0-11" )
+ );
+#ifdef WIN32
+ static unique_ptr<char[]> month[12];
+ if ( !month[ month_index ] )
+ month[ month_index ].reset(
+ get_win32_locale_info( month_name[ month_index ] )
+ );
+ return month[ month_index ].get();
+#else
+ return nl_langinfo( month_name[ month_index ] );
+#endif /* WIN32 */
+}
+
+char const* get_time_ampm( bool pm ) {
+#ifdef WIN32
+ static unique_ptr<char[]> ampm[2];
+ if ( ampm[ pm ] )
+ ampm[ pm ].reset(
+ get_win32_locale_info( pm ? LOCALE_S2359 : LOCALE_S1159 )
+ );
+ return ampm[ pm ].get();
+#else
+ return nl_langinfo( pm ? PM_STR : AM_STR );
+#endif /* WIN32 */
+}
+
+char const* get_time_format() {
+#ifdef WIN32
+ static string format;
+ if ( format.empty() ) {
+ unique_ptr<char[]> const w32_format(
+ get_win32_locale_info( LOCALE_STIMEFORMAT )
+ );
+ //
+ // Convert Windows' time format for that used by strptime(3); see:
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/dd318148(v=vs.85).aspx
+ //
+ for ( char const *buf = w32_format.get(); *buf; ++buf ) {
+ char const c = *buf;
+ switch ( c ) {
+
+ case 'h':
+ if ( buf[1] == 'h' )
+ format += "%I", ++buf;
+ else
+ format += "%l";
+ break;
+
+ case 'H':
+ if ( buf[1] == 'H' )
+ format += "%H", ++buf;
+ else
+ format += "%k";
+ break;
+
+ case 'm':
+ format += "%M";
+ if ( buf[1] == 'm' )
+ ++buf;
+ break;
+
+ case 's':
+ format += "%S";
+ if ( buf[1] == 's' )
+ ++buf;
+ break;
+
+ case 't':
+ format += "%p";
+ if ( buf[1] == 't' )
+ ++buf;
+ break;
+
+ default:
+ format += c;
+ } // switch
+ } // for
+ } // if
+ return format.c_str();
+#else
+ return nl_langinfo( T_FMT );
+#endif /* WIN32 */
+}
+
+char const* get_weekday_abbr( unsigned day_index ) {
+ if ( day_index > 6 )
+ throw invalid_argument(
+ BUILD_STRING( day_index, " not in range 0-6" )
+ );
+#ifdef WIN32
+ static unique_ptr<char[]> weekday[7];
+ if ( !weekday[ day_index ] )
+ weekday[ day_index ].reset(
+ get_win32_locale_info( weekday_abbr[ day_index ] )
+ );
+ return weekday[ day_index ].get();
+#else
+ return nl_langinfo( weekday_abbr[ day_index ] );
+#endif /* WIN32 */
+}
+
+char const* get_weekday_name( unsigned day_index ) {
+ if ( day_index > 6 )
+ throw invalid_argument(
+ BUILD_STRING( day_index, " not in range 0-6" )
+ );
+#ifdef WIN32
+ static unique_ptr<char[]> weekday[7];
+ if ( !weekday[ day_index ] )
+ weekday[ day_index ].reset(
+ get_win32_locale_info( weekday_name[ day_index ] )
+ );
+ return weekday[ day_index ].get();
+#else
+ return nl_langinfo( weekday_name[ day_index ] );
+#endif /* WIN32 */
+}
+
///////////////////////////////////////////////////////////////////////////////
} // namespace locale
=== modified file 'src/zorbautils/locale.h'
--- src/zorbautils/locale.h 2012-09-19 21:16:15 +0000
+++ src/zorbautils/locale.h 2013-01-02 14:49:24 +0000
@@ -297,7 +297,7 @@
* @return Returns said enumeration or \c unknown.
*/
type find( char const *country );
- }
+ } // namespace iso3166_1
///////////////////////////////////////////////////////////////////////////
@@ -474,7 +474,7 @@
* @return Returns said enumeration or \c unknown.
*/
type find( char const *lang );
- }
+ } // namespace iso639_2
///////////////////////////////////////////////////////////////////////////
@@ -487,6 +487,22 @@
iso639_1::type find_lang( char const *lang );
/**
+ * Gets the date format for the current locale. The format is that used by
+ * strptime(3).
+ *
+ * @return Returns said date format.
+ */
+ char const* get_date_format();
+
+ /**
+ * Gets the date and time format for the current locale. The format is
+ * that used by strptime(3).
+ *
+ * @return Returns said date format.
+ */
+ char const* get_date_time_format();
+
+ /**
* Gets the ISO 3166-1 country code enumeration for the host system.
*
* @return Returns said enumeration or \c unknown.
@@ -500,12 +516,58 @@
*/
iso639_1::type get_host_lang();
+ /**
+ * Gets a month's abbreviation in the current locale.
+ *
+ * @param month_index The index of the month to get in the range 0-11.
+ * @return Returns said abbreviation.
+ */
+ char const* get_month_abbr( unsigned month_index );
+
+ /**
+ * Gets a month's full name in the current locale.
+ *
+ * @param month_index The index of the month to get in the range 0-11.
+ * @return Returns said full name.
+ */
+ char const* get_month_name( unsigned month_index );
+
+ /**
+ * Gets the time AM or PM string in the current locale.
+ *
+ * @param pm If \c true, gets the PM string; else the AM string.
+ * @return Returns said string.
+ */
+ char const* get_time_ampm( bool pm );
+
+ /**
+ * Gets the time format for the current locale. The format is that used by
+ * strptime(3).
+ *
+ * @return Returns said time format.
+ */
+ char const* get_time_format();
+
+ /**
+ * Gets a weekday's abbreviation in the current locale.
+ *
+ * @param day_index The index of the weekday to get in the range 0-6.
+ * @return Returns said abbreviation.
+ */
+ char const* get_weekday_abbr( unsigned day_index );
+
+ /**
+ * Gets a weekday's full name in the current locale.
+ *
+ * @param day_index The index of the month to get in the range 0-6.
+ * @return Returns said full name.
+ */
+ char const* get_weekday_name( unsigned day_index );
+
///////////////////////////////////////////////////////////////////////////
} // namespace locale
} // namespace zorba
-#undef DEF_OSTREAM_INSERT_OPERATOR
-
#endif /* ZORBA_CORE_LOCALE_H */
/* vim:set et sw=2 ts=2: */
=== added directory 'test/rbkt/ExpQueryResults/zorba/datetime'
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-lj-uY-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-lj-uY-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-lj-uY-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+2012-12-28
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uD-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uD-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uD-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+2068-01-02
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uD-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uD-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uD-2.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+1969-01-02
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uF-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uF-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-date-uF-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+1912-12-28
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-dateTime-uFTZ-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-dateTime-uFTZ-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-dateTime-uFTZ-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+1912-12-28T05:00:00-08:00
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uH-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uH-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uH-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+23:00:00Z
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uIMS-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uIMS-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uIMS-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+00:34:56Z
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uR-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uR-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uR-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+23:45:00Z
=== added file 'test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uT-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uT-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/datetime/datetime-parse-time-uT-1.xml.res 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+23:45:01Z
=== added directory 'test/rbkt/Queries/zorba/datetime'
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-date-ld-1.spec'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-date-ld-1.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-date-ld-1.spec 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+Error: http://www.zorba-xquery.com/errors:ZDTP0005
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-date-ld-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-date-ld-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-date-ld-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-date( "1", "%d" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-date-lj-uY-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-date-lj-uY-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-date-lj-uY-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-date( "363 2012", "%j %Y" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-date-uD-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-date-uD-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-date-uD-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-date( "1/2/68", "%D" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-date-uD-2.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-date-uD-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-date-uD-2.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-date( "1/2/69", "%D" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-date-uF-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-date-uF-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-date-uF-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-date( "1912-12-28", "%F" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-dateTime-uFTZ-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-dateTime-uFTZ-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-dateTime-uFTZ-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-dateTime( "1912-12-28 05:00:00 PST", "%F %T %Z" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-time( "23", "%H" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-2.spec'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-2.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-2.spec 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+Error: http://www.zorba-xquery.com/errors:ZDTP0003
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-2.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uH-2.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-time( "24", "%H" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uIMS-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uIMS-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uIMS-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-time( "12:34:56", "%I:%M:%S" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uM-1.spec'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uM-1.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uM-1.spec 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+Error: http://www.zorba-xquery.com/errors:ZDTP0005
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uM-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uM-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uM-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-time( "59", "%M" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uR-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uR-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uR-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-time( "23:45", "%R" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uS-1.spec'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uS-1.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uS-1.spec 2013-01-02 14:49:24 +0000
@@ -0,0 +1,1 @@
+Error: http://www.zorba-xquery.com/errors:ZDTP0005
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uS-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uS-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uS-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-time( "59", "%S" )
=== added file 'test/rbkt/Queries/zorba/datetime/datetime-parse-time-uT-1.xq'
--- test/rbkt/Queries/zorba/datetime/datetime-parse-time-uT-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/datetime/datetime-parse-time-uT-1.xq 2013-01-02 14:49:24 +0000
@@ -0,0 +1,3 @@
+import module namespace dt = "http://www.zorba-xquery.com/modules/datetime";;
+
+dt:parse-time( "23:45:01", "%T" )
Follow ups
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: noreply, 2013-01-11
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-11
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-11
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-11
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-11
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-11
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Chris Hillery, 2013-01-11
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-10
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-10
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-10
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Matthias Brantner, 2013-01-10
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Matthias Brantner, 2013-01-10
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Rodolfo Ochoa, 2013-01-09
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-08
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-08
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-08
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-08
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-08
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-08
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-08
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-08
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-08
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Matthias Brantner, 2013-01-07
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Matthias Brantner, 2013-01-07
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-07
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-07
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-07
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-07
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-06
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-06
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-06
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Matthias Brantner, 2013-01-06
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-05
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-05
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-04
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-04
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-02
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-02
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Zorba Build Bot, 2013-01-02
-
[Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-02
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1053113 into lp:zorba
From: Paul J. Lucas, 2013-01-02