aboutsummaryrefslogtreecommitdiffhomepage
path: root/path.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-02-18 18:54:36 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-02-18 18:54:36 -0800
commit14b3a5be56a99281f2a4c75f7097fd842f922242 (patch)
tree60bf04d82fa9ac9df285c1cd3dd9c3938b4526d2 /path.cpp
parented89df7e9d9ac21e84417f744f1b8759bdaba7e5 (diff)
Changes to make autosuggestion even smarter by specially recognizing the cd command.
Diffstat (limited to 'path.cpp')
-rw-r--r--path.cpp177
1 files changed, 103 insertions, 74 deletions
diff --git a/path.cpp b/path.cpp
index 8a05adf1..57a8b123 100644
--- a/path.cpp
+++ b/path.cpp
@@ -336,96 +336,91 @@ bool path_get_cdpath_string(const wcstring &dir_str, wcstring &result, const env
}
-wchar_t *path_allocate_cdpath( const wchar_t *dir )
+wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd )
{
- wchar_t *res = 0;
+ wchar_t *res = NULL;
int err = ENOENT;
if( !dir )
return 0;
+
+ if (wd) {
+ size_t len = wcslen(wd);
+ assert(wd[len - 1] == L'/');
+ }
+
+ wcstring_list_t paths;
+
+ if (dir[0] == L'/') {
+ /* Absolute path */
+ paths.push_back(dir);
+ } else if (wcsncmp(dir, L"./", 2) == 0 ||
+ wcsncmp(dir, L"../", 3) == 0 ||
+ wcscmp(dir, L".") == 0 ||
+ wcscmp(dir, L"..") == 0) {
+ /* Path is relative to the working directory */
+ wcstring path;
+ if (wd)
+ path.append(wd);
+ path.append(dir);
+ paths.push_back(path);
+ } else {
+ wchar_t *path_cpy;
+ const wchar_t *nxt_path;
+ wchar_t *state;
+ wchar_t *whole_path;
+
+ env_var_t path = env_get_string(L"CDPATH");
+ if (path.missing())
+ path = wd ? wd : L".";
+
+ nxt_path = path.c_str();
+ path_cpy = wcsdup( path.c_str() );
+
+ for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
+ nxt_path != 0;
+ nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
+ {
+ wchar_t *expanded_path = expand_tilde_compat( wcsdup(nxt_path) );
+// debug( 2, L"woot %ls\n", expanded_path );
- if( dir[0] == L'/'|| (wcsncmp( dir, L"./", 2 )==0) )
- {
+ int path_len = wcslen( expanded_path );
+ if( path_len == 0 )
+ {
+ free(expanded_path );
+ continue;
+ }
+
+ whole_path =
+ wcsdupcat( expanded_path,
+ ( expanded_path[path_len-1] != L'/' )?L"/":L"",
+ dir );
+
+ free(expanded_path );
+ paths.push_back(whole_path);
+ free( whole_path );
+ }
+ free( path_cpy );
+ }
+
+ for (wcstring_list_t::const_iterator iter = paths.begin(); iter != paths.end(); iter++) {
struct stat buf;
+ const wchar_t *dir = iter->c_str();
if( wstat( dir, &buf ) == 0 )
{
if( S_ISDIR(buf.st_mode) )
{
res = wcsdup(dir);
+ break;
}
else
{
err = ENOTDIR;
}
-
- }
- }
- else
- {
- wchar_t *path_cpy;
- const wchar_t *nxt_path;
- wchar_t *state;
- wchar_t *whole_path;
-
- env_var_t path = L".";
-
- nxt_path = path.c_str();
- path_cpy = wcsdup( path.c_str() );
-
- if( !path_cpy )
- {
- DIE_MEM();
- }
-
- for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
- nxt_path != 0;
- nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
- {
- wchar_t *expanded_path = expand_tilde_compat( wcsdup(nxt_path) );
-
-// debug( 2, L"woot %ls\n", expanded_path );
-
- int path_len = wcslen( expanded_path );
- if( path_len == 0 )
- {
- free(expanded_path );
- continue;
- }
-
- whole_path =
- wcsdupcat( expanded_path,
- ( expanded_path[path_len-1] != L'/' )?L"/":L"",
- dir );
-
- free(expanded_path );
-
- struct stat buf;
- if( wstat( whole_path, &buf ) == 0 )
- {
- if( S_ISDIR(buf.st_mode) )
- {
- res = whole_path;
- break;
- }
- else
- {
- err = ENOTDIR;
- }
- }
- else
- {
- if( lwstat( whole_path, &buf ) == 0 )
- {
- err = EROTTEN;
- }
- }
-
- free( whole_path );
}
- free( path_cpy );
- }
-
- if( !res )
+ }
+
+ if( !res )
{
errno = err;
}
@@ -434,8 +429,8 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir )
}
-bool path_can_get_cdpath(const wcstring &in) {
- wchar_t *tmp = path_allocate_cdpath(in.c_str());
+bool path_can_get_cdpath(const wcstring &in, const wchar_t *wd) {
+ wchar_t *tmp = path_allocate_cdpath(in.c_str(), wd);
bool result = (tmp != NULL);
free(tmp);
return result;
@@ -512,3 +507,37 @@ void path_make_canonical( wcstring &path )
path.resize(size+1);
}
+bool path_is_valid(const wcstring &path, const wcstring &working_directory)
+{
+ bool path_is_valid;
+ /* Some special paths are always valid */
+ if (path.empty()) {
+ path_is_valid = false;
+ } else if (path == L"." || path == L"./") {
+ path_is_valid = true;
+ } else if (path == L".." || path == L"../") {
+ path_is_valid = (! working_directory.empty() && working_directory != L"/");
+ } else if (path.at(0) != '/') {
+ /* Prepend the working directory. Note that we know path is not empty here. */
+ wcstring tmp = working_directory;
+ tmp.append(path);
+ path_is_valid = (0 == waccess(tmp.c_str(), F_OK));
+ } else {
+ /* Simple check */
+ path_is_valid = (0 == waccess(path.c_str(), F_OK));
+ }
+ return path_is_valid;
+}
+
+wcstring get_working_directory(void) {
+ wcstring wd = L"./";
+ wchar_t dir_path[4096];
+ const wchar_t *cwd = wgetcwd( dir_path, 4096 );
+ if (cwd) {
+ wd = cwd;
+ /* Make sure the working directory ends with a slash */
+ if (! wd.empty() && wd.at(wd.size() - 1) != L'/')
+ wd.push_back(L'/');
+ }
+ return wd;
+}