2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * Copyright 2001-2004 David Abrahams.
9 * Distributed under the Boost Software License, Version 1.0.
10 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
18 # include "timestamp.h"
23 * timestamp.c - get the timestamp of a file or archive member
25 * 09/22/00 (seiwald) - downshift names on OS2, too
29 * BINDING - all known files
32 typedef struct _binding BINDING;
38 # define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
42 # define BIND_INIT 0 /* never seen */
43 # define BIND_NOENTRY 1 /* timestamp requested but file never found */
44 # define BIND_SPOTTED 2 /* file found but not timed yet */
45 # define BIND_MISSING 3 /* file found but can't get timestamp */
46 # define BIND_FOUND 4 /* file found and time stamped */
48 time_t time; /* update time - 0 if not exist */
51 static struct hash * bindhash = 0;
52 static void time_enter( void *, char *, int, time_t );
54 static char * time_progress[] =
65 * timestamp() - return timestamp on a file, if present.
68 void timestamp( char * target, time_t * time )
70 PROFILE_ENTER( timestamp );
75 BINDING * b = &binding;
77 #ifdef DOWNSHIFT_PATHS
82 #ifdef DOWNSHIFT_PATHS
83 string_copy( &path, target );
90 /* On NT, we must use backslashes or the file will not be found. */
98 #endif /* #ifdef DOWNSHIFT_PATHS */
102 bindhash = hashinit( sizeof( BINDING ), "bindings" );
104 /* Quick path - is it there? */
106 b->time = b->flags = 0;
107 b->progress = BIND_INIT;
109 if ( hashenter( bindhash, (HASHDATA * *)&b ) )
110 b->name = newstr( target ); /* never freed */
112 if ( b->progress != BIND_INIT )
115 b->progress = BIND_NOENTRY;
117 /* Not found - have to scan for it. */
118 path_parse( target, &f1 );
120 /* Scan directory if not already done so. */
123 BINDING * b = &binding;
128 path_build( &f2, buf, 0 );
130 b->name = buf->value;
131 b->time = b->flags = 0;
132 b->progress = BIND_INIT;
134 if ( hashenter( bindhash, (HASHDATA * *)&b ) )
135 b->name = newstr( buf->value ); /* never freed */
137 if ( !( b->flags & BIND_SCANNED ) )
139 file_dirscan( buf->value, time_enter, bindhash );
140 b->flags |= BIND_SCANNED;
144 /* Scan archive if not already done so. */
145 if ( f1.f_member.len )
148 BINDING * b = &binding;
153 string_truncate( buf, 0 );
154 path_build( &f2, buf, 0 );
156 b->name = buf->value;
157 b->time = b->flags = 0;
158 b->progress = BIND_INIT;
160 if ( hashenter( bindhash, (HASHDATA * *)&b ) )
161 b->name = newstr( buf->value ); /* never freed */
163 if ( !( b->flags & BIND_SCANNED ) )
165 file_archscan( buf->value, time_enter, bindhash );
166 b->flags |= BIND_SCANNED;
172 if ( b->progress == BIND_SPOTTED )
174 b->progress = file_time( b->name, &b->time ) < 0
179 *time = b->progress == BIND_FOUND ? b->time : 0;
181 #ifdef DOWNSHIFT_PATHS
182 string_free( &path );
185 PROFILE_EXIT( timestamp );
189 static void time_enter( void * closure, char * target, int found, time_t time )
192 BINDING * b = &binding;
193 struct hash * bindhash = (struct hash *)closure;
195 #ifdef DOWNSHIFT_PATHS
196 char path[ MAXJPATH ];
199 do *p++ = tolower( *target );
208 if ( hashenter( bindhash, (HASHDATA * *)&b ) )
209 b->name = newstr( target ); /* never freed */
212 b->progress = found ? BIND_FOUND : BIND_SPOTTED;
214 if ( DEBUG_BINDSCAN )
215 printf( "time ( %s ) : %s\n", target, time_progress[ b->progress ] );
220 * stamps_done() - free timestamp tables.
225 hashdone( bindhash );