diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-11-11 03:06:06 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-11-11 03:06:06 +0000 |
commit | 28112bfb7f0f1f689310716b8feea1b4e52e5b1f (patch) | |
tree | 4c8137cf4b256e8b6dc63d7b51d40309b571d03b /libs/ardour/utils.cc | |
parent | cf136a59ba12dbf8c8da5f7db6b884a68149c9de (diff) |
use home-grown solution for path_expand(), rather than wordexp() which is broken in different ways on different platforms
git-svn-id: svn://localhost/ardour2/branches/3.0@10535 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/utils.cc')
-rw-r--r-- | libs/ardour/utils.cc | 102 |
1 files changed, 55 insertions, 47 deletions
diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index 3c6963bbc1..0549698383 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -25,6 +25,7 @@ #include <cstdio> /* for sprintf */ #include <cstring> +#include <climits> #include <cstdlib> #include <cmath> #include <cctype> @@ -37,14 +38,11 @@ #include <fcntl.h> #include <dirent.h> #include <errno.h> +#include <regex.h> #include <glibmm/miscutils.h> #include <glibmm/fileutils.h> -#ifdef HAVE_WORDEXP -#include <wordexp.h> -#endif - #include "pbd/cpus.h" #include "pbd/error.h" #include "pbd/stacktrace.h" @@ -282,58 +280,68 @@ path_expand (string path) return path; } -#ifdef HAVE_WORDEXP - /* Handle tilde and environment variable expansion in session path */ - string ret = path; - string quoted; - wordexp_t expansion; + /* tilde expansion */ - /* wordexp cannot be forced (it appears) into either - - (1) NOT doing field splitting - (2) splitting based on something other than whitespace - - (despite the documentation claiming that it obeys IFS etc). + if (path[0] == '~') { + if (path.length() == 1) { + return Glib::get_home_dir(); + } - so, quote the most likely spaces to occur in a path, and that should - be about as much as we can do. - */ + if (path[1] == '/') { + path.replace (0, 1, Glib::get_home_dir()); + } else { + /* can't handle ~roger, so just leave it */ + } + } - quoted = path; - replace_all (quoted, " ", "\\ "); + /* now do $VAR substitution, since wordexp isn't reliable */ - switch (wordexp (quoted.c_str(), &expansion, WRDE_NOCMD|WRDE_UNDEF)) { - case 0: - break; - case WRDE_NOSPACE: - /* see docs on wordexp() */ - wordfree (&expansion); - /* fallthru */ - default: - error << string_compose (_("illegal or badly-formed string used for path (%1)"), path) << endmsg; - goto out; - } + regex_t compiled_pattern; + const int nmatches = 100; + regmatch_t matches[nmatches]; + + if (regcomp (&compiled_pattern, "\\$([a-zA-Z_][a-zA-Z0-9_]*|\\{[a-zA-Z_][a-zA-Z0-9_]*\\})", REG_EXTENDED)) { + cerr << "bad regcomp\n"; + return path; + } - if (expansion.we_wordc > 1) { - string all; - for (unsigned int i = 0; i < expansion.we_wordc; ++i) { - if (i > 0) { - all += " | "; - } - all += expansion.we_wordv[i]; + while (true) { + + cerr << "working on " << path << endl; + + if (regexec (&compiled_pattern, path.c_str(), nmatches, matches, 0)) { + break; } - error << string_compose (_("path (%1) is ambiguous: %2"), path, all) << endmsg; - goto out; + + /* matches[0] gives the entire match */ + + string match = path.substr (matches[0].rm_so, matches[0].rm_eo - matches[0].rm_so); + + /* try to get match from the environment */ + + if (match[1] == '{') { + /* ${FOO} form */ + match = match.substr (2, match.length() - 3); + } + + char* matched_value = getenv (match.c_str()); + + if (matched_value) { + path.replace (matches[0].rm_so, matches[0].rm_eo - matches[0].rm_so, matched_value); + } else { + path.replace (matches[0].rm_so, matches[0].rm_eo - matches[0].rm_so, string()); + } + + /* go back and do it again with whatever remains after the + * substitution + */ } - ret = expansion.we_wordv[0]; - out: - wordfree (&expansion); - return ret; + /* canonicalize */ -#else - return path; -#endif + char buf[PATH_MAX+1]; + realpath (path.c_str(), buf); + return buf; } #if __APPLE__ |