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
This commit is contained in:
Taybin Rutkin 2006-06-29 16:29:19 +00:00
parent 2fa75950c7
commit d1a4f74ef2
5 changed files with 381 additions and 7 deletions

View file

@ -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)

View file

@ -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

164
libs/pbd3/path.cc Normal file
View file

@ -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

113
libs/pbd3/pbd/path.h Normal file
View file

@ -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

49
libs/pbd3/pbd/tokenizer.h Normal file
View file

@ -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