add realloc pool to MSVC project
[ardour.git] / libs / pbd / search_path.cc
index 9956c6c76339d589a691e8b5ac81ca9eb40f0099..46292ef1f353dab4e8286dfd60353f82e7e1c730 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2007 Tim Mayberry 
+    Copyright (C) 2007 Tim Mayberry
 
     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
 
 */
 
-#include <pbd/tokenizer.h>
-#include <pbd/search_path.h>
-#include <pbd/error.h>
+#include <string>
 
-namespace {
+#include <glib.h>
+#include <glibmm/miscutils.h>
 
-#ifdef WIN32
-const char * const path_delimiter = ";";
-#else
-const char * const path_delimiter = ":";
-#endif
+#include "pbd/tokenizer.h"
+#include "pbd/search_path.h"
+#include "pbd/error.h"
 
-}
+using namespace std;
 
 namespace PBD {
 
-SearchPath::SearchPath ()
+Searchpath::Searchpath ()
 {
 
 }
 
-SearchPath::SearchPath (const string& path)
+Searchpath::Searchpath (const string& path)
 {
-       vector<sys::path> tmp;
+       vector<std::string> tmp;
 
-       if(tokenize (path, string(path_delimiter), std::back_inserter (tmp)))
-       {
+       if (tokenize (path, string(G_SEARCHPATH_SEPARATOR_S), std::back_inserter (tmp))) {
                add_directories (tmp);
        }
 }
 
-SearchPath::SearchPath (const sys::path& directory_path)
+Searchpath::Searchpath (const vector<std::string>& paths)
 {
-       add_directory (directory_path);
+       add_directories (paths);
 }
 
-SearchPath::SearchPath (const vector<sys::path>& paths)
+void
+Searchpath::remove_directory (const std::string& directory_path)
 {
-       add_directories (paths);
+       if (directory_path.empty()) {
+               return;
+       }
+
+       for (vector<std::string>::iterator i = begin(); i != end();) {
+               if (*i == directory_path) {
+                       i = erase (i);
+               } else {
+                       ++i;
+               }
+       }
 }
 
-SearchPath::SearchPath (const SearchPath& other)
-       : m_dirs(other.m_dirs)
+void
+Searchpath::remove_directories (const vector<std::string>& paths)
 {
-
+       for(vector<std::string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
+               remove_directory (*i);
+       }
 }
 
 void
-SearchPath::add_directory (const sys::path& directory_path)
+Searchpath::add_directory (const std::string& directory_path)
 {
-       // test for existance and warn etc?
-       m_dirs.push_back(directory_path);
+       if (directory_path.empty()) {
+               return;
+       }
+       for (vector<std::string>::const_iterator i = begin(); i != end(); ++i) {
+               if (*i == directory_path) {
+                       return;
+               }
+       }
+       push_back(directory_path);
 }
 
 void
-SearchPath::add_directories (const vector<sys::path>& paths)
+Searchpath::add_directories (const vector<std::string>& paths)
 {
-       for(vector<sys::path>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
+       for(vector<std::string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
                add_directory (*i);
        }
 }
 
 const string
-SearchPath::to_string () const
+Searchpath::to_string () const
 {
        string path;
 
-       for (vector<sys::path>::const_iterator i = m_dirs.begin(); i != m_dirs.end(); ++i) {
-               path += (*i).to_string();
-               path += path_delimiter;
+       for (vector<std::string>::const_iterator i = begin(); i != end(); ++i) {
+               path += *i;
+               path += G_SEARCHPATH_SEPARATOR;
        }
 
        path = path.substr (0, path.length() - 1); // drop final separator
@@ -94,59 +110,90 @@ SearchPath::to_string () const
        return path;
 }
 
-SearchPath&
-SearchPath::operator= (const SearchPath& path)
+Searchpath&
+Searchpath::operator+= (const Searchpath& spath)
 {
-       m_dirs = path.m_dirs;
+       insert(end(), spath.begin(), spath.end());
        return *this;
 }
 
-SearchPath& 
-SearchPath::operator+= (const SearchPath& spath)
+Searchpath&
+Searchpath::operator+= (const std::string& directory_path)
 {
-       m_dirs.insert(m_dirs.end(), spath.m_dirs.begin(), spath.m_dirs.end());
+       add_directory (directory_path);
        return *this;
 }
 
-SearchPath& 
-SearchPath::operator+= (const sys::path& directory_path)
+const Searchpath
+Searchpath::operator+ (const std::string& directory_path)
 {
-       add_directory (directory_path);
-       return *this;
+       return Searchpath (*this) += directory_path;
 }
 
-SearchPath& 
-SearchPath::operator+ (const sys::path& directory_path)
+const Searchpath
+Searchpath::operator+ (const Searchpath& spath)
 {
-       add_directory (directory_path);
+       return Searchpath (*this) += spath;
+}
+
+Searchpath&
+Searchpath::operator-= (const Searchpath& spath)
+{
+       remove_directories (spath);
        return *this;
 }
 
-SearchPath& 
-SearchPath::operator+ (const SearchPath& spath)
+Searchpath&
+Searchpath::operator-= (const std::string& directory_path)
 {
-       // concatenate paths into new SearchPath
-       m_dirs.insert(m_dirs.end(), spath.m_dirs.begin(), spath.m_dirs.end());
+       remove_directory (directory_path);
        return *this;
 }
 
-SearchPath&
-SearchPath::add_subdirectory_to_paths (const string& subdir)
+
+Searchpath&
+Searchpath::add_subdirectory_to_paths (const string& subdir)
 {
-       for (vector<sys::path>::iterator i = m_dirs.begin(); i != m_dirs.end(); ++i)
-       {
-               // should these new paths just be added to the end of 
+       for (vector<std::string>::iterator i = begin(); i != end(); ++i) {
+               // should these new paths just be added to the end of
                // the search path rather than replace?
-               *i /= subdir;
+               *i = Glib::build_filename (*i, subdir);
        }
-       
+
        return *this;
 }
-       
-SearchPath&
-SearchPath::operator/= (const string& subdir)
+
+bool
+Searchpath::contains (const string& path) const
 {
-       return add_subdirectory_to_paths (subdir);
+       std::vector<std::string>::const_iterator i = find(begin(), end(), path);
+
+       if (i == end()) {
+               return false;
+       }
+       return true;
+}
+
+/* This is not part of the Searchpath object, but is closely related to the
+ * whole idea, and we put it here for convenience.
+ */
+
+void
+export_search_path (const string& base_dir, const char* varname, const char* dir)
+{
+       string path;
+       const char * cstr = g_getenv (varname);
+
+       if (cstr) {
+               path = cstr;
+               path += G_SEARCHPATH_SEPARATOR;
+       } else {
+               path = "";
+       }
+       path += base_dir;
+       path += dir;
+
+       g_setenv (varname, path.c_str(), 1);
 }
 
 } // namespace PBD