mirror of
https://github.com/boostorg/build.git
synced 2026-02-16 01:12:13 +00:00
227 lines
4.9 KiB
C
227 lines
4.9 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)
|
|
*/
|
|
|
|
# include "jam.h"
|
|
|
|
# include "hash.h"
|
|
# include "filesys.h"
|
|
# include "pathsys.h"
|
|
# include "timestamp.h"
|
|
# include "newstr.h"
|
|
# include "strings.h"
|
|
|
|
/*
|
|
* timestamp.c - get the timestamp of a file or archive member
|
|
*
|
|
* 09/22/00 (seiwald) - downshift names on OS2, too
|
|
*/
|
|
|
|
/*
|
|
* BINDING - all known files
|
|
*/
|
|
|
|
typedef struct _binding BINDING;
|
|
|
|
struct _binding {
|
|
char *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't get timestamp */
|
|
# define BIND_FOUND 4 /* file found and time stamped */
|
|
|
|
time_t time; /* update time - 0 if not exist */
|
|
};
|
|
|
|
static struct hash * bindhash = 0;
|
|
static void time_enter( void *, char *, int, time_t );
|
|
|
|
static char * time_progress[] =
|
|
{
|
|
"INIT",
|
|
"NOENTRY",
|
|
"SPOTTED",
|
|
"MISSING",
|
|
"FOUND"
|
|
};
|
|
|
|
|
|
/*
|
|
* timestamp() - return timestamp on a file, if present.
|
|
*/
|
|
|
|
void timestamp( char * target, time_t * time )
|
|
{
|
|
PROFILE_ENTER( timestamp );
|
|
|
|
PATHNAME f1;
|
|
PATHNAME f2;
|
|
BINDING binding;
|
|
BINDING * b = &binding;
|
|
string buf[ 1 ];
|
|
#ifdef DOWNSHIFT_PATHS
|
|
string path;
|
|
char * p;
|
|
#endif
|
|
|
|
#ifdef DOWNSHIFT_PATHS
|
|
string_copy( &path, target );
|
|
p = path.value;
|
|
|
|
do
|
|
{
|
|
*p = tolower( *p );
|
|
#ifdef NT
|
|
/* On NT, we must use backslashes or the file will not be found. */
|
|
if ( *p == '/' )
|
|
*p = PATH_DELIM;
|
|
#endif
|
|
}
|
|
while ( *p++ );
|
|
|
|
target = path.value;
|
|
#endif /* #ifdef DOWNSHIFT_PATHS */
|
|
string_new( buf );
|
|
|
|
if ( !bindhash )
|
|
bindhash = hashinit( sizeof( BINDING ), "bindings" );
|
|
|
|
/* Quick path - is it there? */
|
|
b->name = target;
|
|
b->time = b->flags = 0;
|
|
b->progress = BIND_INIT;
|
|
|
|
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
|
|
b->name = newstr( target ); /* never freed */
|
|
|
|
if ( b->progress != BIND_INIT )
|
|
goto afterscanning;
|
|
|
|
b->progress = BIND_NOENTRY;
|
|
|
|
/* Not found - have to scan for it. */
|
|
path_parse( target, &f1 );
|
|
|
|
/* Scan directory if not already done so. */
|
|
{
|
|
BINDING binding;
|
|
BINDING * b = &binding;
|
|
|
|
f2 = f1;
|
|
f2.f_grist.len = 0;
|
|
path_parent( &f2 );
|
|
path_build( &f2, buf, 0 );
|
|
|
|
b->name = buf->value;
|
|
b->time = b->flags = 0;
|
|
b->progress = BIND_INIT;
|
|
|
|
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
|
|
b->name = newstr( buf->value ); /* never freed */
|
|
|
|
if ( !( b->flags & BIND_SCANNED ) )
|
|
{
|
|
file_dirscan( buf->value, time_enter, bindhash );
|
|
b->flags |= BIND_SCANNED;
|
|
}
|
|
}
|
|
|
|
/* Scan archive if not already done so. */
|
|
if ( f1.f_member.len )
|
|
{
|
|
BINDING binding;
|
|
BINDING * b = &binding;
|
|
|
|
f2 = f1;
|
|
f2.f_grist.len = 0;
|
|
f2.f_member.len = 0;
|
|
string_truncate( buf, 0 );
|
|
path_build( &f2, buf, 0 );
|
|
|
|
b->name = buf->value;
|
|
b->time = b->flags = 0;
|
|
b->progress = BIND_INIT;
|
|
|
|
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
|
|
b->name = newstr( buf->value ); /* never freed */
|
|
|
|
if ( !( b->flags & BIND_SCANNED ) )
|
|
{
|
|
file_archscan( buf->value, time_enter, bindhash );
|
|
b->flags |= BIND_SCANNED;
|
|
}
|
|
}
|
|
|
|
afterscanning:
|
|
|
|
if ( b->progress == BIND_SPOTTED )
|
|
{
|
|
b->progress = file_time( b->name, &b->time ) < 0
|
|
? BIND_MISSING
|
|
: BIND_FOUND;
|
|
}
|
|
|
|
*time = b->progress == BIND_FOUND ? b->time : 0;
|
|
string_free( buf );
|
|
#ifdef DOWNSHIFT_PATHS
|
|
string_free( &path );
|
|
#endif
|
|
|
|
PROFILE_EXIT( timestamp );
|
|
}
|
|
|
|
|
|
static void time_enter( void * closure, char * target, int found, time_t time )
|
|
{
|
|
BINDING binding;
|
|
BINDING * b = &binding;
|
|
struct hash * bindhash = (struct hash *)closure;
|
|
|
|
#ifdef DOWNSHIFT_PATHS
|
|
char path[ MAXJPATH ];
|
|
char * p = path;
|
|
|
|
do *p++ = tolower( *target );
|
|
while ( *target++ );
|
|
|
|
target = path;
|
|
#endif
|
|
|
|
b->name = target;
|
|
b->flags = 0;
|
|
|
|
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
|
|
b->name = newstr( target ); /* never freed */
|
|
|
|
b->time = time;
|
|
b->progress = found ? BIND_FOUND : BIND_SPOTTED;
|
|
|
|
if ( DEBUG_BINDSCAN )
|
|
printf( "time ( %s ) : %s\n", target, time_progress[ b->progress ] );
|
|
}
|
|
|
|
|
|
/*
|
|
* stamps_done() - free timestamp tables.
|
|
*/
|
|
|
|
void stamps_done()
|
|
{
|
|
hashdone( bindhash );
|
|
}
|