Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83888 - in trunk/tools/build/v2/engine: . modules
From: steven_at_[hidden]
Date: 2013-04-13 19:09:58


Author: steven_watanabe
Date: 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
New Revision: 83888
URL: http://svn.boost.org/trac/boost/changeset/83888

Log:
Don't create a separate timestamp table. The file table already contains everything we need.
Text files modified:
   trunk/tools/build/v2/engine/builtins.c | 8 +-
   trunk/tools/build/v2/engine/filent.c | 98 +++++++++++++++++++++++++++++++++++---
   trunk/tools/build/v2/engine/filesys.c | 76 +++++++++++++----------------
   trunk/tools/build/v2/engine/filesys.h | 9 +-
   trunk/tools/build/v2/engine/fileunix.c | 12 +++-
   trunk/tools/build/v2/engine/modules/path.c | 5 -
   trunk/tools/build/v2/engine/search.c | 2
   trunk/tools/build/v2/engine/timestamp.c | 101 ---------------------------------------
   8 files changed, 145 insertions(+), 166 deletions(-)

Modified: trunk/tools/build/v2/engine/builtins.c
==============================================================================
--- trunk/tools/build/v2/engine/builtins.c (original)
+++ trunk/tools/build/v2/engine/builtins.c 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -744,11 +744,9 @@
 
 static LIST * append_if_exists( LIST * list, OBJECT * file )
 {
- timestamp time;
- timestamp_from_path( &time, file );
- return timestamp_empty( &time )
- ? list
- : list_push_back( list, object_copy( file ) );
+ return file_query( file )
+ ? list_push_back( list, object_copy( file ) )
+ : list ;
 }
 
 

Modified: trunk/tools/build/v2/engine/filent.c
==============================================================================
--- trunk/tools/build/v2/engine/filent.c (original)
+++ trunk/tools/build/v2/engine/filent.c 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -116,9 +116,11 @@
             path_register_key( pathname_obj );
             files = list_push_back( files, pathname_obj );
             {
- file_info_t * const ff = file_info( pathname_obj );
+ int found;
+ file_info_t * const ff = file_info( pathname_obj, &found );
                 ff->is_dir = finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
                 ff->is_file = !ff->is_dir;
+ ff->exists = 1;
                 timestamp_from_filetime( &ff->time, &finfo.ftLastWriteTime );
             }
         }
@@ -192,19 +194,97 @@
  * implemented (collects information about all files in a folder).
  */
 
