mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2024-12-28 14:32:38 +03:00
263 lines
6.0 KiB
C
263 lines
6.0 KiB
C
/*
|
|
* Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
|
*
|
|
* This file is part of Jam - see jam.c for Copyright information.
|
|
*/
|
|
|
|
/* This file is ALSO:
|
|
* Copyright 2001-2004 David Abrahams.
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* (See accompanying file LICENSE_1_0.txt or
|
|
* http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
|
|
/*
|
|
* timestamp.c - get the timestamp of a file or archive member
|
|
*
|
|
* External routines:
|
|
* timestamp_from_path() - return timestamp for a path, if present
|
|
* timestamp_done() - free timestamp tables
|
|
*
|
|
* Internal routines:
|
|
* time_enter() - internal worker callback for scanning archives &
|
|
* directories
|
|
* free_timestamps() - worker function for freeing timestamp table contents
|
|
*/
|
|
|
|
#include "jam.h"
|
|
#include "timestamp.h"
|
|
|
|
#include "filesys.h"
|
|
#include "hash.h"
|
|
#include "object.h"
|
|
#include "pathsys.h"
|
|
#include "strings.h"
|
|
|
|
|
|
/*
|
|
* BINDING - all known files
|
|
*/
|
|
|
|
typedef struct _binding
|
|
{
|
|
OBJECT * name;
|
|
short flags;
|
|
|
|
#define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
|
|
|
|
short progress;
|
|
|
|
#define BIND_INIT 0 /* never seen */
|
|
#define BIND_NOENTRY 1 /* timestamp requested but file never found */
|
|
#define BIND_SPOTTED 2 /* file found but not timed yet */
|
|
#define BIND_MISSING 3 /* file found but can not get timestamp */
|
|
#define BIND_FOUND 4 /* file found and time stamped */
|
|
|
|
/* update time - cleared if the there is nothing to bind */
|
|
timestamp time;
|
|
} BINDING;
|
|
|
|
static struct hash * bindhash = 0;
|
|
|
|
static void time_enter( void *, OBJECT *, int const found,
|
|
timestamp const * const );
|
|
|
|
static char * time_progress[] =
|
|
{
|
|
"INIT",
|
|
"NOENTRY",
|
|
"SPOTTED",
|
|
"MISSING",
|
|
"FOUND"
|
|
};
|
|
|
|
|
|
#ifdef OS_NT
|
|
/*
|
|
* timestamp_from_filetime() - Windows FILETIME --> timestamp conversion
|
|
*
|
|
* Lifted shamelessly from the CPython implementation.
|
|
*/
|
|
|
|
void timestamp_from_filetime( timestamp * const t, FILETIME const * const ft )
|
|
{
|
|
/* Seconds between 1.1.1601 and 1.1.1970 */
|
|
static __int64 const secs_between_epochs = 11644473600;
|
|
|
|
/* We can not simply cast and dereference a FILETIME, since it might not be
|
|
* aligned properly. __int64 type variables are expected to be aligned to an
|
|
* 8 byte boundary while FILETIME structures may be aligned to any 4 byte
|
|
* boundary. Using an incorrectly aligned __int64 variable may cause a
|
|
* performance penalty on some platforms or even exceptions on others
|
|
* (documented on MSDN).
|
|
*/
|
|
__int64 in;
|
|
memcpy( &in, ft, sizeof( in ) );
|
|
|
|
/* FILETIME resolution: 100ns. */
|
|
timestamp_init( t, (time_t)( ( in / 10000000 ) - secs_between_epochs ),
|
|
(int)( in % 10000000 ) * 100 );
|
|
}
|
|
#endif /* OS_NT */
|
|
|
|
|
|
void timestamp_clear( timestamp * const time )
|
|
{
|
|
time->secs = time->nsecs = 0;
|
|
}
|
|
|
|
|
|
int timestamp_cmp( timestamp const * const lhs, timestamp const * const rhs )
|
|
{
|
|
return lhs->secs == rhs->secs
|
|
? lhs->nsecs - rhs->nsecs
|
|
: lhs->secs - rhs->secs;
|
|
}
|
|
|
|
|
|
void timestamp_copy( timestamp * const target, timestamp const * const source )
|
|
{
|
|
target->secs = source->secs;
|
|
target->nsecs = source->nsecs;
|
|
}
|
|
|
|
|
|
void timestamp_current( timestamp * const t )
|
|
{
|
|
#ifdef OS_NT
|
|
/* GetSystemTimeAsFileTime()'s resolution seems to be about 15 ms on Windows
|
|
* XP and under a millisecond on Windows 7.
|
|
*/
|
|
FILETIME ft;
|
|
GetSystemTimeAsFileTime( &ft );
|
|
timestamp_from_filetime( t, &ft );
|
|
#else /* OS_NT */
|
|
timestamp_init( t, time( 0 ), 0 );
|
|
#endif /* OS_NT */
|
|
}
|
|
|
|
|
|
int timestamp_empty( timestamp const * const time )
|
|
{
|
|
return !time->secs && !time->nsecs;
|
|
}
|
|
|
|
|
|
/*
|
|
* timestamp_from_path() - return timestamp for a path, if present
|
|
*/
|
|
|
|
void timestamp_from_path( timestamp * const time, OBJECT * const path )
|
|
{
|
|
PROFILE_ENTER( timestamp );
|
|
|
|
PATHNAME f1;
|
|
PATHNAME f2;
|
|
int found;
|
|
BINDING * b;
|
|
string buf[ 1 ];
|
|
|
|
|
|
if ( file_time( path, time ) < 0 )
|
|
timestamp_clear( time );
|
|
|
|
PROFILE_EXIT( timestamp );
|
|
}
|
|
|
|
|
|
void timestamp_init( timestamp * const time, time_t const secs, int const nsecs
|
|
)
|
|
{
|
|
time->secs = secs;
|
|
time->nsecs = nsecs;
|
|
}
|
|
|
|
|
|
void timestamp_max( timestamp * const max, timestamp const * const lhs,
|
|
timestamp const * const rhs )
|
|
{
|
|
if ( timestamp_cmp( lhs, rhs ) > 0 )
|
|
timestamp_copy( max, lhs );
|
|
else
|
|
timestamp_copy( max, rhs );
|
|
}
|
|
|
|
|
|
static char const * timestamp_formatstr( timestamp const * const time,
|
|
char const * const format )
|
|
{
|
|
static char result1[ 500 ];
|
|
static char result2[ 500 ];
|
|
strftime( result1, sizeof( result1 ) / sizeof( *result1 ), format, gmtime(
|
|
&time->secs ) );
|
|
sprintf( result2, result1, time->nsecs );
|
|
return result2;
|
|
}
|
|
|
|
|
|
char const * timestamp_str( timestamp const * const time )
|
|
{
|
|
return timestamp_formatstr( time, "%Y-%m-%d %H:%M:%S.%%09d +0000" );
|
|
}
|
|
|
|
|
|
char const * timestamp_timestr( timestamp const * const time )
|
|
{
|
|
return timestamp_formatstr( time, "%H:%M:%S.%%09d" );
|
|
}
|
|
|
|
|
|
/*
|
|
* time_enter() - internal worker callback for scanning archives & directories
|
|
*/
|
|
|
|
static void time_enter( void * closure, OBJECT * target, int const found,
|
|
timestamp const * const time )
|
|
{
|
|
int item_found;
|
|
BINDING * b;
|
|
struct hash * const bindhash = (struct hash *)closure;
|
|
|
|
target = path_as_key( target );
|
|
|
|
b = (BINDING *)hash_insert( bindhash, target, &item_found );
|
|
if ( !item_found )
|
|
{
|
|
b->name = object_copy( target );
|
|
b->flags = 0;
|
|
}
|
|
|
|
timestamp_copy( &b->time, time );
|
|
b->progress = found ? BIND_FOUND : BIND_SPOTTED;
|
|
|
|
if ( DEBUG_BINDSCAN )
|
|
printf( "time ( %s ) : %s\n", object_str( target ), time_progress[
|
|
b->progress ] );
|
|
|
|
object_free( target );
|
|
}
|
|
|
|
|
|
/*
|
|
* free_timestamps() - worker function for freeing timestamp table contents
|
|
*/
|
|
|
|
static void free_timestamps( void * xbinding, void * data )
|
|
{
|
|
object_free( ( (BINDING *)xbinding )->name );
|
|
}
|
|
|
|
|
|
/*
|
|
* timestamp_done() - free timestamp tables
|
|
*/
|
|
|
|
void timestamp_done()
|
|
{
|
|
if ( bindhash )
|
|
{
|
|
hashenumerate( bindhash, free_timestamps, 0 );
|
|
hashdone( bindhash );
|
|
}
|
|
}
|