timestamp.c #3

  • //
  • guest/
  • grant_glouser/
  • jam/
  • timestamp.c
  • View
  • Commits
  • Open Download .zip Download (4 KB)
/*
 * Copyright 1993, 1995 Christopher Seiwald.
 *
 * This file is part of Jam - see jam.c for Copyright information.
 */

# include "jam.h"
# include "hash.h"
# include "filesys.h"
# include "timestamp.h"
# include "newstr.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( char *target, int found, time_t time );

static char *time_progress[] =
{
	"INIT",
	"NOENTRY",
	"SPOTTED",
	"MISSING",
	"FOUND"
} ;


/*
 * timestamp() - return timestamp on a file, if present
 */

void
timestamp( 
	char	*target,
	time_t	*time )
{
	FILENAME f1, f2;
	BINDING	binding, *b = &binding;
	char buf[ MAXJPATH ];

# ifdef DOWNSHIFT_PATHS
	char path[ MAXJPATH ];
	char *p = path;

	do *p++ = tolower( *target );
	while( *target++ );

	target = path;
# endif 

	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 */

	file_parse( target, &f1 );

	/* Scan directory if not already done so */

	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    file_parent( &f2 );
	    file_build( &f2, buf, 0 );

	    b->name = buf;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_dirscan( buf, time_enter );
		b->flags |= BIND_SCANNED;
	    }
	}

	/* Scan archive if not already done so */

	if( f1.f_member.len )
	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    f2.f_member.len = 0;
	    file_build( &f2, buf, 0 );

	    b->name = buf;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_archscan( buf, time_enter );
		b->flags |= BIND_SCANNED;
	    }
	}

    afterscanning:

	if( b->progress == BIND_SPOTTED )
	{
	    if( file_time( b->name, &b->time ) < 0 )
		b->progress = BIND_MISSING;
	    else
		b->progress = BIND_FOUND;
	}

	#if defined( macintosh )
	/* If BIND_NOENTRY look for the file anyway (it could be a volume name) */
	else if (b->progress == BIND_NOENTRY && !strchr(b->name, ':'))
	{
		if( file_time( b->name, &b->time ) < 0 )
			b->progress = BIND_MISSING;
		else
			b->progress = BIND_FOUND;
	}
	#endif /* macintosh */
	

	*time = b->progress == BIND_FOUND ? b->time : 0;
}

static void
time_enter( 
	char	*target,
	int	found,
	time_t	time )
{
	BINDING	binding, *b = &binding;

# 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] );
}

/*
 * donestamps() - free timestamp tables
 */

void
donestamps()
{
	hashdone( bindhash );
}
# Change User Description Committed
#3 553 Grant Glouser Integrate Jam 2.3 changes.
#2 352 Grant Glouser Use MacOS native APIs instead of GUSI.
And additional Mac path handling improvements.

filemac.c
    - rewrote file_dirscan and file_time to use MacOS native API
    (PBGetCatInfo).  This means GUSI is no longer needed, which should
    make Jam more stable and ever so slightly faster under MacOS.

pathmac.c
    - no trailing colons on directories.  This has the effect of allowing
    rules to recursively process paths under MacOS (which makes MacOS just
    like every other platform in this respect).

timestamp.c
    - extra timestamp check for possible volume names under MacOS
    - case-sensitivity OFF for MacOS

Jamfile and Build.mpw
    - altered to remove GUSI header search paths and libraries.  This
    complicates the Jamfile - perhaps these changes should be merged
    into the Jambase.
#1 300 Grant Glouser Branching jam sources to my guest directory.
//guest/perforce_software/jam/src/timestamp.c
#1 2 laura Add Jam/MR 2.2 source