-int file_query_( file_info_t * const info )
+int try_file_query_root( file_info_t * const info )
 {
     WIN32_FILE_ATTRIBUTE_DATA fileData;
+ char buf[ 4 ];
     char const * const pathstr = object_str( info->name );
- char const * const pathspec = *pathstr ? pathstr : ".";
+ if ( !pathstr[ 0 ] )
+ {
+ buf[ 0 ] = '.';
+ buf[ 1 ] = 0;
+ }
+ else if ( pathstr[ 0 ] == '\\' && ! pathstr[ 1 ] )
+ {
+ buf[ 0 ] = '\\';
+ buf[ 1 ] = '\0';
+ }
+ else if ( pathstr[ 1 ] == ':' )
+ {
+ if ( !pathstr[ 2 ] )
+ {
+ }
+ else if ( !pathstr[ 2 ] || ( pathstr[ 2 ] == '\\' && !pathstr[ 3 ] ) )
+ {
+ buf[ 0 ] = pathstr[ 0 ];
+ buf[ 1 ] = ':';
+ buf[ 2 ] = '\\';
+ buf[ 3 ] = '\0';
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+
+ /* We have a root path */
+ if ( !GetFileAttributesExA( buf, GetFileExInfoStandard, &fileData ) )
+ {
+ info->is_dir = 0;
+ info->is_file = 0;
+ info->exists = 0;
+ timestamp_clear( &info->time );
+ }
+ else
+ {
+ info->is_dir = fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ info->is_file = !info->is_dir;
+ info->exists = 1;
+ timestamp_from_filetime( &info->time, &fileData.ftLastWriteTime );
+ }
+ return 1;
+}
+
+void file_query_( file_info_t * const info )
+{
+ char const * const pathstr = object_str( info->name );
+ const char * dir;
+ OBJECT * parent;
+ file_info_t * parent_info;
 
- if ( !GetFileAttributesExA( pathspec, GetFileExInfoStandard, &fileData ) )
- return -1;
+ if ( try_file_query_root( info ) )
+ return;
 
- info->is_dir = fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- info->is_file = !info->is_dir;
- timestamp_from_filetime( &info->time, &fileData.ftLastWriteTime );
- return 0;
+ if ( ( dir = strrchr( pathstr, '\\' ) ) )
+ {
+ parent = object_new_range( pathstr, dir - pathstr );
+ }
+ else
+ {
+ parent = object_copy( constant_empty );
+ }
+ parent_info = file_query( parent );
+ object_free( parent );
+ if ( !parent_info || !parent_info->is_dir )
+ {
+ info->is_dir = 0;
+ info->is_file = 0;
+ info->exists = 0;
+ timestamp_clear( &info->time );
+ }
+ else
+ {
+ info->is_dir = 0;
+ info->is_file = 0;
+ info->exists = 0;
+ timestamp_clear( &info->time );
+ if ( list_empty( parent_info->files ) )
+ file_collect_dir_content_( parent_info );
+ }
 }
 
 

Modified: trunk/tools/build/v2/engine/filesys.c
==============================================================================
--- trunk/tools/build/v2/engine/filesys.c (original)
+++ trunk/tools/build/v2/engine/filesys.c 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -45,7 +45,7 @@
  */
 void file_dirscan_( file_info_t * const dir, scanback func, void * closure );
 int file_collect_dir_content_( file_info_t * const dir );
-int file_query_( file_info_t * const );
+void file_query_( file_info_t * const );
 
 static void file_dirscan_impl( OBJECT * dir, scanback func, void * closure );
 static void free_file_info( void * xfile, void * data );
@@ -123,22 +123,18 @@
  * referenced.
  */
 
-file_info_t * file_info( OBJECT * const path )
+file_info_t * file_info( OBJECT * const path, int * found )
 {
     OBJECT * const path_key = path_as_key( path );
     file_info_t * finfo;
- int found;
 
     if ( !filecache_hash )
         filecache_hash = hashinit( sizeof( file_info_t ), "file_info" );
 
- finfo = (file_info_t *)hash_insert( filecache_hash, path_key, &found );
- if ( !found )
+ finfo = (file_info_t *)hash_insert( filecache_hash, path_key, found );
+ if ( !*found )
     {
         finfo->name = path_key;
- finfo->is_file = 0;
- finfo->is_dir = 0;
- timestamp_clear( &finfo->time );
         finfo->files = L0;
     }
     else
@@ -187,24 +183,24 @@
      * Possibly allow Jamfiles to specify some files as 'volatile' which would
      * make Boost Jam avoid caching information about those files and instead
      * ask the OS about them every time.
- *
- * FIXME: Consider returning a clear file_info() result here if
- * file_query_() fails. Should simplify the caller side error checking and
- * the caller still can and needs to detect whether the file has not been
- * successfully detected by the OS, i.e. whether the file_query() call
- * failed.
      */
- file_info_t * const ff = file_info( path );
- if ( timestamp_empty( &ff->time ) )
+ int found;
+ file_info_t * const ff = file_info( path, &found );
+ if ( !found )
     {
- if ( file_query_( ff ) < 0 )
- return 0;
-
- /* Set the path's timestamp to 1 in case it is 0 or undetected to avoid
- * confusion with non-existing paths.
- */
- if ( timestamp_empty( &ff->time ) )
- timestamp_init( &ff->time, 1, 0 );
+ file_query_( ff );
+ if ( ff->exists )
+ {
+ /* Set the path's timestamp to 1 in case it is 0 or undetected to avoid
+ * confusion with non-existing paths.
+ */
+ if ( timestamp_empty( &ff->time ) )
+ timestamp_init( &ff->time, 1, 0 );
+ }
+ }
+ if ( !ff->exists )
+ {
+ return 0;
     }
     return ff;
 }
@@ -228,21 +224,26 @@
  * with internal time representation.
  */
 
-int file_query_posix_( file_info_t * const info )
+void file_query_posix_( file_info_t * const info )
 {
     struct stat statbuf;
     char const * const pathstr = object_str( info->name );
     char const * const pathspec = *pathstr ? pathstr : ".";
 
- assert( timestamp_empty( &info->time ) );
-
     if ( stat( pathspec, &statbuf ) < 0 )
- return -1;
-
- info->is_file = statbuf.st_mode & S_IFREG ? 1 : 0;
- info->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0;
- timestamp_init( &info->time, statbuf.st_mtime, 0 );
- return 0;
+ {
+ info->is_file = 0;
+ info->is_dir = 0;
+ info->exists = 0;
+ timestamp_clear( &info->time );
+ }
+ else
+ {
+ info->is_file = statbuf.st_mode & S_IFREG ? 1 : 0;
+ info->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0;
+ info->exists = 1;
+ timestamp_init( &info->time, statbuf.st_mtime, 0 );
+ }
 }
 
 
@@ -288,13 +289,6 @@
         {
             OBJECT * const path = list_item( iter );
             file_info_t const * const ffq = file_query( path );
- /* The only way a file_query() call can fail is if its internal OS
- * file information gathering API (e.g. stat()) failed. If that
- * happens we should treat the file as if it no longer exists. We
- * then request the raw cached file_info_t structure for that file
- * and use the file name from there.
- */
- file_info_t const * const ff = ffq ? ffq : file_info( path );
             /* Using a file name read from a file_info_t structure allows OS
              * specific implementations to store some kind of a normalized file
              * name there. Using such a normalized file name then allows us to
@@ -307,7 +301,7 @@
              * short path variant thus allowing for many different path
              * strings identifying the same file.
              */
- (*func)( closure, ff->name, 1 /* stat()'ed */, &ff->time );
+ (*func)( closure, ffq->name, 1 /* stat()'ed */, &ffq->time );
         }
     }
 }

