From a1a8794dadc0ab972f441481594b53117df1ca92 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 20 Mar 2013 08:43:19 -0400 Subject: add missing files --- libs/pbd/pathexpand.cc | 138 ++++++++++++++++++++++++++++++++++++++++++++++ libs/pbd/pbd/pathexpand.h | 30 ++++++++++ 2 files changed, 168 insertions(+) create mode 100644 libs/pbd/pathexpand.cc create mode 100644 libs/pbd/pbd/pathexpand.h (limited to 'libs') diff --git a/libs/pbd/pathexpand.cc b/libs/pbd/pathexpand.cc new file mode 100644 index 0000000000..4911f12788 --- /dev/null +++ b/libs/pbd/pathexpand.cc @@ -0,0 +1,138 @@ +/* + Copyright (C) 2013 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include + +#include + +#include + +#include "pbd/pathexpand.h" +#include "pbd/strsplit.h" + +using std::string; +using std::vector; + +string +PBD::path_expand (string path) +{ + if (path.empty()) { + return path; + } + + /* tilde expansion */ + + if (path[0] == '~') { + if (path.length() == 1) { + return Glib::get_home_dir(); + } + + if (path[1] == '/') { + path.replace (0, 1, Glib::get_home_dir()); + } else { + /* can't handle ~roger, so just leave it */ + } + } + + /* now do $VAR substitution, since wordexp isn't reliable */ + + 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)) { + std::cerr << "bad regcomp\n"; + return path; + } + + while (true) { + + if (regexec (&compiled_pattern, path.c_str(), nmatches, matches, 0)) { + break; + } + + /* 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 + */ + } + + regfree (&compiled_pattern); + + /* canonicalize */ + + char buf[PATH_MAX+1]; + + if (realpath (path.c_str(), buf)) { + return buf; + } else { + return string(); + } +} + +string +PBD::search_path_expand (string path) +{ + if (path.empty()) { + return path; + } + + vector s; + vector n; + + split (path, s, ':'); + + for (vector::iterator i = s.begin(); i != s.end(); ++i) { + string exp = path_expand (*i); + if (!exp.empty()) { + n.push_back (exp); + } + } + + string r; + + for (vector::iterator i = n.begin(); i != n.end(); ++i) { + if (!r.empty()) { + r += ':'; + } + r += *i; + } + + return r; +} diff --git a/libs/pbd/pbd/pathexpand.h b/libs/pbd/pbd/pathexpand.h new file mode 100644 index 0000000000..a7b9f7557a --- /dev/null +++ b/libs/pbd/pbd/pathexpand.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2013 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __libpbd_path_expand_h__ +#define __libpbd_path_expand_h__ + +#include + +namespace PBD { + std::string path_expand (std::string path); + std::string search_path_expand (std::string path); +} + +#endif /* __libpbd_path_expand_h__ */ + -- cgit v1.2.3