[svn-r28416] Description:

Refactor time conversion code to put all the system-specific changes into
one routine, H5_make_time, in H5system.c.

Tested on:
    MacOSX/64 10.11.1 (amazon) w/serial & parallel
    (h5committest forthcoming)
This commit is contained in:
Quincey Koziol 2015-11-20 09:43:58 -05:00
parent 54aa68df1a
commit 5c6f1819d5
3 changed files with 77 additions and 68 deletions

View File

@ -96,9 +96,6 @@ const H5O_msg_class_t H5O_MSG_MTIME_NEW[1] = {{
/* Current version of new mtime information */
#define H5O_MTIME_VERSION 1
/* Track whether tzset routine was called */
static hbool_t ntzset = FALSE;
/* Declare a free list to manage the time_t struct */
H5FL_DEFINE(time_t);
@ -148,7 +145,7 @@ H5O_mtime_new_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_
/* The return value */
if (NULL==(mesg = H5FL_MALLOC(time_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
*mesg = (time_t)tmp_time;
/* Set return value */
@ -183,8 +180,8 @@ H5O_mtime_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5
unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p)
{
time_t *mesg, the_time;
int i;
struct tm tm;
int i; /* Local index variable */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@ -193,50 +190,22 @@ H5O_mtime_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5
HDassert(f);
HDassert(p);
/* Initialize time zone information */
if(!ntzset) {
HDtzset();
ntzset = TRUE;
} /* end if */
/* decode */
for(i = 0; i < 14; i++)
if(!HDisdigit(p[i]))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "badly formatted modification time message")
/*
* Convert YYYYMMDDhhmmss UTC to a time_t. This is a little problematic
* because mktime() operates on local times. We convert to local time
* and then figure out the adjustment based on the local time zone and
* daylight savings setting.
*/
/* Convert YYYYMMDDhhmmss UTC to a time_t. */
HDmemset(&tm, 0, sizeof tm);
tm.tm_year = (p[0]-'0')*1000 + (p[1]-'0')*100 +
(p[2]-'0')*10 + (p[3]-'0') - 1900;
tm.tm_year = (p[0]-'0')*1000 + (p[1]-'0')*100 + (p[2]-'0')*10 + (p[3]-'0') - 1900;
tm.tm_mon = (p[4]-'0')*10 + (p[5]-'0') - 1;
tm.tm_mday = (p[6]-'0')*10 + (p[7]-'0');
tm.tm_hour = (p[8]-'0')*10 + (p[9]-'0');
tm.tm_min = (p[10]-'0')*10 + (p[11]-'0');
tm.tm_sec = (p[12]-'0')*10 + (p[13]-'0');
tm.tm_isdst = -1; /*figure it out*/
if((time_t)-1 == (the_time = HDmktime(&tm)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "badly formatted modification time message")
#if defined(H5_HAVE_TM_GMTOFF)
/* BSD-like systems */
the_time += tm.tm_gmtoff;
#elif defined(H5_HAVE_TIMEZONE)
the_time -= HDgettimezone() - (tm.tm_isdst ? 3600 : 0);
#else
/*
* The catch-all. If we can't convert a character string universal
* coordinated time to a time_t value reliably then we can't decode the
* modification time message. This really isn't as bad as it sounds -- the
* only way a user can get the modification time is from our internal
* query routines, which can gracefully recover.
*/
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to obtain local timezone information")
#endif
tm.tm_isdst = -1; /* (figure it out) */
if((time_t)-1 == (the_time = H5_make_time(&tm)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't construct time info")
/* The return value */
if(NULL == (mesg = H5FL_MALLOC(time_t)))

View File

@ -935,14 +935,6 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#ifndef HDgets
#define HDgets(S) gets(S)
#endif /* HDgets */
#ifndef H5_HAVE_TM_GMTOFF
#ifdef H5_HAVE_TIMEZONE
#ifndef HDgettimezone
#define HDgettimezone() HDget_timezone()
#endif /* HDgettimezone */
H5_DLL long int HDget_timezone(void);
#endif /* H5_HAVE_TIMEZONE */
#endif /* H5_HAVE_TM_GMTOFF */
#ifndef HDgettimeofday
#define HDgettimeofday(S,P) gettimeofday(S,P)
#endif /* HDgettimeofday */
@ -2505,6 +2497,9 @@ H5_DLL uint32_t H5_checksum_lookup3(const void *data, size_t len, uint32_t initv
H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t initval);
H5_DLL uint32_t H5_hash_string(const char *str);
/* Time related routines */
H5_DLL time_t H5_make_time(struct tm *tm);
/* Functions for building paths, etc. */
H5_DLL herr_t H5_build_extpath(const char *, char ** /*out*/ );

View File

@ -73,6 +73,9 @@
/* Local Variables */
/*******************/
/* Track whether tzset routine was called */
static hbool_t H5_ntzset = FALSE;
/*-------------------------------------------------------------------------
* Function: HDfprintf
@ -584,43 +587,85 @@ void HDsrand(unsigned int seed)
}
#endif /* H5_HAVE_RAND_R */
/*-------------------------------------------------------------------------
* Function: HDget_timezone
* Function: H5_make_time
*
* Purpose: Wrapper function for global variable timezone, if it exists
* on this system, or use the function if VS2015
* Purpose: Portability routine to abstract converting a 'tm' struct into
* a time_t value.
*
* VS2015 removed the deprecated global variable timezone.
* Note: This is a little problematic because mktime() operates on
* local times. We convert to local time and then figure out the
* adjustment based on the local time zone and daylight savings
* setting.
*
* Return: Success: The value of timezone
* Return: Success: The value of timezone
* Failure: -1
*
* Failure: Cannot fail.
* Programmer: Quincey Koziol
* November 18, 2015
*
*-------------------------------------------------------------------------
*/
#ifndef H5_HAVE_TM_GMTOFF
#ifdef H5_HAVE_TIMEZONE
long int HDget_timezone(void)
time_t
H5_make_time(struct tm *tm)
{
#ifdef H5_HAVE_VISUAL_STUDIO
#if _MSC_VER >= 1900 /* VS 2015 */
time_t the_time; /* The converted time */
#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */
/* In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
* variable declared in time.h. That variable was deprecated and in
* VS 2015 is removed, with _get_timezone replacing it.
*/
long int timezone = 0;
long timezone = 0;
#endif /* defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) */
time_t ret_value; /* Return value */
#define HDget_timezone(V) _get_timezone(V);
HDget_timezone(&timezone);
FUNC_ENTER_NOAPI_NOINIT
/* Sanity check */
HDassert(tm);
/* Initialize timezone information */
if(!H5_ntzset) {
HDtzset();
H5_ntzset = TRUE;
} /* end if */
/* Perform base conversion */
if((time_t)-1 == (the_time = HDmktime(tm)))
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCONVERT, FAIL, "badly formatted modification time message")
/* Adjust for timezones */
#if defined(H5_HAVE_TM_GMTOFF)
/* BSD-like systems */
the_time += tm->tm_gmtoff;
#elif defined(H5_HAVE_TIMEZONE)
#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */
/* In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
* variable declared in time.h. That variable was deprecated and in
* VS 2015 is removed, with _get_timezone replacing it.
*/
_get_timezone(&timezone);
#endif /* defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) */
the_time -= timezone - (tm->tm_isdst ? 3600 : 0);
#else
/*
* The catch-all. If we can't convert a character string universal
* coordinated time to a time_t value reliably then we can't decode the
* modification time message. This really isn't as bad as it sounds -- the
* only way a user can get the modification time is from our internal
* query routines, which can gracefully recover.
*/
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "unable to obtain local timezone information")
#endif
#endif
return timezone;
}
#endif /* H5_HAVE_TIMEZONE */
#endif /* H5_HAVE_TM_GMTOFF */
/* Set return value */
ret_value = the_time;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5_make_time() */
/*-------------------------------------------------------------------------
* Function: Wgettimeofday