diff --git a/builtin_complete.cpp b/builtin_complete.cpp index 5ea10487c..49e09f91c 100644 --- a/builtin_complete.cpp +++ b/builtin_complete.cpp @@ -555,8 +555,6 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) { recursion_level++; -// comp = al_halloc( 0 ); - complete( do_complete, comp ); for( size_t i=0; i< comp.size() ; i++ ) @@ -585,7 +583,6 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) } } -// halloc_free( comp ); recursion_level--; } diff --git a/complete.cpp b/complete.cpp index ae7e6fef2..8ae81f59b 100644 --- a/complete.cpp +++ b/complete.cpp @@ -215,36 +215,10 @@ void completion_allocate(std::vector &completions, const wcstring } /** - Destroys various structures used for tab-completion and free()s the memory used by them. -*/ -static void complete_destroy() -{ - complete_entry_t *i=first_entry, *prev; - - while( i ) - { - prev = i; - i=i->next; - complete_free_entry( prev ); - } - first_entry = 0; - - completion_autoloader.unload_all(); - -} - -/** - The init function for the completion code. Currently, all it really - does is make sure complete_destroy is called on exit. + The init function for the completion code. Does nothing. */ static void complete_init() { - static int is_init = 0; - if( !is_init ) - { - is_init = 1; - halloc_register_function_void( global_context, &complete_destroy ); - } } /** diff --git a/env.cpp b/env.cpp index b5989e7cd..58a647b12 100644 --- a/env.cpp +++ b/env.cpp @@ -769,15 +769,12 @@ int env_set( const wchar_t *key, if( val && contains( key, L"PWD", L"HOME" ) ) { - void *context = halloc( 0, 0 ); - const wchar_t *val_canonical = path_make_canonical( context, val ); - if( wcscmp( val_canonical, val ) ) - { - int res = env_set( key, val_canonical, var_mode ); - halloc_free( context ); - return res; - } - halloc_free( context ); + /* Canoncalize our path; if it changes, recurse and try again. */ + wcstring val_canonical = val; + path_make_canonical(val_canonical); + if (val != val_canonical) { + return env_set( key, val_canonical.c_str(), var_mode ); + } } if( (var_mode & ENV_USER ) && is_read_only(key) ) diff --git a/fish_tests.cpp b/fish_tests.cpp index 66b6a6432..e329120fe 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -752,18 +752,13 @@ static void test_path() { say( L"Testing path functions" ); - void *context = halloc( 0, 0 ); - - - wchar_t *can = path_make_canonical( context, L"//foo//////bar/" ); - - if( wcscmp( can, L"/foo/bar" ) ) + wcstring path = L"//foo//////bar/"; + wcstring canon = path; + path_make_canonical(canon); + if( canon != L"/foo/bar" ) ) { err( L"Bug in canonical PATH code" ); - } - - halloc_free( context ); - + } } diff --git a/path.cpp b/path.cpp index 407448e3b..a959f4106 100644 --- a/path.cpp +++ b/path.cpp @@ -514,38 +514,30 @@ bool path_get_config(wcstring &path) } -wchar_t *path_make_canonical( void *context, const wchar_t *path ) +static void replace_all(wcstring &str, const wchar_t *needle, const wchar_t *replacement) { - wchar_t *res = halloc_wcsdup( context, path ); - wchar_t *in, *out; - - in = out = res; - - while( *in ) - { - if( *in == L'/' ) - { - while( *(in+1) == L'/' ) - { - in++; - } - } - *out = *in; - - out++; - in++; - } - - while( 1 ) - { - if( out == res ) - break; - if( *(out-1) != L'/' ) - break; - out--; - } - *out = 0; - - return res; + size_t needle_len = wcslen(needle); + size_t offset = 0; + while((offset = str.find(needle, offset)) != wcstring::npos) + { + str.replace(offset, needle_len, replacement); + offset += needle_len; + } +} + +void path_make_canonical( wcstring &path ) +{ + + /* Remove double slashes */ + replace_all(path, L"//", L"/"); + + /* Remove trailing slashes */ + size_t size = path.size(); + while (size--) { + if (path.at(size) != L'/') + break; + } + /* Now size is either -1 (if the entire string was slashes) or is the index of the last non-slash character. Either way this will set it to the correct size. */ + path.resize(size+1); } diff --git a/path.h b/path.h index aa6143c8d..8f63d14ea 100644 --- a/path.h +++ b/path.h @@ -57,13 +57,10 @@ bool path_can_get_cdpath(const wcstring &in); bool path_get_cdpath_string(const wcstring &in, wcstring &out, const env_vars &vars); /** - Remove doulbe slashes and trailing slashes from a path, - e.g. transform foo//bar/ into foo/bar. - - The returned string is allocated using the specified halloc - context. + Remove double slashes and trailing slashes from a path, + e.g. transform foo//bar/ into foo/bar. The string is modified in-place. */ -wchar_t *path_make_canonical( void *context, const wchar_t *path ); +void path_make_canonical( wcstring &path ); #endif