Modified: trunk/tools/build/v2/engine/filesys.h
==============================================================================
--- trunk/tools/build/v2/engine/filesys.h (original)
+++ trunk/tools/build/v2/engine/filesys.h 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -27,8 +27,9 @@
 typedef struct file_info_t
 {
     OBJECT * name;
- short is_file;
- short is_dir;
+ char is_file;
+ char is_dir;
+ char exists;
     timestamp time;
     LIST * files;
 } file_info_t;
@@ -40,7 +41,7 @@
 void file_archscan( char const * arch, scanback func, void * closure );
 void file_build1( PATHNAME * const f, string * file ) ;
 void file_dirscan( OBJECT * dir, scanback func, void * closure );
-file_info_t * file_info( OBJECT * const path );
+file_info_t * file_info( OBJECT * const path, int * found );
 int file_is_file( OBJECT * const path );
 int file_mkdir( char const * const path );
 file_info_t * file_query( OBJECT * const path );
@@ -49,7 +50,7 @@
 int file_time( OBJECT * const path, timestamp * const );
 
 /* Internal utility worker functions. */
-int file_query_posix_( file_info_t * const );
+void file_query_posix_( file_info_t * const );
 
 void file_done();
 

Modified: trunk/tools/build/v2/engine/fileunix.c
==============================================================================
--- trunk/tools/build/v2/engine/fileunix.c (original)
+++ trunk/tools/build/v2/engine/fileunix.c 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -128,6 +128,7 @@
     string_new( path );
     while ( ( dirent = readdir( dd ) ) )
     {
+ OBJECT * name;
         f.f_base.ptr = dirent->d_name
         #ifdef old_sinix
             - 2 /* Broken structure definition on sinix. */
@@ -137,7 +138,12 @@
 
         string_truncate( path, 0 );
         path_build( &f, path );
- files = list_push_back( files, object_new( path->value ) );
+ name = object_new( path->value );
+ /* Immediately stat the file to preserve invariants. */
+ if ( file_query( name ) )
+ files = list_push_back( files, name );
+ else
+ object_free( name );
     }
     string_free( path );
 
@@ -180,9 +186,9 @@
  * file_query_() - query information about a path from the OS
  */
 
-int file_query_( file_info_t * const info )
+void file_query_( file_info_t * const info )
 {
- return file_query_posix_( info );
+ file_query_posix_( info );
 }
 
 

