summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaybin Rutkin <taybin@taybin.com>2006-06-29 16:29:19 +0000
committerTaybin Rutkin <taybin@taybin.com>2006-06-29 16:29:19 +0000
commitd1a4f74ef2c86042a0cbe0e83e611596df27575f (patch)
treee8fbefa9c274b61e16ac8e2f007ef08868e1de36
parent2fa75950c7f645e3fbd932d1913002434ff9dad7 (diff)
Added path.cc and tokenizer.h from win32 branch.
Added mountpoint.cc support for non-getmntent() systems. git-svn-id: svn://localhost/ardour2/trunk@653 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/pbd3/SConscript7
-rw-r--r--libs/pbd3/mountpoint.cc55
-rw-r--r--libs/pbd3/path.cc164
-rw-r--r--libs/pbd3/pbd/path.h113
-rw-r--r--libs/pbd3/pbd/tokenizer.h49
5 files changed, 381 insertions, 7 deletions
diff --git a/libs/pbd3/SConscript b/libs/pbd3/SConscript
index 2766b3c5ed..cebb2472aa 100644
--- a/libs/pbd3/SConscript
+++ b/libs/pbd3/SConscript
@@ -10,7 +10,7 @@ pbd3 = env.Copy()
domain = 'libpbd'
-pbd3.Append(DOMAIN=domain,MAJOR=4,MINOR=0,MICRO=0)
+pbd3.Append(DOMAIN=domain,MAJOR=4,MINOR=1,MICRO=0)
pbd3.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"")
pbd3.Append(CXXFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
pbd3.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
@@ -24,6 +24,7 @@ convert.cc
dmalloc.cc
error.cc
mountpoint.cc
+path.cc
pathscanner.cc
pool.cc
pthread_utils.cc
@@ -50,9 +51,11 @@ pbd3.Merge ([ libraries['sigc2'], libraries['xml'], libraries['glibmm2'], librar
pbd3.VersionBuild(['version.cc','pbd/version.h'], 'SConscript')
libpbd3 = pbd3.SharedLibrary('pbd', pbd3_files)
-
Default(libpbd3)
+mount_env = Environment(CCFLAGS='-DTEST_MOUNTPOINT -Ilibs/pbd3')
+mount_env.Program('mountpoint', 'mountpoint.cc')
+
if env['NLS']:
i18n (pbd3, pbd3_files, env)
diff --git a/libs/pbd3/mountpoint.cc b/libs/pbd3/mountpoint.cc
index 160f5e921c..c1bcb375f3 100644
--- a/libs/pbd3/mountpoint.cc
+++ b/libs/pbd3/mountpoint.cc
@@ -88,7 +88,7 @@ mountpoint (string path)
return best;
}
-#else // no getmntent()
+#else // !HAVE_GETMNTENT
#include <sys/param.h>
#include <sys/ucred.h>
@@ -97,10 +97,55 @@ mountpoint (string path)
string
mountpoint (string path)
{
-//XXX IMPLEMENT ME using getmntinfo() or getfsstat().
- return "/";
+ struct statfs *mntbufp = 0;
+ int count;
+ unsigned int maxmatch = 0;
+ unsigned int matchlen;
+ const char *cpath = path.c_str();
+ char best[PATH_MAX+1];
+
+ if ((count = getmntinfo(&mntbufp, MNT_NOWAIT)) == 0) {
+ free(mntbufp);
+ return "\0";
+ }
+
+ best[0] = '\0';
+
+ for (int i = 0; i < count; ++i) {
+ unsigned int n = 0;
+ matchlen = 0;
+
+ /* note: strcmp's semantics are not
+ strict enough to use for this.
+ */
+
+ while (cpath[n] && mntbufp[i].f_mntonname[n]) {
+ if (cpath[n] != mntbufp[i].f_mntonname[n]) {
+ break;
+ }
+ matchlen++;
+ n++;
+ }
+
+ if (cpath[matchlen] == '\0') {
+ snprintf(best, sizeof(best), "%s", mntbufp[i].f_mntonname);
+ free(mntbufp);
+ return best;
+
+ } else {
+
+ if (matchlen > maxmatch) {
+ snprintf (best, sizeof(best), "%s", mntbufp[i].f_mntonname);
+ maxmatch = matchlen;
+ }
+ }
+ }
+
+ free(mntbufp);
+
+ return best;
}
-#endif
+#endif // HAVE_GETMNTENT
#ifdef TEST_MOUNTPOINT
@@ -110,4 +155,4 @@ main (int argc, char *argv[])
exit (0);
}
-#endif
+#endif // TEST_MOUNTPOINT
diff --git a/libs/pbd3/path.cc b/libs/pbd3/path.cc
new file mode 100644
index 0000000000..80f916c9ae
--- /dev/null
+++ b/libs/pbd3/path.cc
@@ -0,0 +1,164 @@
+/*
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <cerrno>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <glibmm/miscutils.h>
+#include <glibmm/fileutils.h>
+
+#include <pbd/path.h>
+#include <pbd/tokenizer.h>
+
+namespace PBD {
+
+Path::Path ()
+{
+
+}
+
+Path::Path (const string& path)
+{
+ vector<string> tmp;
+
+ if(!tokenize ( path, string(":;"), std::back_inserter (tmp))) {
+ g_warning ("%s : %s\n", G_STRLOC, G_STRFUNC);
+ return;
+ }
+
+ add_readable_directories (tmp);
+}
+
+Path::Path (const vector<string>& paths)
+{
+ add_readable_directories (paths);
+}
+
+Path::Path (const Path& other)
+ : m_dirs(other.m_dirs)
+{
+
+}
+
+bool
+Path::readable_directory (const string& directory_path)
+{
+ if (g_access (directory_path.c_str(), R_OK) == 0) {
+ if (Glib::file_test(directory_path, Glib::FILE_TEST_IS_DIR)) {
+ return true;
+ } else {
+ g_warning (" %s : Path exists but is not a directory\n", G_STRLOC);
+ }
+ } else {
+ g_warning ("%s : %s : %s\n", G_STRLOC, directory_path.c_str(), g_strerror(errno));
+ }
+ return false;
+}
+
+void
+Path::add_readable_directory (const string& directory_path)
+{
+ if(readable_directory(directory_path)) {
+ m_dirs.push_back(directory_path);
+ }
+}
+
+void
+Path::add_readable_directories (const vector<string>& paths)
+{
+ for(vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
+ add_readable_directory (*i);
+ }
+}
+
+const string
+Path::path_string() const
+{
+ string path;
+
+ for (vector<string>::const_iterator i = m_dirs.begin(); i != m_dirs.end(); ++i) {
+ path += (*i);
+ path += G_SEARCHPATH_SEPARATOR;
+ }
+
+ g_message ("%s : %s", G_STRLOC, path.c_str());
+
+ return path.substr (0, path.length() - 1); // drop final colon
+}
+
+const Path&
+Path::operator= (const Path& path)
+{
+ m_dirs = path.m_dirs;
+ return *this;
+}
+
+const Path&
+Path::operator+= (const string& directory_path)
+{
+ add_readable_directory (directory_path);
+ return *this;
+}
+
+const Path
+operator+ (const Path& lhs_path, const Path& rhs_path)
+{
+ Path tmp_path(lhs_path); // does this do what I think it does.
+ // concatenate paths into new Path
+ tmp_path.m_dirs.insert(tmp_path.m_dirs.end(), rhs_path.m_dirs.begin(), rhs_path.m_dirs.end());
+ return tmp_path;
+}
+
+Path&
+Path::add_subdirectory_to_path (const string& subdir)
+{
+ vector<string> tmp;
+ string directory_path;
+
+ for (vector<string>::iterator i = m_dirs.begin(); i != m_dirs.end(); ++i) {
+ directory_path = Glib::build_filename (*i, subdir);
+ if(readable_directory(directory_path)) {
+ tmp.push_back(directory_path);
+ }
+ }
+ m_dirs = tmp;
+ return *this;
+}
+
+bool
+find_file_in_path (const Path& path, const string& filename, string& resulting_path)
+{
+ for (vector<string>::const_iterator i = path.dirs().begin(); i != path.dirs().end(); ++i) {
+ resulting_path = Glib::build_filename ((*i), filename);
+ if (g_access (resulting_path.c_str(), R_OK) == 0) {
+ g_message ("File %s found in Path : %s\n", resulting_path.c_str(),
+ path.path_string().c_str());
+ return true;
+ }
+ }
+
+ g_warning ("%s : Could not locate file %s in path %s\n", G_STRLOC, filename.c_str(),
+ path.path_string().c_str());
+
+ return false;
+}
+
+} // namespace PBD
+
diff --git a/libs/pbd3/pbd/path.h b/libs/pbd3/pbd/path.h
new file mode 100644
index 0000000000..0b77a7c237
--- /dev/null
+++ b/libs/pbd3/pbd/path.h
@@ -0,0 +1,113 @@
+/*
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PBD_PATH
+#define PBD_PATH
+
+#include <string>
+#include <vector>
+
+namespace PBD {
+
+using std::string;
+using std::vector;
+
+/**
+ The Path class is a helper class for getting a vector of absolute
+ paths contained in a path string where a path string contains
+ absolute directory paths separated by a colon(:) or a semi-colon(;)
+ on windows.
+ */
+class Path {
+public:
+
+ /**
+ Create an empty Path.
+ */
+ Path ();
+
+ /**
+ Initialize Path from a string, each absolute path contained
+ in the "path" will be accessed to ensure it exists and is
+ readable.
+ \param path A path string.
+ */
+ Path (const string& path);
+
+ /**
+ Initialize Path from a vector of path strings, each absolute
+ path contained in paths will be accessed to ensure it
+ exists and is readable.
+ \param path A path string.
+ */
+ Path (const vector<string>& paths);
+
+ Path(const Path& path);
+
+ /**
+ Indicate whether there are any directories in m_dirs, if Path is
+ initialized with an empty string as the result of for instance
+ calling Glib::getenv where the environment variable doesn't
+ exist or if none of the directories in the path string are
+ accessible then false is returned.
+
+ \return true if there are any paths in m_paths.
+ */
+ //operator bool () const { return !m_dirs.empty(); }
+
+ /**
+ \return vector containing the absolute paths to the directories
+ contained
+ */
+ operator const vector<string>& () const { return m_dirs; }
+
+ /**
+ \return vector containing the absolute paths to the directories
+ contained
+ */
+ const vector<string>& dirs () const { return m_dirs; }
+
+ const string path_string() const;
+
+ const Path& operator= (const Path& path);
+
+ const Path& operator+= (const string& directory_path);
+
+ Path& add_subdirectory_to_path (const string& subdirectory);
+
+protected:
+
+ friend const Path operator+ (const Path&, const Path&);
+
+ bool readable_directory (const string& directory_path);
+
+ void add_readable_directory (const string& directory_path);
+
+ void add_readable_directories (const vector<string>& paths);
+
+ vector<string> m_dirs;
+
+};
+
+bool find_file_in_path (const Path& path, const string& filename, string& resulting_path_to_file);
+
+} // namespace PBD
+
+#endif // PBD_PATH
+
+
diff --git a/libs/pbd3/pbd/tokenizer.h b/libs/pbd3/pbd/tokenizer.h
new file mode 100644
index 0000000000..a976b79341
--- /dev/null
+++ b/libs/pbd3/pbd/tokenizer.h
@@ -0,0 +1,49 @@
+#ifndef PBD_TOKENIZER
+#define PBD_TOKENIZER
+
+#include <iterator>
+#include <string>
+
+namespace PBD {
+
+/**
+ Tokenize string, this should work for standard
+ strings aswell as Glib::ustring. This is a bit of a hack,
+ there are much better string tokenizing patterns out there.
+*/
+template<typename StringType, typename Iter>
+unsigned int
+tokenize(const StringType& str,
+ const StringType& delims,
+ Iter it)
+{
+ typename StringType::size_type start_pos = 0;
+ typename StringType::size_type end_pos = 0;
+ unsigned int token_count = 0;
+
+ do {
+ start_pos = str.find_first_not_of(delims, start_pos);
+ end_pos = str.find_first_of(delims, start_pos);
+ if (start_pos != end_pos) {
+ if (end_pos == str.npos) {
+ end_pos = str.length();
+ }
+ *it++ = str.substr(start_pos, end_pos - start_pos);
+ ++token_count;
+ start_pos = str.find_first_not_of(delims, end_pos + 1);
+ }
+ } while (start_pos != str.npos);
+
+ if (start_pos != str.npos) {
+ *it++ = str.substr(start_pos, str.length() - start_pos);
+ ++token_count;
+ }
+
+ return token_count;
+}
+
+} // namespace PBD
+
+#endif // PBD_TOKENIZER
+
+