|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r75808 - trunk/tools/build/v2/engine
From: steven_at_[hidden]
Date: 2011-12-04 21:12:57
Author: steven_watanabe
Date: 2011-12-04 21:12:55 EST (Sun, 04 Dec 2011)
New Revision: 75808
URL: http://svn.boost.org/trac/boost/changeset/75808
Log:
Convert short paths to long paths on NT.
Text files modified:
trunk/tools/build/v2/engine/filent.c | 1
trunk/tools/build/v2/engine/pathsys.h | 1
trunk/tools/build/v2/engine/pathunix.c | 270 +++++++++++++++++++++++----------------
3 files changed, 160 insertions(+), 112 deletions(-)
Modified: trunk/tools/build/v2/engine/filent.c
==============================================================================
--- trunk/tools/build/v2/engine/filent.c (original)
+++ trunk/tools/build/v2/engine/filent.c 2011-12-04 21:12:55 EST (Sun, 04 Dec 2011)
@@ -169,6 +169,7 @@
path_build( &f, filename, 0 );
filename_obj = object_new( filename->value );
+ path_add_key( filename_obj );
files = list_new( files, filename_obj );
ff = file_info( filename_obj );
ff->is_file = finfo->attrib & _A_SUBDIR ? 0 : 1;
Modified: trunk/tools/build/v2/engine/pathsys.h
==============================================================================
--- trunk/tools/build/v2/engine/pathsys.h (original)
+++ trunk/tools/build/v2/engine/pathsys.h 2011-12-04 21:12:55 EST (Sun, 04 Dec 2011)
@@ -65,6 +65,7 @@
same key.
*/
OBJECT * path_as_key( OBJECT * path );
+void path_add_key( OBJECT * path );
#ifdef USE_PATHUNIX
/** Returns a static pointer to the system dependent path to the temporary
Modified: trunk/tools/build/v2/engine/pathunix.c
==============================================================================
--- trunk/tools/build/v2/engine/pathunix.c (original)
+++ trunk/tools/build/v2/engine/pathunix.c 2011-12-04 21:12:55 EST (Sun, 04 Dec 2011)
@@ -18,6 +18,7 @@
# include "filesys.h"
# include <time.h>
# include <stdlib.h>
+# include <assert.h>
# ifndef OS_NT
# include <unistd.h>
# endif
@@ -273,131 +274,90 @@
#ifdef NT
#include <windows.h>
-#include <tchar.h>
/* The definition of this in winnt.h is not ANSI-C compatible. */
#undef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+OBJECT * path_as_key( OBJECT * path );
+static void path_write_key( char * path_, string * out );
-DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
- cchBuffer)
+void ShortPathToLongPath( char * short_path, string * out )
{
- LONG i=0;
- TCHAR path[_MAX_PATH]={0};
- TCHAR ret[_MAX_PATH]={0};
- LONG pos=0, prev_pos=0;
- LONG len=_tcslen(lpszShortPath);
-
- /* Is the string valid? */
- if (!lpszShortPath) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- /* Is the path valid? */
- if (GetFileAttributes(lpszShortPath)==INVALID_FILE_ATTRIBUTES)
- return 0;
-
- /* Convert "/" to "\" */
- for (i=0;i<len;++i) {
- if (lpszShortPath[i]==_T('/'))
- path[i]=_T('\\');
- else
- path[i]=lpszShortPath[i];
+ const char * new_element;
+ unsigned long saved_size;
+ char * p;
+
+ if ( short_path[0] == '\0' )
+ {
+ return;
}
- /* UNC path? */
- if (path[0]==_T('\\') && path[1]==_T('\\')) {
- pos=2;
- for (i=0;i<2;++i) {
- while (path[pos]!=_T('\\') && path[pos]!=_T('\0'))
- ++pos;
- ++pos;
- }
- _tcsncpy(ret,path,pos-1);
- } /* Drive letter? */
- else if (path[1]==_T(':')) {
- if (path[2]==_T('\\'))
- pos=3;
- if (len==3) {
- if (cchBuffer>3)
- _tcscpy(lpszLongPath,lpszShortPath);
- return len;
- }
- _tcsncpy(ret,path,2);
- ret[0] = toupper(ret[0]);
+ if ( short_path[1] == ':' &&
+ ( short_path[2] == '\0' ||
+ ( short_path[2] == '\\' && short_path[3] == '\0' ) ) )
+ {
+ string_push_back( out, toupper( short_path[0] ) );
+ string_push_back( out, ':' );
+ string_push_back( out, '\\' );
+ return;
}
+
+ /* '/' already handled. */
+ if ( ( p = strrchr( short_path, '\\' ) ) )
+ {
+ char saved;
+ new_element = p + 1;
- /* Expand the path for each subpath, and strip trailing backslashes */
- for (prev_pos = pos-1;pos<=len;++pos) {
- if (path[pos]==_T('\\') || (path[pos]==_T('\0') &&
- path[pos-1]!=_T('\\'))) {
- WIN32_FIND_DATA fd;
- HANDLE hf=0;
- TCHAR c=path[pos];
- char* new_element;
- path[pos]=_T('\0');
-
- /* the path[prev_pos+1]... path[pos] range is the part of
- path we're handling right now. We need to find long
- name for that element and add it. */
- new_element = path + prev_pos + 1;
-
- /* First add separator, but only if there's something in result already. */
- if (ret[0] != _T('\0'))
- {
- _tcscat(ret,_T("\\"));
- }
-
- /* If it's ".." element, we need to append it, not
- the name in parent that FindFirstFile will return.
- Same goes for "." */
-
- if (new_element[0] == _T('.') && new_element[1] == _T('\0') ||
- new_element[0] == _T('.') && new_element[1] == _T('.')
- && new_element[2] == _T('\0'))
- {
- _tcscat(ret, new_element);
- }
- else
- {
- hf=FindFirstFile(path, &fd);
- if (hf==INVALID_HANDLE_VALUE)
- return 0;
-
- _tcscat(ret,fd.cFileName);
- FindClose(hf);
- }
+ /* special case \ */
+ if ( p == short_path )
+ ++p;
+
+ /* special case D:\ */
+ if ( p == short_path + 2 && short_path[1] == ':' )
+ ++p;
- path[pos]=c;
+ saved = *p;
+ *p = '\0';
+ path_write_key( short_path, out );
+ *p = saved;
+ }
+ else
+ {
+ new_element = short_path;
+ }
- prev_pos = pos;
- }
+ if ( out->size && out->value[ out->size - 1 ] != '\\' )
+ {
+ string_push_back( out, '\\' );
}
+
+ saved_size = out->size;
+ string_append( out, new_element );
- len=_tcslen(ret)+1;
- if (cchBuffer>=len)
- _tcscpy(lpszLongPath,ret);
+ if ( ! ( new_element[0] == '.' && new_element[1] == '\0' ||
+ new_element[0] == '.' && new_element[1] == '.'
+ && new_element[2] == '\0' ) )
+ {
+ WIN32_FIND_DATA fd;
+ HANDLE hf = 0;
+ hf = FindFirstFile( out->value, &fd );
- return len;
+ /* If the file exists, replace the name. */
+ if ( hf != INVALID_HANDLE_VALUE )
+ {
+ string_truncate( out, saved_size );
+ string_append( out, fd.cFileName );
+ FindClose( hf );
+ }
+ }
}
OBJECT * short_path_to_long_path( OBJECT * short_path )
{
- char buffer2[_MAX_PATH];
- int ret = ShortPathToLongPath( object_str( short_path ), buffer2, _MAX_PATH );
-
- if (ret)
- return object_new( buffer2 );
- else
- return object_copy( short_path );
+ return path_as_key( short_path );
}
-#endif
-
-#ifdef NT
-
struct path_key_entry
{
OBJECT * path;
@@ -406,6 +366,78 @@
static struct hash * path_key_cache;
+static void path_write_key( char * path_, string * out )
+{
+ struct path_key_entry e, *result = &e;
+ OBJECT * path = object_new( path_ );
+
+ /* This is only called by path_as_key, which initializes the cache. */
+ assert( path_key_cache );
+
+ result->path = path;
+ if ( hashenter( path_key_cache, (HASHDATA * *)&result ) )
+ {
+ /* path_ is already normalized. */
+ ShortPathToLongPath( path_, out );
+ result->key = object_new( out->value );
+ }
+ else
+ {
+ object_free( path );
+ string_append( out, object_str( result->key ) );
+ }
+
+}
+
+static void normalize_path( string * path )
+{
+ char * s;
+ for ( s = path->value; s < path->value + path->size; ++s )
+ {
+ if ( *s == '/' )
+ *s = '\\';
+ else
+ *s = tolower( *s );
+ }
+ /* Strip trailing "/" */
+ if ( path->size != 0 && path->size != 3 && path->value[ path->size - 1 ] == '\\' )
+ {
+ string_pop_back( path );
+ }
+}
+
+void path_add_key( OBJECT * path )
+{
+ struct path_key_entry e, *result = &e;
+
+ if ( ! path_key_cache )
+ path_key_cache = hashinit( sizeof( struct path_key_entry ), "path to key" );
+
+ result->path = path;
+ if ( hashenter( path_key_cache, (HASHDATA * *)&result ) )
+ {
+ string buf[1];
+ OBJECT * normalized;
+ struct path_key_entry ne, *nresult = ≠
+ string_copy( buf, object_str( path ) );
+ normalize_path( buf );
+ normalized = object_new( buf->value );
+ string_free( buf );
+ nresult->path = normalized;
+ if ( hashenter( path_key_cache, (HASHDATA * *)&nresult ) || nresult == result )
+ {
+ nresult->path = object_copy( normalized );
+ nresult->key = object_copy( path );
+ }
+ object_free( normalized );
+ if ( nresult != result )
+ {
+ result->path = object_copy( path );
+ result->key = object_copy( nresult->key );
+ }
+ }
+}
+
OBJECT * path_as_key( OBJECT * path )
{
struct path_key_entry e, *result = &e;
@@ -417,21 +449,31 @@
if ( hashenter( path_key_cache, (HASHDATA * *)&result ) )
{
string buf[1];
- char * s;
+ OBJECT * normalized;
+ struct path_key_entry ne, *nresult = ≠
string_copy( buf, object_str( path ) );
- for ( s = buf->value; s < buf->value + buf->size; ++s )
+ normalize_path( buf );
+ normalized = object_new( buf->value );
+ nresult->path = normalized;
+ if ( hashenter( path_key_cache, (HASHDATA * *)&nresult ) || nresult == result )
{
- if ( *s == '/' )
- *s = '\\';
- else
- *s = tolower( *s );
+ string long_path[1];
+ string_new( long_path );
+ ShortPathToLongPath( buf->value, long_path );
+ nresult->path = object_copy( normalized );
+ nresult->key = object_new( long_path->value );
+ string_free( long_path );
}
- result->path = object_copy( path );
- result->key = object_new( buf->value );
string_free( buf );
+ object_free( normalized );
+ if ( nresult != result )
+ {
+ result->path = object_copy( path );
+ result->key = object_copy( nresult->key );
+ }
}
- return result->key;
+ return object_copy( result->key );
}
static void free_path_key_entry( void * xentry, void * data )
@@ -452,6 +494,10 @@
#else
+void path_add_key( OBJECT * path )
+{
+}
+
OBJECT * path_as_key( OBJECT * path )
{
return object_copy( path );
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