Modified: trunk/tools/build/v2/engine/modules/path.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/path.c (original)
+++ trunk/tools/build/v2/engine/modules/path.c 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -13,9 +13,8 @@
 
 LIST * path_exists( FRAME * frame, int flags )
 {
- timestamp time;
- timestamp_from_path( &time, list_front( lol_get( frame->args, 0 ) ) );
- return timestamp_empty( &time ) ? L0 : list_new( object_copy( constant_true ) );
+ return file_query( list_front( lol_get( frame->args, 0 ) ) ) ?
+ list_new( object_copy( constant_true ) ) : L0;
 }
 
 

Modified: trunk/tools/build/v2/engine/search.c
==============================================================================
--- trunk/tools/build/v2/engine/search.c (original)
+++ trunk/tools/build/v2/engine/search.c 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -210,7 +210,7 @@
                 object_free( key );
                 break;
             }
- else if ( ff && !timestamp_empty( &ff->time ) )
+ else if ( ff )
             {
                 if ( !file || ff->is_file )
                 {

Modified: trunk/tools/build/v2/engine/timestamp.c
==============================================================================
--- trunk/tools/build/v2/engine/timestamp.c (original)
+++ trunk/tools/build/v2/engine/timestamp.c 2013-04-13 19:09:57 EDT (Sat, 13 Apr 2013)
@@ -157,109 +157,10 @@
     BINDING * b;
     string buf[ 1 ];
 
- OBJECT * const normalized_path = path_as_key( path );
 
- string_new( buf );
-
- if ( !bindhash )
- bindhash = hashinit( sizeof( BINDING ), "bindings" );
-
- /* Quick path - is it there? */
-
- b = (BINDING *)hash_insert( bindhash, normalized_path, &found );
- if ( !found )
- {
- b->name = object_copy( normalized_path );
- b->flags = 0;
- b->progress = BIND_INIT;
- timestamp_clear( &b->time );
- }
-
- if ( b->progress == BIND_INIT )
- {
- b->progress = BIND_NOENTRY;
-
- /* Not found - have to scan for it. */
- path_parse( object_str( normalized_path ), &f1 );
-
- /* Scan directory if not already done so. */
- {
- int found;
- BINDING * b;
- OBJECT * name;
-
- f2 = f1;
- f2.f_grist.len = 0;
- path_parent( &f2 );
- path_build( &f2, buf );
-
- name = object_new( buf->value );
-
- b = (BINDING *)hash_insert( bindhash, name, &found );
- if ( !found )
- {
- b->name = object_copy( name );
- b->flags = 0;
- b->progress = BIND_INIT;
- timestamp_clear( &b->time );
- }
-
- if ( !( b->flags & BIND_SCANNED ) )
- {
- file_dirscan( name, time_enter, bindhash );
- b->flags |= BIND_SCANNED;
- }
-
- object_free( name );
- }
-
- /* Scan archive if not already done so. */
- if ( f1.f_member.len )
- {
- int found;
- BINDING * b;
- OBJECT * name;
-
- f2 = f1;
- f2.f_grist.len = 0;
- f2.f_member.len = 0;
- string_truncate( buf, 0 );
- path_build( &f2, buf );
-
- name = object_new( buf->value );
-
- b = (BINDING *)hash_insert( bindhash, name, &found );
- if ( !found )
- {
- b->name = object_copy( name );
- b->flags = 0;
- b->progress = BIND_INIT;
- timestamp_clear( &b->time );
- }
-
- if ( !( b->flags & BIND_SCANNED ) )
- {
- file_archscan( buf->value, time_enter, bindhash );
- b->flags |= BIND_SCANNED;
- }
-
- object_free( name );
- }
- }
-
- if ( b->progress == BIND_SPOTTED )
- b->progress = file_time( b->name, &b->time ) < 0
- ? BIND_MISSING
- : BIND_FOUND;
-
- if ( b->progress == BIND_FOUND )
- timestamp_copy( time, &b->time );
- else
+ if ( file_time( path, time ) < 0 )
         timestamp_clear( time );
 
- string_free( buf );
- object_free( normalized_path );
-
     PROFILE_EXIT( timestamp );
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk