mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-26 06:58:22 +01:00
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
This commit is contained in:
parent
cf136a59ba
commit
28112bfb7f
2 changed files with 55 additions and 48 deletions
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -278,7 +278,6 @@ def configure(conf):
|
|||
conf.define('CURRENT_SESSION_FILE_VERSION', CURRENT_SESSION_FILE_VERSION)
|
||||
|
||||
conf.check(header_name='sys/vfs.h', define_name='HAVE_SYS_VFS_H',mandatory=False)
|
||||
conf.check(header_name='wordexp.h', define_name='HAVE_WORDEXP',mandatory=False)
|
||||
|
||||
conf.check(header_name='jack/session.h', uselib = [ 'JACK' ],
|
||||
define_name='HAVE_JACK_SESSION')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue